test program, flatdb tested
[tedtools.git] / flatdb.c
index b591041..3ee3472 100644 (file)
--- 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 {