2 * Copyright (c) 2004 Teodor Sigaev <teodor@sigaev.ru>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the author nor the names of any co-contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
18 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44 "tbtreetest [ -c CACHESIZE ] [-r] [-k] [-f FILE] [-D | -L | -b | -i KEY -v VALUE [ -S strategynumber ] | -d KEY | -s KEY ] [-V] [-q]\n"
45 "\t-c CACHESIZE - cache size in pages (default 0)\n"
46 "\t-r - readonly mode\n"
47 "\t-k - fixed size key (integer)\n"
48 "\t-f FILE - db-file (default ./BTREE)");
50 "\t-D - dump data base\n"
51 "\t-L - list all pairs (in bulk format)\n"
52 "\t-b - bulk operations from stdin in format (insert/delete/search):\n"
56 "\t-i KEY -v VALUE - insert KEY/VALUE\n"
57 "\t-d KEY - delete key\n"
58 "\t-s KEY - search key\n"
59 "\t-V - print page read/writes at the end\n"
60 "\t-q - do not print results of searches\n"
81 fillKV(int keylen, char *key, char *value) {
86 K.length = strlen(key);
90 V.length = strlen(value);
96 cmpINT(const TBTValue *a, const TBTValue *b) {
97 if ( *(int*)(a->value) == *(int*)(b->value) ) return 0;
98 return ( *(int*)(a->value) > *(int*)(b->value) ) ? 1 : -1;
102 cmpSTR(const TBTValue *a, const TBTValue *b) {
103 int rc = strncmp( a->value, b->value, (a->length > b->length) ? b->length : a->length);
105 if ( a->length == b->length ) return 0;
106 return ( a->length > b->length ) ? 1 : -1;
110 printLSTR(u_int32_t len, char *ptr) {
118 main(int argn, char *argv[]) {
123 char *key=NULL, *val=NULL;
124 int mode=MODE_NO, verbose=0, quietout=0;
126 opentlog(TL_OPEN_STDERR,TL_DEBUG, NULL);
128 memset(&db, 0, sizeof(TBTree));
130 while((i=getopt(argn,argv,"qVbS:Dc:hrkf:i:v:d:s:L")) != EOF) {
142 file = strdup(optarg);
145 db.keylen=sizeof(int);
148 key = strdup(optarg);
152 key = strdup(optarg);
156 key = strdup(optarg);
160 val = strdup(optarg);
164 db.npage = atoi(optarg);
167 db.strategy = atoi(optarg);
168 if ( db.strategy > 2 )
169 db.strategy = TBT_STATEGY_RIGHTFILL;
190 db.cmpkey = (db.keylen) ? cmpINT : cmpSTR;
192 if ( (rc=TBTOpen(&db, file))!= TBT_OK )
195 if ( mode==MODE_INSERT && key && val ) {
196 fillKV(db.keylen, key, val);
197 rc = TBTInsert(&db, &K, &V);
198 } else if ( mode==MODE_SEARCH && key ) {
199 fillKV(db.keylen, key, NULL);
200 rc = TBTFind(&db, &K, &V);
201 if ( rc == TBT_OK ) {
205 for(i=0;i<V.length;i++)
206 fputc(V.value[i], stdout);
210 printf("Not found\n");
213 } else if ( mode==MODE_DELETE && key ) {
214 fillKV(db.keylen, key, NULL);
215 rc = TBTDelete(&db, &K);
216 } else if ( mode==MODE_DUMP ) {
217 dumpTree(&db, TBTPAGEROOT, 0);
218 } else if ( mode==MODE_LIST ) {
219 TBTIterator iterator;
220 if ( (rc=TBTInitIterator(&db, &iterator))==TBT_OK ) {
223 rc = TBTIterate(&db, &iterator, &key, &value);
224 if ( rc == TBT_OK && key.value ) {
225 fputs("I\t", stdout);
227 printf("%d", *(int*)(key.value));
229 printLSTR(key.length, key.value);
231 printLSTR(value.length, value.value);
239 TBTFreeIterator(&db, &iterator);
240 } else if ( mode==MODE_BULK ) {
241 char buf[TBTREEPAGESIZE];
247 while( rc==TBT_OK && fgets(buf, TBTREEPAGESIZE-1, stdin) ) {
250 while( *ptr && isspace(*ptr) ) ptr++;
252 while( *ptr && !isspace(*ptr) ) ptr++;
253 key.length = ptr-key.value;
254 while( *ptr && isspace(*ptr) ) ptr++;
256 while( *ptr && !isspace(*ptr) ) ptr++;
257 value.length = ptr-value.value;
260 key.length = db.keylen;
261 key.value=(char*)&tmp;
263 rc=TBTInsert(&db, &key, &value);
264 } else if ( *buf == 'D' || *buf == 'S' ) {
266 while( *ptr && isspace(*ptr) ) ptr++;
268 while( *ptr && !isspace(*ptr) ) ptr++;
269 key.length = ptr-key.value;
272 key.length = db.keylen;
273 key.value=(char*)&tmp;
276 rc=TBTDelete(&db, &key);
277 } else if ( (rc=TBTFind(&db, &key, &value))==TBT_OK && quietout==0) {
279 printf("%d", *(int*)(key.value));
281 printLSTR(key.length, key.value);
284 printLSTR(value.length, value.value);
296 if ( rc ) printf("Method returns %d\n", rc);
300 printf("Page read: %d (include cache hits %d)\n", db.pageread, db.cachehits);
301 printf("Page write: %d\n", db.pagewrite);