add TBTGetFirst/TBTGetLast methods
[tedtools.git] / tbtree.c
index 1096a94..b7bb757 100644 (file)
--- a/tbtree.c
+++ b/tbtree.c
@@ -1043,4 +1043,69 @@ 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);
+
+       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));
+               if ( db->keylen ) {
+                       key->length = db->keylen;
+                       key->value = ptr->key.fixed.key;
+               } else {
+                       key->length = ptr->key.varlen.length; 
+                       key->value = page->page.data + ptr->key.varlen.offset;
+               }
+
+               value->length = ptr->pointer.leaf.length; 
+               value->value = page->page.data + ptr->pointer.leaf.offset;
+       } 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);
+}