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 | -z | -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-z - list first and last pairs\n"
53 "\t-b - bulk operations from stdin in format (insert/delete/search):\n"
57 "\t-i KEY -v VALUE - insert KEY/VALUE\n"
58 "\t-d KEY - delete key\n"
59 "\t-s KEY - search key\n"
60 "\t-V - print page read/writes at the end\n"
61 "\t-q - do not print results of searches\n"
83 fillKV(int keylen, char *key, char *value) {
88 K.length = strlen(key);
92 V.length = strlen(value);
98 cmpINT(const TBTValue *a, const TBTValue *b) {
99 if ( *(int*)(a->value) == *(int*)(b->value) ) return 0;
100 return ( *(int*)(a->value) > *(int*)(b->value) ) ? 1 : -1;
104 cmpSTR(const TBTValue *a, const TBTValue *b) {
105 int rc = strncmp( a->value, b->value, (a->length > b->length) ? b->length : a->length);
107 if ( a->length == b->length ) return 0;
108 return ( a->length > b->length ) ? 1 : -1;
112 printLSTR(u_int32_t len, char *ptr) {
120 main(int argn, char *argv[]) {
125 char *key=NULL, *val=NULL;
126 int mode=MODE_NO, verbose=0, quietout=0;
128 opentlog(TL_OPEN_STDERR,TL_DEBUG, NULL);
130 memset(&db, 0, sizeof(TBTree));
132 while((i=getopt(argn,argv,"qVbS:Dc:hrkf:i:v:d:s:Lz")) != EOF) {
144 file = strdup(optarg);
147 db.keylen=sizeof(int);
150 key = strdup(optarg);
154 key = strdup(optarg);
158 key = strdup(optarg);
162 val = strdup(optarg);
166 db.npage = atoi(optarg);
169 db.strategy = atoi(optarg);
170 if ( db.strategy > 2 )
171 db.strategy = TBT_STATEGY_RIGHTFILL;
195 db.cmpkey = (db.keylen) ? cmpINT : cmpSTR;
197 if ( (rc=TBTOpen(&db, file))!= TBT_OK )
200 if ( mode==MODE_INSERT && key && val ) {
201 fillKV(db.keylen, key, val);
202 rc = TBTInsert(&db, &K, &V);
203 } else if ( mode==MODE_SEARCH && key ) {
204 fillKV(db.keylen, key, NULL);
205 rc = TBTFind(&db, &K, &V);
206 if ( rc == TBT_OK ) {
210 for(i=0;i<V.length;i++)
211 fputc(V.value[i], stdout);
215 printf("Not found\n");
218 } else if ( mode==MODE_DELETE && key ) {
219 fillKV(db.keylen, key, NULL);
220 rc = TBTDelete(&db, &K);
221 } else if ( mode==MODE_DUMP ) {
222 dumpTree(&db, TBTPAGEROOT, 0);
223 } else if ( mode==MODE_LIST ) {
224 TBTIterator iterator;
225 if ( (rc=TBTInitIterator(&db, &iterator))==TBT_OK ) {
228 rc = TBTIterate(&db, &iterator, &key, &value);
229 if ( rc == TBT_OK && key.value ) {
230 fputs("I\t", stdout);
232 printf("%d", *(int*)(key.value));
234 printLSTR(key.length, key.value);
236 printLSTR(value.length, value.value);
244 TBTFreeIterator(&db, &iterator);
245 } else if ( mode==MODE_FL ) {
247 rc = TBTGetFirst(&db, &key, &value);
250 printf("%d", *(int*)(key.value));
252 printLSTR(key.length, key.value);
254 printLSTR(value.length, value.value);
257 rc |= TBTGetLast(&db, &key, &value);
260 printf("%d", *(int*)(key.value));
262 printLSTR(key.length, key.value);
264 printLSTR(value.length, value.value);
267 } else if ( mode==MODE_BULK ) {
268 char buf[TBTREEPAGESIZE];
274 while( rc==TBT_OK && fgets(buf, TBTREEPAGESIZE-1, stdin) ) {
277 while( *ptr && isspace(*ptr) ) ptr++;
279 while( *ptr && !isspace(*ptr) ) ptr++;
280 key.length = ptr-key.value;
281 while( *ptr && isspace(*ptr) ) ptr++;
283 while( *ptr && !isspace(*ptr) ) ptr++;
284 value.length = ptr-value.value;
287 key.length = db.keylen;
288 key.value=(char*)&tmp;
290 rc=TBTInsert(&db, &key, &value);
291 } else if ( *buf == 'D' || *buf == 'S' ) {
293 while( *ptr && isspace(*ptr) ) ptr++;
295 while( *ptr && !isspace(*ptr) ) ptr++;
296 key.length = ptr-key.value;
299 key.length = db.keylen;
300 key.value=(char*)&tmp;
303 rc=TBTDelete(&db, &key);
304 } else if ( (rc=TBTFind(&db, &key, &value))==TBT_OK && quietout==0) {
306 printf("%d", *(int*)(key.value));
308 printLSTR(key.length, key.value);
311 printLSTR(value.length, value.value);
323 if ( rc ) printf("Method returns %d\n", rc);
327 printf("Page read: %d (include cache hits %d)\n", db.pageread, db.cachehits);
328 printf("Page write: %d\n", db.pagewrite);