#include #include #include #include #include #include #include "buffer.h" #include "mmap.h" #include "uint32.h" #include "mstorage.h" mstorage_t idx; char* map; int compar(const void* a,const void* b) { int i; if ((i=strcmp(map+*(uint32*)a,map+*(uint32*)b))) return i; else return *(uint32*)b-*(uint32*)a; } int compari(const void* a,const void* b) { int i; if ((i=strcasecmp(map+*(uint32*)a,map+*(uint32*)b))) return i; else return *(uint32*)b-*(uint32*)a; } int main(int argc,char* argv[]) { long filelen; char* filename=argv[1]; uint32 magic,attribute_count,record_count,indices_offset,size_of_string_table; uint32 wanted,casesensitive,dn,objectClass; int ignorecase,fastindex; ignorecase=fastindex=0; mstorage_init(&idx); if (argc<3) { buffer_putsflush(buffer_2,"usage: ./addindex filename attribute [i][f]\n" "if i is present, make index case insensitive.\n" "if f is present, make index twice as large, but quicker.\n"); return 1; } if (argc>3) { if (strchr(argv[3],'i')) ignorecase=1; if (strchr(argv[3],'f')) fastindex=1; } map=mmap_read(filename,&filelen); uint32_unpack(map,&magic); if (magic!=0xfefe1da9) { buffer_putsflush(buffer_2,"file format not recognized! Invalid magic!\n"); return 1; } uint32_unpack(map+4,&attribute_count); uint32_unpack(map+2*4,&record_count); uint32_unpack(map+3*4,&indices_offset); uint32_unpack(map+4*4,&size_of_string_table); { unsigned int i; char* x=map+5*4+size_of_string_table; wanted=casesensitive=dn=objectClass=0; for (i=0; i2; --j) { uint32_unpack(x,&k); if (k==wanted) { uint32_unpack(x+4,&k); mstorage_add(&idx,(char*)&k,4); if (fastindex) mstorage_add(&idx,(char*)&i,4); ++counted; } x+=8; } } } buffer_putulong(buffer_1,counted); buffer_putsflush(buffer_1," entries to be sorted..."); if (ignorecase) qsort(idx.root,counted,4*(fastindex+1),compari); else qsort(idx.root,counted,4*(fastindex+1),compar); buffer_putsflush(buffer_1," done.\n"); munmap(map,filelen); { int fd=open(filename,O_RDWR); if (fd<0) { buffer_putsflush(buffer_2,"could not re-open database file read-write\n"); exit(1); } ftruncate(fd,filelen+3*4+counted*4*(fastindex+1)); map=mmap(0,filelen+(counted+3)*4*(fastindex+1),PROT_WRITE,MAP_SHARED,fd,0); if (map==(char*)-1) { buffer_putsflush(buffer_2,"could not mmap database file read-write\n"); exit(1); } uint32_pack(map+casesensitive,ignorecase); uint32_pack(map+filelen,fastindex); uint32_pack(map+filelen+4,filelen+3*4+counted*4*(fastindex+1)); uint32_pack(map+filelen+8,wanted); { char* x=map+filelen+12; unsigned long i; for (i=0; i