Add support for lxt2 break size

This commit is contained in:
steve 2004-02-06 18:23:30 +00:00
parent a436bfc711
commit fa4a873628
3 changed files with 169 additions and 40 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003 Tony Bybell.
* Copyright (c) 2003-2004 Tony Bybell.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@ -645,8 +645,8 @@ if((lt)&&(lt->numfacs))
lt->zfacname_predec_size = lt->zpackcount;
gzflush_buffered(lt, 1);
fseek(lt->handle, 0L, SEEK_END);
lt->position=ftell(lt->handle);
fseeko(lt->handle, 0L, SEEK_END);
lt->position=ftello(lt->handle);
lt->zfacname_size = lt->position - lt->zfacname_size;
lt->zhandle = gzdopen(dup(fileno(lt->handle)), "wb9");
@ -671,11 +671,12 @@ if((lt)&&(lt->numfacs))
}
gzflush_buffered(lt, 1);
fseek(lt->handle, 0L, SEEK_END);
lt->position=ftell(lt->handle);
fseeko(lt->handle, 0L, SEEK_END);
lt->position=ftello(lt->handle);
lt->break_header_size = lt->position; /* in case we need to emit multiple lxt2s with same header */
lt->zfacgeometry_size = lt->position - lt->facgeometry_offset;
fseek(lt->handle, lt->facname_offset + 12, SEEK_SET);
fseeko(lt->handle, lt->facname_offset + 12, SEEK_SET);
lxt2_wr_emit_u32(lt, lt->zfacname_size); /* backpatch sizes... */
lxt2_wr_emit_u32(lt, lt->zfacname_predec_size);
lxt2_wr_emit_u32(lt, lt->zfacgeometry_size);
@ -695,13 +696,15 @@ struct lxt2_wr_trace *lxt2_wr_init(const char *name)
{
struct lxt2_wr_trace *lt=(struct lxt2_wr_trace *)calloc(1, sizeof(struct lxt2_wr_trace));
if(!(lt->handle=fopen(name, "wb")))
if((!name)||(!(lt->handle=fopen(name, "wb"))))
{
free(lt);
lt=NULL;
}
else
{
lt->lxtname = strdup(name);
lxt2_wr_emit_u16(lt, LXT2_WR_HDRID);
lxt2_wr_emit_u16(lt, LXT2_WR_VERSION);
lxt2_wr_emit_u8 (lt, LXT2_WR_GRANULE_SIZE); /* currently 32 or 64 */
@ -715,6 +718,18 @@ return(lt);
}
/*
* setting break size
*/
void lxt2_wr_set_break_size(struct lxt2_wr_trace *lt, off_t siz)
{
if(lt)
{
lt->break_size = siz;
}
}
/*
* enable/disable partial dump mode (for faster reads)
*/
@ -938,6 +953,72 @@ return(lxt2_wr_set_time64(lt, lt->maxtime + timeval));
}
/*
* file size limiting/header cloning...
*/
static void lxt2_wr_emit_do_breakfile(struct lxt2_wr_trace *lt)
{
unsigned int len = strlen(lt->lxtname);
int i;
char *tname = malloc(len + 30);
FILE *f2, *clone;
off_t cnt, seg;
char buf[32768];
for(i=len;i>0;i--)
{
if(lt->lxtname[i]=='.') break;
}
if(!i)
{
sprintf(tname, "%s_%03d.lxt", lt->lxtname, ++lt->break_number);
}
else
{
memcpy(tname, lt->lxtname, i);
sprintf(tname+i, "_%03d.lxt", ++lt->break_number);
}
f2 = fopen(tname, "wb");
if(!f2) /* if error, keep writing to same output file...sorry */
{
free(tname);
return;
}
clone = fopen(lt->lxtname, "rb");
if(!clone)
{ /* this should never happen */
fclose(f2);
unlink(tname);
free(tname);
return;
}
/* clone original header */
for(cnt = 0; cnt < lt->break_header_size; cnt += sizeof(buf))
{
seg = lt->break_header_size - cnt;
if(seg > sizeof(buf))
{
seg = sizeof(buf);
}
fread(buf, seg, 1, clone);
fwrite(buf, seg, 1, f2);
}
fclose(clone);
fclose(lt->handle);
lt->handle = f2;
free(tname);
}
/*
* emit granule
*/
void lxt2_wr_flush_granule(struct lxt2_wr_trace *lt, int do_finalize)
{
unsigned int idx_nbytes, map_nbytes, i, j;
@ -945,7 +1026,8 @@ struct lxt2_wr_symbol *s;
unsigned int partial_iter;
unsigned int iter, iter_hi;
unsigned char using_partial, using_partial_zip=0;
unsigned int current_iter_pos=0;
off_t current_iter_pos=0;
int early_flush;
if(lt->flush_valid)
{
@ -969,11 +1051,25 @@ if((using_partial=(lt->partial)&&(lt->numfacs>lt->partial_iter)))
partial_iter = lt->numfacs;
}
if(!lt->timegranule)
{
fseek(lt->handle, 0L, SEEK_END);
lt->current_chunk=lt->position = ftell(lt->handle);
int attempt_break_state = 2;
do {
fseeko(lt->handle, 0L, SEEK_END);
lt->current_chunk=lt->position = ftello(lt->handle);
if((lt->break_size)&&(attempt_break_state==2)&&(lt->position >= lt->break_size)&&(lt->position != lt->break_header_size))
{
lxt2_wr_emit_do_breakfile(lt);
attempt_break_state--;
}
else
{
attempt_break_state = 0;
}
} while(attempt_break_state);
/* fprintf(stderr, "First chunk position is %d (0x%08x)\n", lt->current_chunk, lt->current_chunk); */
lxt2_wr_emit_u32(lt, 0); /* size of this section (uncompressed) */
lxt2_wr_emit_u32(lt, 0); /* size of this section (compressed) */
@ -1060,8 +1156,8 @@ if(using_partial)
if(using_partial_zip)
{
fseek(lt->handle, 0L, SEEK_END);
current_iter_pos = ftell(lt->handle);
fseeko(lt->handle, 0L, SEEK_END);
current_iter_pos = ftello(lt->handle);
lxt2_wr_emit_u32(lt, 0); /* size of this section (compressed) */
lxt2_wr_emit_u32(lt, partial_length+9); /* size of this section (uncompressed) */
lxt2_wr_emit_u32(lt, iter); /* begin iter of section */
@ -1130,14 +1226,14 @@ for(j=iter;j<iter_hi;j++)
if(using_partial_zip)
{
unsigned int clen;
off_t clen;
gzflush_buffered(lt, 1);
fseek(lt->handle, 0L, SEEK_END);
lt->position=ftell(lt->handle);
fseeko(lt->handle, 0L, SEEK_END);
lt->position=ftello(lt->handle);
clen = lt->position - current_iter_pos - 12;
fseek(lt->handle, current_iter_pos, SEEK_SET);
fseeko(lt->handle, current_iter_pos, SEEK_SET);
lt->zpackcount_cumulative+=lt->zpackcount;
@ -1152,16 +1248,26 @@ if(using_partial_zip)
lt->timepos = 0;
lt->timegranule++;
if((lt->timegranule>=lt->maxgranule)||(do_finalize))
if(lt->break_size)
{
unsigned int unclen, clen;
early_flush = (ftello(lt->handle) >= lt->break_size);
}
else
{
early_flush = 0;
}
if((lt->timegranule>=lt->maxgranule)||(do_finalize)||(early_flush))
{
off_t unclen, clen;
lxt2_wr_ds_Tree *dt, *dt2;
lxt2_wr_dslxt_Tree *ds, *ds2;
if(using_partial_zip)
{
fseek(lt->handle, 0L, SEEK_END);
current_iter_pos = ftell(lt->handle);
fseeko(lt->handle, 0L, SEEK_END);
current_iter_pos = ftello(lt->handle);
lxt2_wr_emit_u32(lt, 0); /* size of this section (compressed) */
lxt2_wr_emit_u32(lt, 0); /* size of this section (uncompressed) */
lxt2_wr_emit_u32(lt, ~0); /* control section */
@ -1233,14 +1339,14 @@ if((lt->timegranule>=lt->maxgranule)||(do_finalize))
if(using_partial_zip)
{
unsigned int clen;
off_t clen;
gzflush_buffered(lt, 1);
fseek(lt->handle, 0L, SEEK_END);
lt->position=ftell(lt->handle);
fseeko(lt->handle, 0L, SEEK_END);
lt->position=ftello(lt->handle);
clen = lt->position - current_iter_pos - 12;
fseek(lt->handle, current_iter_pos, SEEK_SET);
fseeko(lt->handle, current_iter_pos, SEEK_SET);
lt->zpackcount_cumulative+=lt->zpackcount;
lxt2_wr_emit_u32(lt, clen);
@ -1251,8 +1357,8 @@ if((lt->timegranule>=lt->maxgranule)||(do_finalize))
gzflush_buffered(lt, 1);
}
fseek(lt->handle, 0L, SEEK_END);
lt->position=ftell(lt->handle);
fseeko(lt->handle, 0L, SEEK_END);
lt->position=ftello(lt->handle);
/* fprintf(stderr, "file position after dumping dict: %d 0x%08x\n", lt->position, lt->position); */
unclen = lt->zpackcount;
@ -1260,7 +1366,7 @@ if((lt->timegranule>=lt->maxgranule)||(do_finalize))
/* fprintf(stderr, "%d/%d un/compressed bytes in section\n", unclen, clen); */
fseek(lt->handle, lt->current_chunk, SEEK_SET);
fseeko(lt->handle, lt->current_chunk, SEEK_SET);
if(using_partial_zip)
{
lxt2_wr_emit_u32(lt, lt->zpackcount_cumulative);
@ -1434,7 +1540,7 @@ if(len>32) len=32;
len--;
for(i=0;i<len;i++)
for(i=0;i<=len;i++)
{
*(p++) = '0' | ((value & (1<<(len-i)))!=0);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003 Tony Bybell.
* Copyright (c) 2003-2004 Tony Bybell.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@ -32,6 +32,12 @@
#include <inttypes.h>
#include <zlib.h>
#if defined _MSC_VER || defined __MINGW32__
#define fseeko fseek
#define ftello ftell
#endif
#define LXT2_WR_HDRID (0x1380)
#define LXT2_WR_VERSION (0x0001)
@ -50,7 +56,11 @@ typedef uint64_t lxttime_t;
#ifndef _MSC_VER
#define LXT2_WR_LLD "%lld"
#ifdef __MINGW32__
#define LXT2_WR_LLD "%I64d"
#else
#define LXT2_WR_LLD "%lld"
#endif
#define LXT2_WR_LLDESC(x) x##LL
#define LXT2_WR_ULLDESC(x) x##ULL
#else
@ -94,7 +104,7 @@ enum LXT2_WR_Encodings {
LXT2_WR_ENC_BLACKOUT,
LXT2_WR_DICT_START,
LXT2_WR_DICT_START
};
/*
@ -137,10 +147,10 @@ unsigned int num_map_entries;
lxt2_wr_ds_Tree *mapdict_head;
lxt2_wr_ds_Tree *mapdict_curr;
unsigned int position;
unsigned int zfacname_predec_size, zfacname_size, zfacgeometry_size;
unsigned int zpackcount, zpackcount_cumulative;
unsigned int current_chunk, current_chunkz;
off_t position;
off_t zfacname_predec_size, zfacname_size, zfacgeometry_size;
off_t zpackcount, zpackcount_cumulative;
off_t current_chunk, current_chunkz;
struct lxt2_wr_symbol *sym[LXT2_WR_SYMPRIME];
struct lxt2_wr_symbol **sorted_facs;
@ -150,7 +160,7 @@ int numfacbytes;
int longestname;
int numsections, numblock;
unsigned int facname_offset, facgeometry_offset;
off_t facname_offset, facgeometry_offset;
lxttime_t mintime, maxtime;
unsigned int timegranule;
@ -184,6 +194,11 @@ char initial_value;
char zmode[4]; /* fills in with "wb0".."wb9" */
unsigned int gzbufpnt;
unsigned char gzdest[LXT2_WR_GZWRITE_BUFFER + 4]; /* enough for zlib buffering */
char *lxtname;
off_t break_size;
off_t break_header_size;
unsigned int break_number;
};
@ -242,6 +257,9 @@ struct lxt2_wr_trace * lxt2_wr_init(const char *name);
void lxt2_wr_flush(struct lxt2_wr_trace *lt);
void lxt2_wr_close(struct lxt2_wr_trace *lt);
/* for dealing with very large traces, split into multiple files approximately "siz" in length */
void lxt2_wr_set_break_size(struct lxt2_wr_trace *lt, off_t siz);
/* 0 = no compression, 9 = best compression, 4 = default */
void lxt2_wr_set_compression_depth(struct lxt2_wr_trace *lt, unsigned int depth);
@ -261,7 +279,7 @@ struct lxt2_wr_symbol * lxt2_wr_symbol_add(struct lxt2_wr_trace *lt, const char
struct lxt2_wr_symbol * lxt2_wr_symbol_alias(struct lxt2_wr_trace *lt, const char *existing_name, const char *alias, int msb, int lsb);
void lxt2_wr_symbol_bracket_stripping(struct lxt2_wr_trace *lt, int doit);
/* each granule is LXT2_WR_GRANULE_SIZE (32 or 64) timesteps, default is 8 per section */
/* each granule is LXT2_WR_GRANULE_SIZE (32 or 64) timesteps, default is 256 per section */
void lxt2_wr_set_maxgranule(struct lxt2_wr_trace *lt, unsigned int maxgranule);
/* time ops */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003 Stephen Williams (steve@icarus.com)
* Copyright (c) 2003-2004 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: sys_lxt2.c,v 1.5 2004/01/21 01:22:53 steve Exp $"
#ident "$Id: sys_lxt2.c,v 1.6 2004/02/06 18:23:30 steve Exp $"
#endif
# include "sys_priv.h"
@ -48,6 +48,7 @@ static enum lxm_optimum_mode_e {
LXM_SPEED = 2
} lxm_optimum_mode = LXM_SPEED;
static off_t lxt2_file_size_limit = 0x40000000UL;
/*
* The lxt_scope head and current pointers are used to keep a scope
@ -424,6 +425,7 @@ static void open_dumpfile(const char*path)
lxt2_wr_set_initial_value(dump_file, 'x');
lxt2_wr_set_compression_depth(dump_file, 4);
lxt2_wr_set_partial_on(dump_file, 1);
lxt2_wr_set_break_size(dump_file, lxt2_file_size_limit);
atexit((void(*)(void))close_dumpfile);
}
@ -815,6 +817,9 @@ void sys_lxt2_register()
/*
* $Log: sys_lxt2.c,v $
* Revision 1.6 2004/02/06 18:23:30 steve
* Add support for lxt2 break size
*
* Revision 1.5 2004/01/21 01:22:53 steve
* Give the vip directory its own configure and vpi_config.h
*