+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);
+}