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"
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, quietout=0;
109 opentlog(TL_OPEN_STDERR,TL_DEBUG, NULL);
111 memset(&db, 0, sizeof(TBTree));
113 while((i=getopt(argn,argv,"qVbS:Dc:hrkf:i:v:d:s:L")) != EOF) {
125 file = strdup(optarg);
128 db.keylen=sizeof(int);
131 key = strdup(optarg);
135 key = strdup(optarg);
139 key = strdup(optarg);
143 val = strdup(optarg);
147 db.npage = atoi(optarg);
150 db.strategy = atoi(optarg);
151 if ( db.strategy > 2 )
152 db.strategy = TBT_STATEGY_RIGHTFILL;
170 db.cmpkey = (db.keylen) ? cmpINT : cmpSTR;
172 if ( (rc=TBTOpen(&db, file))!= TBT_OK )
175 if ( mode==MODE_INSERT && key && val ) {
176 fillKV(db.keylen, key, val);
177 rc = TBTInsert(&db, &K, &V);
178 } else if ( mode==MODE_SEARCH && key ) {
179 fillKV(db.keylen, key, NULL);
180 rc = TBTFind(&db, &K, &V);
181 if ( rc == TBT_OK ) {
185 for(i=0;i<V.length;i++)
186 fputc(V.value[i], stdout);
190 printf("Not found\n");
193 } else if ( mode==MODE_DELETE && key ) {
194 fillKV(db.keylen, key, NULL);
195 rc = TBTDelete(&db, &K);
196 } else if ( mode==MODE_DUMP ) {
197 dumpTree(&db, TBTPAGEROOT, 0);
198 } else if ( mode==MODE_LIST ) {
199 TBTIterator iterator;
200 if ( (rc=TBTInitIterator(&db, &iterator))==TBT_OK ) {
203 rc = TBTIterate(&db, &iterator, &key, &value);
204 if ( rc == TBT_OK && key.value ) {
205 fputs("I\t", stdout);
207 printf("%d", *(int*)(key.value));
209 printLSTR(key.length, key.value);
211 printLSTR(value.length, value.value);
219 TBTFreeIterator(&db, &iterator);
220 } else if ( mode==MODE_BULK ) {
221 char buf[TBTREEPAGESIZE];
227 while( rc==TBT_OK && fgets(buf, TBTREEPAGESIZE-1, stdin) ) {
230 while( *ptr && isspace(*ptr) ) ptr++;
232 while( *ptr && !isspace(*ptr) ) ptr++;
233 key.length = ptr-key.value;
234 while( *ptr && isspace(*ptr) ) ptr++;
236 while( *ptr && !isspace(*ptr) ) ptr++;
237 value.length = ptr-value.value;
240 key.length = db.keylen;
241 key.value=(char*)&tmp;
243 rc=TBTInsert(&db, &key, &value);
244 } else if ( *buf == 'D' || *buf == 'S' ) {
246 while( *ptr && isspace(*ptr) ) ptr++;
248 while( *ptr && !isspace(*ptr) ) ptr++;
249 key.length = ptr-key.value;
252 key.length = db.keylen;
253 key.value=(char*)&tmp;
256 rc=TBTDelete(&db, &key);
257 } else if ( (rc=TBTFind(&db, &key, &value))==TBT_OK && quietout==0) {
259 printf("%d", *(int*)(key.value));
261 printLSTR(key.length, key.value);
264 printLSTR(value.length, value.value);
276 if ( rc ) printf("Method returns %d\n", rc);
280 printf("Page read: %d (include cache hits %d)\n", db.pageread, db.cachehits);
281 printf("Page write: %d\n", db.pagewrite);