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 ]\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;
109 opentlog(TL_OPEN_STDERR,TL_DEBUG, NULL);
111 memset(&db, 0, sizeof(TBTree));
113 while((i=getopt(argn,argv,"bS:Dc:hrkf:i:v:d:s:L")) != EOF) {
119 file = strdup(optarg);
122 db.keylen=sizeof(int);
125 key = strdup(optarg);
129 key = strdup(optarg);
133 key = strdup(optarg);
137 val = strdup(optarg);
141 db.npage = atoi(optarg);
144 db.strategy = atoi(optarg);
145 if ( db.strategy > 2 )
146 db.strategy = TBT_STATEGY_RIGHTFILL;
164 db.cmpkey = (db.keylen) ? cmpINT : cmpSTR;
166 if ( (rc=TBTOpen(&db, file))!= TBT_OK )
169 if ( mode==MODE_INSERT && key && val ) {
170 fillKV(db.keylen, key, val);
171 rc = TBTInsert(&db, &K, &V);
172 } else if ( mode==MODE_SEARCH && key ) {
173 fillKV(db.keylen, key, NULL);
174 rc = TBTFind(&db, &K, &V);
175 if ( rc == TBT_OK ) {
179 for(i=0;i<V.length;i++)
180 fputc(V.value[i], stdout);
184 printf("Not found\n");
187 } else if ( mode==MODE_DELETE && key ) {
188 fillKV(db.keylen, key, NULL);
189 rc = TBTDelete(&db, &K);
190 } else if ( mode==MODE_DUMP ) {
191 dumpTree(&db, TBTPAGEROOT, 0);
192 } else if ( mode==MODE_LIST ) {
193 TBTIterator iterator;
194 if ( (rc=TBTInitIterator(&db, &iterator))==TBT_OK ) {
197 rc = TBTIterate(&db, &iterator, &key, &value);
198 if ( rc == TBT_OK && key.value ) {
199 fputs("I\t", stdout);
201 printf("%d", *(int*)(key.value));
203 printLSTR(key.length, key.value);
205 printLSTR(value.length, value.value);
213 TBTFreeIterator(&db, &iterator);
214 } else if ( mode==MODE_BULK ) {
215 char buf[TBTREEPAGESIZE];
221 while( rc==TBT_OK && fgets(buf, TBTREEPAGESIZE-1, stdin) ) {
224 while( *ptr && isspace(*ptr) ) ptr++;
226 while( *ptr && !isspace(*ptr) ) ptr++;
227 key.length = ptr-key.value;
228 while( *ptr && isspace(*ptr) ) ptr++;
230 while( *ptr && !isspace(*ptr) ) ptr++;
231 value.length = ptr-value.value;
234 key.length = db.keylen;
235 key.value=(char*)&tmp;
237 rc=TBTInsert(&db, &key, &value);
238 } else if ( *buf == 'D' || *buf == 'S' ) {
240 while( *ptr && isspace(*ptr) ) ptr++;
242 while( *ptr && !isspace(*ptr) ) ptr++;
243 key.length = ptr-key.value;
246 key.length = db.keylen;
247 key.value=(char*)&tmp;
250 rc=TBTDelete(&db, &key);
251 } else if ( (rc=TBTFind(&db, &key, &value))==TBT_OK ) {
253 printf("%d", *(int*)(key.value));
255 printLSTR(key.length, key.value);
258 printLSTR(value.length, value.value);
270 if ( rc ) printf("Method returns %d\n", rc);
273 printf("Page read: %d (include cache hits %d)\n", db.pageread, db.cachehits);
274 printf("Page write: %d\n", db.pagewrite);