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]\n"
64 fillKV(int keylen, char *key, char *value) {
69 K.length = strlen(key);
73 V.length = strlen(value);
79 cmpINT(const TBTValue *a, const TBTValue *b) {
80 if ( *(int*)(a->value) == *(int*)(b->value) ) return 0;
81 return ( *(int*)(a->value) > *(int*)(b->value) ) ? 1 : -1;
85 cmpSTR(const TBTValue *a, const TBTValue *b) {
86 int rc = strncmp( a->value, b->value, (a->length > b->length) ? b->length : a->length);
88 if ( a->length == b->length ) return 0;
89 return ( a->length > b->length ) ? 1 : -1;
93 printLSTR(u_int32_t len, char *ptr) {
101 main(int argn, char *argv[]) {
106 char *key=NULL, *val=NULL;
107 int mode=0, verbose=0;
109 opentlog(TL_OPEN_STDERR,TL_DEBUG, NULL);
111 memset(&db, 0, sizeof(TBTree));
113 while((i=getopt(argn,argv,"VbS:Dc:hrkf:i:v:d:s:L")) != EOF) {
122 file = strdup(optarg);
125 db.keylen=sizeof(int);
128 key = strdup(optarg);
132 key = strdup(optarg);
136 key = strdup(optarg);
140 val = strdup(optarg);
144 db.npage = atoi(optarg);
147 db.strategy = atoi(optarg);
148 if ( db.strategy > 2 )
149 db.strategy = TBT_STATEGY_RIGHTFILL;
167 db.cmpkey = (db.keylen) ? cmpINT : cmpSTR;
169 if ( (rc=TBTOpen(&db, file))!= TBT_OK )
172 if ( mode==MODE_INSERT && key && val ) {
173 fillKV(db.keylen, key, val);
174 rc = TBTInsert(&db, &K, &V);
175 } else if ( mode==MODE_SEARCH && key ) {
176 fillKV(db.keylen, key, NULL);
177 rc = TBTFind(&db, &K, &V);
178 if ( rc == TBT_OK ) {
182 for(i=0;i<V.length;i++)
183 fputc(V.value[i], stdout);
187 printf("Not found\n");
190 } else if ( mode==MODE_DELETE && key ) {
191 fillKV(db.keylen, key, NULL);
192 rc = TBTDelete(&db, &K);
193 } else if ( mode==MODE_DUMP ) {
194 dumpTree(&db, TBTPAGEROOT, 0);
195 } else if ( mode==MODE_LIST ) {
196 TBTIterator iterator;
197 if ( (rc=TBTInitIterator(&db, &iterator))==TBT_OK ) {
200 rc = TBTIterate(&db, &iterator, &key, &value);
201 if ( rc == TBT_OK && key.value ) {
202 fputs("I\t", stdout);
204 printf("%d", *(int*)(key.value));
206 printLSTR(key.length, key.value);
208 printLSTR(value.length, value.value);
216 TBTFreeIterator(&db, &iterator);
217 } else if ( mode==MODE_BULK ) {
218 char buf[TBTREEPAGESIZE];
224 while( rc==TBT_OK && fgets(buf, TBTREEPAGESIZE-1, stdin) ) {
227 while( *ptr && isspace(*ptr) ) ptr++;
229 while( *ptr && !isspace(*ptr) ) ptr++;
230 key.length = ptr-key.value;
231 while( *ptr && isspace(*ptr) ) ptr++;
233 while( *ptr && !isspace(*ptr) ) ptr++;
234 value.length = ptr-value.value;
237 key.length = db.keylen;
238 key.value=(char*)&tmp;
240 rc=TBTInsert(&db, &key, &value);
241 } else if ( *buf == 'D' || *buf == 'S' ) {
243 while( *ptr && isspace(*ptr) ) ptr++;
245 while( *ptr && !isspace(*ptr) ) ptr++;
246 key.length = ptr-key.value;
249 key.length = db.keylen;
250 key.value=(char*)&tmp;
253 rc=TBTDelete(&db, &key);
254 } else if ( (rc=TBTFind(&db, &key, &value))==TBT_OK ) {
256 printf("%d", *(int*)(key.value));
258 printLSTR(key.length, key.value);
261 printLSTR(value.length, value.value);
273 if ( rc ) printf("Method returns %d\n", rc);
277 printf("Page read: %d (include cache hits %d)\n", db.pageread, db.cachehits);
278 printf("Page write: %d\n", db.pagewrite);