/* * Copyright (c) 2004 Teodor Sigaev * 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 #include #include #include #include #include "tlog.h" #include "tmalloc.h" #include "tbtree.h" static void usage() { puts( "Usage:\n" "tbtreetest [ -c CACHESIZE ] [-r] [-k] [-f FILE] [-D | -L | -z | -b | -i KEY -v VALUE [ -S strategynumber ] | -d KEY | -s KEY ] [-V] [-q]\n" "\t-c CACHESIZE - cache size in pages (default 0)\n" "\t-r - readonly mode\n" "\t-k - fixed size key (integer)\n" "\t-f FILE - db-file (default ./BTREE)"); puts( "\t-D - dump data base\n" "\t-L - list all pairs (in bulk format)\n" "\t-z - list first and last pairs\n" "\t-b - bulk operations from stdin in format (insert/delete/search):\n" "\t I KEY VALUE\n" "\t D KEY\n" "\t S KEY\n" "\t-i KEY -v VALUE - insert KEY/VALUE\n" "\t-d KEY - delete key\n" "\t-s KEY - search key\n" "\t-V - print page read/writes at the end\n" "\t-q - do not print results of searches\n" ); exit(1); } extern char *optarg; extern int opterr; #define MODE_NO 0 #define MODE_SEARCH 1 #define MODE_INSERT 2 #define MODE_DELETE 3 #define MODE_DUMP 4 #define MODE_LIST 5 #define MODE_BULK 6 #define MODE_FL 7 static TBTValue K,V; static int Ki; static void fillKV(int keylen, char *key, char *value) { if ( keylen ) { Ki=atoi(key); K.value=(char*)&Ki; } else { K.length = strlen(key); K.value = key; } if( value ) { V.length = strlen(value); V.value = value; } } static int cmpINT(const TBTValue *a, const TBTValue *b) { if ( *(int*)(a->value) == *(int*)(b->value) ) return 0; return ( *(int*)(a->value) > *(int*)(b->value) ) ? 1 : -1; } static int cmpSTR(const TBTValue *a, const TBTValue *b) { int rc = strncmp( a->value, b->value, (a->length > b->length) ? b->length : a->length); if ( rc ) return rc; if ( a->length == b->length ) return 0; return ( a->length > b->length ) ? 1 : -1; } static void printLSTR(u_int32_t len, char *ptr) { while(len>0) { putchar(*ptr); ptr++; len--; } } int main(int argn, char *argv[]) { TBTree db; int i; int rc=0; char *file="BTREE"; char *key=NULL, *val=NULL; int mode=MODE_NO, verbose=0, quietout=0; opentlog(TL_OPEN_STDERR,TL_DEBUG, NULL); memset(&db, 0, sizeof(TBTree)); while((i=getopt(argn,argv,"qVbS:Dc:hrkf:i:v:d:s:Lz")) != EOF) { switch(i) { case 'q': quietout=1; break; case 'V': verbose=1; break; case 'r': db.readonly=1; break; case 'f': file = strdup(optarg); break; case 'k': db.keylen=sizeof(int); break; case 'i': key = strdup(optarg); mode=MODE_INSERT; break; case 'd': key = strdup(optarg); mode=MODE_DELETE; break; case 's': key = strdup(optarg); mode=MODE_SEARCH; break; case 'v': val = strdup(optarg); mode=MODE_INSERT; break; case 'c': db.npage = atoi(optarg); break; case 'S': db.strategy = atoi(optarg); if ( db.strategy > 2 ) db.strategy = TBT_STATEGY_RIGHTFILL; break; case 'D': mode=MODE_DUMP; break; case 'L': mode=MODE_LIST; break; case 'b': mode=MODE_BULK; break; case 'z': mode=MODE_FL; break; case 'h': default: usage(); break; } } if ( mode==MODE_NO ) usage(); db.cmpkey = (db.keylen) ? cmpINT : cmpSTR; if ( (rc=TBTOpen(&db, file))!= TBT_OK ) exit(1); if ( mode==MODE_INSERT && key && val ) { fillKV(db.keylen, key, val); rc = TBTInsert(&db, &K, &V); } else if ( mode==MODE_SEARCH && key ) { fillKV(db.keylen, key, NULL); rc = TBTFind(&db, &K, &V); if ( rc == TBT_OK ) { if ( V.value ) { int i; printf("Value: '"); for(i=0;i