From: teodor Date: Mon, 7 Jul 2008 16:10:18 +0000 (+0000) Subject: Add user-defined extradata to tree dump X-Git-Url: http://www.sigaev.ru/git/gitweb.cgi?p=tedtools.git;a=commitdiff_plain;h=1ce28ee3043943d4f575214fb0a2b8cc76737321 Add user-defined extradata to tree dump --- diff --git a/sfxstr.c b/sfxstr.c index 92c8233..0697ba3 100644 --- a/sfxstr.c +++ b/sfxstr.c @@ -978,7 +978,7 @@ SFSRevertPlain(SFSTree *info) { } static Opaque -writeNode(WorkPlain *wp, int fd, SFSNode *node) { +writeNode(WorkPlain *wp, int fd, SFSNode *node, u_int32_t extrasize) { int size = getNodeSize(wp->info, node); SFSNode *wnode = (SFSNode*)tmalloc(size); off_t myoffset = wp->offset; @@ -991,7 +991,7 @@ writeNode(WorkPlain *wp, int fd, SFSNode *node) { if ( node->isskip ) { if (node->haschild) *(Opaque*)( ((char*)wnode) + SFSNHRDSZ) = - writeNode(wp, fd, getSkipChildPointer(wp->info, node)); + writeNode(wp, fd, getSkipChildPointer(wp->info, node), extrasize); } else { SFSNodeData *nd = node->data; u_int32_t i; @@ -999,12 +999,12 @@ writeNode(WorkPlain *wp, int fd, SFSNode *node) { for(i=0;inchar;i++) { if (nd->haschild) *(Opaque*)(((char*)wnode) + ( ((char*)nd) - ((char*)node) ) + nd->child) = - writeNode(wp, fd, getChildPointer( wp->info, nd ) ); + writeNode(wp, fd, getChildPointer( wp->info, nd ), extrasize ); nd++; } } - if ( lseek(fd, myoffset + SFSTDHSZ, SEEK_SET) < 0 ) + if ( lseek(fd, myoffset + SFSTDHSZ + extrasize, SEEK_SET) < 0 ) tlog(TL_CRIT|TL_EXIT, "lseek failed: %s", strerror(errno)); if ( write(fd, wnode, size) != size ) tlog(TL_CRIT|TL_EXIT, "write failed: %s", strerror(errno)); @@ -1015,7 +1015,7 @@ writeNode(WorkPlain *wp, int fd, SFSNode *node) { } void -SFSWriteDump(SFSTree *info, char *filename) { +SFSWriteDump(SFSTree *info, char *filename, void *extradata, u_int32_t extrasize) { int fd; off_t size = info->totalen + SFSTDHSZ; SFSTreeDumpHeader dh; @@ -1025,7 +1025,13 @@ SFSWriteDump(SFSTree *info, char *filename) { if ( flock(fd, LOCK_EX) < 0 ) tlog(TL_CRIT|TL_EXIT, "flock failed: %s", strerror(errno)); - if ( lseek(fd, size, SEEK_SET) < 0 ) + + if ( extrasize == 0 ) + extradata = NULL; + else if ( extradata == NULL ) + extrasize = 0; + + if ( lseek(fd, size + MAXALIGN(extrasize) , SEEK_SET) < 0 ) tlog(TL_CRIT|TL_EXIT, "lseek failed: %s", strerror(errno)); dh.version = SFSTREE_VERSION; @@ -1034,12 +1040,25 @@ SFSWriteDump(SFSTree *info, char *filename) { dh.datasize = info->datasize; dh.totalen = info->totalen; dh.nnodes = info->nnodes; + dh.extrasize = extrasize; if ( lseek(fd, 0, SEEK_SET) < 0 ) tlog(TL_CRIT|TL_EXIT, "lseek failed: %s", strerror(errno)); if ( write(fd, &dh, SFSTDHSZ) != SFSTDHSZ ) tlog(TL_CRIT|TL_EXIT, "write failed: %s", strerror(errno)); + if ( extrasize ) { + if ( write(fd, extradata, extrasize) != extrasize ) + tlog(TL_CRIT|TL_EXIT, "write failed: %s", strerror(errno)); + if ( extrasize != MAXALIGN(extrasize) ) { + char dummy[8] = {0,0,0,0,0,0,0,0}; + if ( write(fd, dummy, MAXALIGN(extrasize) - extrasize ) != MAXALIGN(extrasize) - extrasize ) + tlog(TL_CRIT|TL_EXIT, "write failed: %s", strerror(errno)); + + extrasize = MAXALIGN(extrasize); + } + } + if ( info->plainmemory ) { if ( write(fd, info->node, info->totalen) != info->totalen ) tlog(TL_CRIT|TL_EXIT, "write failed: %s", strerror(errno)); @@ -1049,7 +1068,7 @@ SFSWriteDump(SFSTree *info, char *filename) { wp.info = info; wp.offset = 0; - writeNode(&wp, fd, info->node); + writeNode(&wp, fd, info->node, extrasize); } flock(fd, LOCK_UN); @@ -1057,7 +1076,7 @@ SFSWriteDump(SFSTree *info, char *filename) { } static SFSNode* -readNode(SFSTree *info, int fd, char *buf, int bufsize) { +readNode(SFSTree *info, int fd, char *buf, int bufsize, int extrasize) { SFSNode *node; int size; @@ -1072,10 +1091,10 @@ readNode(SFSTree *info, int fd, char *buf, int bufsize) { if ( node->isskip ) { if (node->haschild) { - if ( lseek(fd, *(Opaque*)node->data + SFSTDHSZ, SEEK_SET) < 0 ) + if ( lseek(fd, *(Opaque*)node->data + SFSTDHSZ + extrasize, SEEK_SET) < 0 ) tlog(TL_CRIT|TL_EXIT, "lseek failed: %s", strerror(errno)); *(SFSNode**)( (char*)(node->data) ) = - readNode(info, fd, buf, bufsize); + readNode(info, fd, buf, bufsize, extrasize); } } else { SFSNodeData *nd = node->data; @@ -1083,10 +1102,10 @@ readNode(SFSTree *info, int fd, char *buf, int bufsize) { for(i=0;inchar;i++) { if (nd->haschild) { - if ( lseek(fd, *(Opaque*)(((char*)nd) + nd->child ) + SFSTDHSZ, SEEK_SET) < 0 ) + if ( lseek(fd, *(Opaque*)(((char*)nd) + nd->child ) + SFSTDHSZ + extrasize, SEEK_SET) < 0 ) tlog(TL_CRIT|TL_EXIT, "lseek failed: %s", strerror(errno)); *(SFSNode**) (((char*)nd) + nd->child ) = - readNode(info, fd, buf, bufsize); + readNode(info, fd, buf, bufsize, extrasize); } nd++; } @@ -1096,12 +1115,17 @@ readNode(SFSTree *info, int fd, char *buf, int bufsize) { } void -SFSReadDump(SFSTree *info, char *filename) { +SFSReadDump(SFSTree *info, char *filename, void **extradata, u_int32_t *extrasize) { int fd; SFSTreeDumpHeader dh; char *buf; - int bufsize; - + int bufsize; + + if ( extradata ) + *extradata = NULL; + if (extrasize ) + *extrasize = 0; + memset(info,0,sizeof(SFSTree)); if ( (fd = open(filename, O_RDONLY)) < 0 ) @@ -1123,10 +1147,25 @@ SFSReadDump(SFSTree *info, char *filename) { info->nnodes = dh.nnodes; info->datasize = dh.datasize; + if ( dh.extrasize ) { + void *pointer = tmalloc( MAXALIGN(dh.extrasize) ); + + if ( read(fd, pointer, MAXALIGN(dh.extrasize)) != MAXALIGN(dh.extrasize) ) + tlog(TL_CRIT|TL_EXIT, "read failed: %s", strerror(errno)); + + if ( extradata ) + *extradata = pointer; + else + tfree(pointer); + + if ( extrasize ) + *extrasize = dh.extrasize; + } + /* allocate buffer with max allowed size */ bufsize = SFSNHRDSZ + 256*(sizeof(SFSNodeData) + sizeof(void*) + info->datasize); buf = tmalloc( bufsize ); - info->node = readNode(info, fd, buf, bufsize); + info->node = readNode(info, fd, buf, bufsize, MAXALIGN(dh.extrasize)); tfree(buf); flock(fd, LOCK_UN); @@ -1134,9 +1173,14 @@ SFSReadDump(SFSTree *info, char *filename) { } void -SFSInitFromDump(SFSTree *info, void *pointer, u_int64_t size) { +SFSInitFromDump(SFSTree *info, void *pointer, u_int64_t size, void **extradata, u_int32_t *extrasize) { SFSTreeDumpHeader *dh; + if ( extradata ) + *extradata = NULL; + if (extrasize ) + *extrasize = 0; + memset(info,0,sizeof(SFSTree)); if ( size && size < SFSTDHSZ ) @@ -1158,6 +1202,14 @@ SFSInitFromDump(SFSTree *info, void *pointer, u_int64_t size) { info->datasize = dh->datasize; info->plainmemory = 1; + if ( dh->extrasize ) { + if ( extradata ) + *extradata = ((char*)pointer) + SFSTDHSZ; + + if ( extrasize ) + *extrasize = dh->extrasize; + } + if ( info->totalen && info->nnodes ) - info->node = (SFSNode*)( ((char*)pointer) + SFSTDHSZ ); + info->node = (SFSNode*)( ((char*)pointer) + SFSTDHSZ + MAXALIGN(dh->extrasize) ); } diff --git a/sfxstr.h b/sfxstr.h index 7683e99..84b708e 100644 --- a/sfxstr.h +++ b/sfxstr.h @@ -229,32 +229,33 @@ void * SFSRevertPlain(SFSTree *info); typedef struct SFSTreeDumpHeader { u_int32_t version; - u_int32_t opaquesize; - u_int32_t headersize; + u_int16_t opaquesize; + u_int16_t headersize; u_int32_t datasize; + u_int32_t extrasize; u_int64_t totalen; u_int64_t nnodes; } SFSTreeDumpHeader; -#define SFSTDHSZ ( MAXALIGN(sizeof(SFSTreeDumpHeader)) ) +#define SFSTDHSZ MAXALIGN( sizeof(SFSTreeDumpHeader) ) /* * óÏÚÄÁÅÔ dump ÄÅÒÅ×Á, ÎÅ ÔÒÅÂÕÅÔ ÂÏÌØÛÏÇÏ ÒÁÓÈÏÄÁ ÐÁÍÑÔÉ */ -void SFSWriteDump(SFSTree *info, char *filename); +void SFSWriteDump(SFSTree *info, char *filename, void *extradata, u_int32_t extrasize); /* * óÏÚÄÁÅÔ "ÏÂÙÞÎÏÅ" (ÎÅ ÐÌÏÓËÏÅ) ÄÅÒÅ×Ï ÉÚ ÄÁÍÐÁ, * ÎÅ ÔÒÅÂÕÅÔ ÂÏÌØÛÏÇÏ ÒÁÓÈÏÄÁ ÐÁÍÑÔÉ * ïÂÎÕÌÑÅÔ info! */ -void SFSReadDump(SFSTree *info, char *filename); +void SFSReadDump(SFSTree *info, char *filename, void **extradata, u_int32_t *extrasize); /* * éÎÉÃÉÁÌÉÚÉÒÕÅÔ "ÐÌÏÓËÏÅ" ÄÅÒÅ×Ï ÉÚ ÏÂÒÁÚÁ ÄÁÍÐÁ * ïÂÎÕÌÑÅÔ info! */ -void SFSInitFromDump(SFSTree *info, void *pointer, u_int64_t size); +void SFSInitFromDump(SFSTree *info, void *pointer, u_int64_t size, void **extradata, u_int32_t *extrasize); #endif diff --git a/sfxtest.c b/sfxtest.c index f374036..393aff5 100644 --- a/sfxtest.c +++ b/sfxtest.c @@ -257,9 +257,16 @@ main(int argn, char *argv[]) { } if ( dump ) { - SFSWriteDump(&info, "./sfxtest.dump"); + int n = 0xDEAFBEAF; + u_int32_t nz; + void *pn; + + SFSWriteDump(&info, "./sfxtest.dump", &n, sizeof(n) ); SFSFree(&info,NULL); - SFSReadDump(&info, "./sfxtest.dump"); + SFSReadDump(&info, "./sfxtest.dump", &pn, &nz); + + tassert(*(int*)pn == n); + tassert(sizeof(n) == nz); } if (list) {