X-Git-Url: http://www.sigaev.ru/git/gitweb.cgi?a=blobdiff_plain;f=flatdb.c;h=3ee3472ae282fa8915390f65437f8db559480a10;hb=3b69446cc3a0a05152253db576566dab9a5836c8;hp=b591041d3ad202e404b84dee2c1c26d98a5886ff;hpb=85302547f4200f07bebf97ba4b9aad799ea5a4aa;p=tedtools.git diff --git a/flatdb.c b/flatdb.c index b591041..3ee3472 100644 --- a/flatdb.c +++ b/flatdb.c @@ -74,24 +74,33 @@ cmpFS(const void* a, const void* b) { void FDBVacuumFreeSpace(FDB *db) { FDBFreeSpace *ptr=db->space+1, *ok=db->space; + if ( db->listcur < 2 ) return; qsort( db->space, db->listcur, sizeof(FDBFreeSpace), cmpFS); + /* merge spaces */ while( ptr - db->space < db->listcur ) { - tassert( ok->offset + ok->length <= ptr->offset ); if ( ok->offset + ok->length == ptr->offset || ptr->length==0 ) { ok->length += ptr->length; - } else { + ptr->length=0; + } else ok++; - if ( ok != ptr-1 ) - memcpy(ok, ptr, sizeof(FDBFreeSpace)); - } ptr++; } - db->listcur = ok - db->space + 1; + /* remove void spaces */ + ptr = ok = db->space; + while( ptr - db->space < db->listcur ) { + if ( ptr->length != 0 ) { + if ( ok != ptr ) + memcpy(ok,ptr,sizeof(FDBFreeSpace)); + ok++; + } + ptr++; + } + db->listcur = ok - db->space; } int @@ -247,7 +256,7 @@ FDBGet(FDB *db, off_t offset, size_t length, FDBRecord **record) { *record=NULL; - if ( db->readonly ) + if ( offset < sizeof(FDBHeader) ) return FDB_ERROR; if ( length==0 ) @@ -288,10 +297,13 @@ FDBPut(FDB *db, FDBRecord *record, off_t *offset ) { ptr = findFreeSpace( db, record->length ); if ( ptr ) { *offset = ptr->offset; - ptr->offset += record->length; ptr->length -= record->length; - if ( ptr->length == 0 ) - FDBVacuumFreeSpace(db); + if ( ptr->length == 0 ) { + if ( (ptr - db->space) + 1 != db->listcur ) + memmove(ptr, ptr+1, (db->listcur - (ptr - db->space) + 1) * sizeof(FDBFreeSpace)); + db->listcur--; + } else + ptr->offset += record->length; if ( lseek(db->fd, *offset, SEEK_SET) != *offset ) tlog(TL_CRIT|TL_EXIT,"FDBPut: lseek failed: %s", strerror(errno)); } else {