test program, flatdb tested
authorteodor <teodor>
Tue, 5 Oct 2004 08:03:06 +0000 (08:03 +0000)
committerteodor <teodor>
Tue, 5 Oct 2004 08:03:06 +0000 (08:03 +0000)
Makefile
flatdb.c
flatdb.h
flatdbtest.c [new file with mode: 0644]

index e58d726..7184bef 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -5,12 +5,12 @@ LD=ld -x -shared
 
 INCLUDE=-I.
 CFLAGS=-Wall -g -O2 -pedantic -ansi -DASSERT_CORE -D_GNU_SOURCE -DHAVE_POLL_H -DHAVE_SYS_POLL_H -DHAVE_HSTRERROR
-LIB=-L. -ltedtools -lm
+LIB=-g -L. -ltedtools -lm
 
 OBJS=tlog.o tmalloc.o tools.o prs_hmap.o sfxstr.o \
        regis.o prs_inf.o shmem.o tcp.o udp.o connpool.o \
        psort.o flatdb.o
-PROGS=sfxtest hextest inftest kilter psortex
+PROGS=sfxtest hextest inftest kilter psortex flatdbtest
 
 .SUFFIXES: .o.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 {
index 5130258..5c3a4da 100644 (file)
--- a/flatdb.h
+++ b/flatdb.h
@@ -41,7 +41,7 @@ typedef struct {
 
 typedef struct {
        size_t  length;
-       char    *data;
+       char    data[1];
 } FDBRecord;
 
 #define RECHDRSZ       (sizeof(size_t))
diff --git a/flatdbtest.c b/flatdbtest.c
new file mode 100644 (file)
index 0000000..ec6fb69
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2004 Teodor Sigaev <teodor@sigaev.ru>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of any co-contributors
+ *      may be used to endorse or promote products derived from this software
+ *      without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "tlog.h"
+#include "tmalloc.h"
+#include "flatdb.h"
+
+static void
+usage() {
+       puts(
+       "Usage:\n"
+       "flatdbtest [-r] -f FILE  [ -p INFO | -g OFFSET | -d OFFSET | -v [ ... ] ]\n"
+       "flatdbtest -f FILE  -s"
+       );
+       exit(1);
+}
+
+extern char *optarg;
+extern int opterr;
+
+int
+main(int argn, char *argv[]) {
+       FDB db;
+       int i;
+       int isopened=0, readonly=0;
+       off_t offset;
+       int len,rc;
+       FDBRecord       *record;        
+
+       opentlog(TL_OPEN_STDERR,TL_DEBUG, NULL);
+       opterr=0;
+
+       while((i=getopt(argn,argv,"srf:p:g:d:vh")) != EOF) {
+               switch(i) {
+                       case 'r':
+                               if (isopened) {FDBClose(&db); usage();}
+                               readonly=1;
+                               break;
+                       case 'f':
+                               if (isopened) {FDBClose(&db); usage();}
+                               if ( (rc=FDBOpen(&db, optarg, readonly)) != FDB_OK )
+                                       tlog(TL_CRIT|TL_EXIT, "FDBOpen failed: %d", rc);
+                               isopened=1;
+                               break;
+                       case 'v':
+                               if (!isopened) {usage();}
+                               FDBVacuumFreeSpace(&db);
+                               puts("Vacuum"); 
+                               break;
+                       case 'p':
+                               if (!isopened) {usage();}
+                               len = RECHDRSZ + strlen(optarg);
+                               record = (FDBRecord*)tmalloc( len );
+                               record->length = (size_t)len;
+                               memcpy( record->data, optarg, len-RECHDRSZ );
+                               if ( (rc=FDBPut(&db, record, &offset)) != FDB_OK ) {
+                                       FDBClose(&db);
+                                       tlog(TL_CRIT|TL_EXIT, "FDBPut failed: %d", rc);
+                               }
+                               tfree(record);
+                               printf("Put: off:%d len:%d '%s'\n", (int)offset, len-RECHDRSZ, optarg);
+                               break;
+                       case 'g': 
+                               if (!isopened) {usage();}
+                               offset = atoi(optarg);
+                               if ( (rc=FDBGet(&db, offset, 0, &record)) != FDB_OK ) {
+                                       FDBClose(&db);
+                                       tlog(TL_CRIT|TL_EXIT, "FDBGet failed: %d", rc);
+                               }
+                               printf("Get: off:%d len:%d '", (int)offset, record->length - RECHDRSZ);
+                               fwrite(record->data, record->length - RECHDRSZ, 1, stdout);
+                               puts("'");
+                               tfree(record);
+                               break;
+                       case 'd':
+                               if (!isopened) {usage();}
+                               offset = atoi(optarg);
+                               if ( (rc=FDBDelete(&db, offset, 0)) != FDB_OK ) {
+                                       FDBClose(&db);
+                                       tlog(TL_CRIT|TL_EXIT, "FDBDelete failed: %d", rc);
+                               }
+                               printf("Del: off:%d\n", (int)offset);
+                               break;
+                       case 's':
+                               if (!isopened) {usage();}
+                               if ( db.listcur ) { 
+                               puts("List of free space:");
+                                       for(i=0;i<db.listcur;i++)
+                                               printf("\toff: %d\t len: %d\n", (int)(db.space[i].offset), db.space[i].length);
+                               } else
+                                        puts("List of free space is void");
+                               break;
+                       case 'h':
+                       default:
+                               if (isopened) {FDBClose(&db);}
+                               usage();
+                               break;
+               }
+       }
+                               
+       if (isopened) 
+               FDBClose(&db);
+       else
+               usage();
+
+       return 0;
+}
+
+       
+