X-Git-Url: http://www.sigaev.ru/git/gitweb.cgi?a=blobdiff_plain;f=tbtree.c;h=416cabcf70cb7dbf656a8a604368995cd68546cc;hb=fd64d180d3b9e5ffc4922256b9dbe191db35480c;hp=1096a9479f281dec385b217e52ef299c925990e8;hpb=ba7e1d079124ac7e5685a0cf918229d1a9a26735;p=tedtools.git diff --git a/tbtree.c b/tbtree.c index 1096a94..416cabc 100644 --- a/tbtree.c +++ b/tbtree.c @@ -208,7 +208,7 @@ findInCache(TBTree *db, u_int32_t pagenumber) { while(ptr && ptr->pagenumber != pagenumber) ptr = ptr->link; - return ptr;; + return ptr; } static void @@ -420,8 +420,8 @@ dumpPage(TBTree *db, TBTPage *page, int follow) { TBTPointer *ptr= (TBTPointer*)(page->data+db->pointersize*i); for(j=0;jkeylen) ? db->keylen : ptr->key.varlen.length, (db->keylen) ? 0 : ptr->key.varlen.offset ); @@ -1043,4 +1043,79 @@ TBTIterate(TBTree *db, TBTIterator *iterator, TBTValue *key, TBTValue *value ) { return TBT_OK; } +int +TBTGetFirst(TBTree *db, TBTValue *key, TBTValue *value) { + TBTIterator iterator; + int rc; + + if ( (rc=TBTInitIterator(db, &iterator))!=TBT_OK ) + return rc; + + rc=TBTIterate(db, &iterator, key, value); + + if ( key->value ) { + char * ptr; + + ptr = tmalloc( key->length ); + memcpy( ptr, key->value, key->length ); + key->value = ptr; + + ptr = tmalloc( value->length ); + memcpy( ptr, value->value, value->length ); + value->value = ptr; + } + + TBTFreeIterator(db, &iterator); + + return rc; +} + +static int +findLast(TBTree *db, TBTValue *key, TBTValue *value, u_int32_t pagenumber) { + TBTMemPage *page; + TBTPointer *ptr; + int rc=TBT_OK,i; + + if ( (rc=TBTReadPage(db, pagenumber, &page)) != TBT_OK ) + return rc; + + if ( page->page.npointer==0 ) { + if ( !page->iscached ) + tfree(page); + return TBT_OK; + } + + page->islocked=1; + if ( page->page.isleaf ) { + ptr = (TBTPointer*)(page->page.data + db->pointersize * (page->page.npointer-1)); + + key->length = ( db->keylen ) ? db->keylen : ptr->key.varlen.length; + key->value = tmalloc( key->length ); + memcpy( key->value, ( db->keylen ) ? ptr->key.fixed.key : page->page.data + ptr->key.varlen.offset, key->length ); + + value->length = ptr->pointer.leaf.length; + value->value = tmalloc( value->length ); + memcpy( value->value, page->page.data + ptr->pointer.leaf.offset, value->length ); + } else { + for(i=page->page.npointer-1; i>=0; i--) { + ptr = (TBTPointer*)( page->page.data + db->pointersize * i ); + rc = findLast(db, key, value, ptr->pointer.internal.link); + if ( rc!=TBT_OK || key->value ) + break; + } + } + + page->islocked=0; + if ( !page->iscached ) + tfree(page); + + return rc; +} + +int +TBTGetLast(TBTree *db, TBTValue *key, TBTValue *value) { + memset(key, 0, sizeof(TBTValue)); + memset(value, 0, sizeof(TBTValue)); + return findLast(db, key, value, TBTPAGEROOT); +}