diff --git a/FORMAT b/FORMAT index 6f27c94..6deb11b 100644 --- a/FORMAT +++ b/FORMAT @@ -38,6 +38,7 @@ All integers are stored LITTLE ENDIAN. as two arrays, one for the pointers and one for the numbers, for cache performance reasons. 2 == ACL data + 3 == hash index (only useful for dn) rest reserved */ uint32_t next; /* offset of next index */ /* for index_type==0: */ @@ -48,6 +49,18 @@ All integers are stored LITTLE ENDIAN. uint32_t record_offsets[record_count]; uint32_t record_number[record_count]; /* for index_type==2 see file "ACL" */ + /* for index_type==3: */ + uint32_t indexed_attribute; + uint32_t hash_table_size; /* in uint32_t, not in bytes! */ + uint32_t hash_table[hash_table_size]; + uint32_t lists[]; + /* if a hash table entry is 0, return not found. */ + /* if a hash table entry points to before this index, there is + * exactly one record matching this hash, and the offset points + * there. */ + /* if a hash table entry points somewhere in lists, there were + * hash collisions; The first uint32_t at the offset is the + * length of the list, the rest are the offsets of the records */ } The indices are at the end to make it possible to add more indices. diff --git a/addindex.c b/addindex.c index b0f81bf..5f891fa 100644 --- a/addindex.c +++ b/addindex.c @@ -9,6 +9,7 @@ #include "mmap.h" #include "uint32.h" #include "mstorage.h" +#include mstorage_t idx; char* map; @@ -30,6 +31,7 @@ int compari(const void* a,const void* b) { } int main(int argc,char* argv[]) { + enum { SORTEDTABLE, HASHTABLE } mode; long filelen; char* filename=argv[1]; uint32 magic,attribute_count,record_count,indices_offset,size_of_string_table; @@ -38,29 +40,29 @@ int main(int argc,char* argv[]) { ignorecase=fastindex=0; + errmsg_iam("addindex"); mstorage_init(&idx); if (argc<3) { - buffer_putsflush(buffer_2,"usage: ./addindex filename attribute [i][f]\n" + buffer_putsflush(buffer_2,"usage: ./addindex filename attribute [i][f][h]\n" "if i is present, make index case insensitive.\n" - "if f is present, make index twice as large, but quicker.\n"); + "if f is present, make index twice as large, but quicker.\n" + "if h is present, make it a hash index (only accelerates direct lookups)\n"); return 1; } + mode=SORTEDTABLE; if (argc>3) { if (strchr(argv[3],'i')) ignorecase=1; if (strchr(argv[3],'f')) fastindex=1; + if (strchr(argv[3],'h')) mode=HASHTABLE; } map=mmap_read(filename,&filelen); - if (!map) { - buffer_putmflush(buffer_2,"could not open `",filename,"': ",strerror(errno),"\n"); - return 1; - } + if (!map) + diesys(111,"Could not open \"",filename,"\""); uint32_unpack(map,&magic); - if (magic!=0xfefe1da9) { - buffer_putsflush(buffer_2,"file format not recognized! Invalid magic!\n"); - return 1; - } + if (magic!=0xfefe1da9) + die(111,"File format not recognized (invalid magic)!\n"); uint32_unpack(map+4,&attribute_count); uint32_unpack(map+2*4,&record_count); uint32_unpack(map+3*4,&indices_offset); @@ -80,24 +82,18 @@ int main(int argc,char* argv[]) { // buffer_putsflush(buffer_2,"found attribute!\n"); wanted=j; casesensitive=x+attribute_count*4-map; uint32_unpack(map+casesensitive,&j); - if (j) { - buffer_putsflush(buffer_2,"case sensitivity flag is nonzero?!\n"); - return 1; - } + if (j) + die(1,"Case sensitivity flag is nonzero!?"); } x+=4; } - if (!wanted) { - buffer_putsflush(buffer_2,"that attribute is not in the database!\n"); - return 1; - } - if (!dn || !objectClass) { - buffer_putsflush(buffer_2,"dn or objectClass not found!\n"); - return 1; - } + if (!wanted) + die(1,"That attribute is not in the database."); + if (!dn || !objectClass) + die(1,"dn or objectClass not found."); } - { + if (mode==SORTEDTABLE) { uint32 i,counted=0; char* x=map+5*4+size_of_string_table+attribute_count*8; for (i=0; i=bottom)) { @@ -1298,7 +1299,7 @@ again: struct pollfd p; p.fd=0; p.events=POLLIN; - if (poll(&p,1,1)==1) return; + if (poll(&p,1,1)==1) return 0; } handle(asock,asock); goto again;