diff options
author | Martin Kobetic <mkobetic@gmail.com> | 2014-04-14 19:21:15 +0000 |
---|---|---|
committer | Steven Normore <snormore@gmail.com> | 2014-04-16 13:27:48 +0000 |
commit | 4e01c9fd81eec87e54ed79a6b7c04f0d2e39ea50 (patch) | |
tree | 64956acc1d33682b56f26361f0ddaf857d740e96 /c | |
parent | cleanup (diff) | |
download | dedo-4e01c9fd81eec87e54ed79a6b7c04f0d2e39ea50.tar.gz dedo-4e01c9fd81eec87e54ed79a6b7c04f0d2e39ea50.tar.xz |
fix up the C bits to compile
Diffstat (limited to 'c')
-rw-r--r-- | c/cursor.go | 134 | ||||
-rw-r--r-- | c/cursor_test.go | 9 |
2 files changed, 74 insertions, 69 deletions
diff --git a/c/cursor.go b/c/cursor.go index 0af66af..84eae03 100644 --- a/c/cursor.go +++ b/c/cursor.go @@ -1,13 +1,15 @@ package c /* +#include <stdint.h> +#include <stdlib.h> #define MAX_DEPTH 100 #define BRANCH_PAGE 1 // These types MUST have the same layout as their corresponding Go types -typedef unsigned long long pageid; +typedef unsigned long long pgid; typedef unsigned short elemid; typedef struct page { @@ -20,7 +22,7 @@ typedef struct page { typedef struct branch_elem { unsigned long pos; unsigned long ksize; - pgid pgid; + pgid page; } branch_elem; typedef struct leaf_elem { @@ -33,7 +35,6 @@ typedef struct leaf_elem { // private types typedef struct elem_ref { - void *element; page *page; elemid index; } elem_ref; @@ -49,34 +50,75 @@ typedef struct bolt_cursor { void *data; pgid root; size_t pgsz; - elemid[MAX_DEPTH] stack; unsigned int stackp; + elem_ref stack[MAX_DEPTH]; } bolt_cursor; + +// int bolt_cursor_seek(bolt_cursor *c, bolt_val *key, bolt_val *actual_key, bolt_val *value) + +// private functions + +page *get_page(bolt_cursor *c, pgid id) { + return (page *)(c->data + (c->pgsz * id)); +} + +branch_elem *branch_page_element(page *p, elemid index) { + return (branch_elem*)(p + sizeof(page) + index * sizeof(branch_elem)); +} + +leaf_elem *leaf_page_element(page *p, elemid index) { + return (leaf_elem*)(p + sizeof(page) + index * sizeof(leaf_elem)); +} + +// return current leaf element +// if stack points at a branch page descend down to the first elemenet +// of the first leaf page +int leaf_element(bolt_cursor *c, bolt_val *key, bolt_val *value) { + elem_ref *ref = &(c->stack[c->stackp]); + branch_elem *branch; + while (ref->page->flags | BRANCH_PAGE) { + branch = branch_page_element(ref->page,ref->index); + c->stackp++; + ref = &c->stack[c->stackp]; + ref->index = 0; + ref->page = get_page(c, branch->page); + }; + set_key_value(leaf_page_element(ref->page,ref->index), key, value); + return 0; +} + +set_key_value(leaf_elem *leaf, bolt_val *key, bolt_val *value) { + key->size = leaf->ksize; + key->data = leaf + leaf->pos; + value->size = leaf->vsize; + value->data = key->data + key->size; +} + // public functions -void bolt_cursor_init(bolt_cursor* c, void *data, size_t pgsz, pgid root) { +void bolt_cursor_init(bolt_cursor *c, void *data, size_t pgsz, pgid root) { c->data = data; - c->pgid = pgid; + c->root = root; c->pgsz = pgsz; } -int bolt_cursor_first(bolt_cursor* c, bolt_val *key, bolt_val *value) { - leaf_elem* leaf; - elem_ref* ref; +int bolt_cursor_first(bolt_cursor *c, bolt_val *key, bolt_val *value) { + leaf_elem *leaf; + elem_ref *ref; // reset stack to initial state c->stackp = 0; - ref = &c->stack[c->stackp] - ref->page = page(c, c->pgid); + ref = &(c->stack[c->stackp]); + ref->page = get_page(c, c->root); ref->index = 0; // get current leaf element return leaf_element(c, key, value); } -int bolt_cursor_next(bolt_cursor* c, bolt_val *key, bolt_val *value) { - elem_ref* ref= &c->stack[c->stackp]; +int bolt_cursor_next(bolt_cursor *c, bolt_val *key, bolt_val *value) { + elem_ref *ref = &c->stack[c->stackp]; // increment element index ref->index++; @@ -85,66 +127,34 @@ int bolt_cursor_next(bolt_cursor* c, bolt_val *key, bolt_val *value) { c->stackp--; ref = &c->stack[c->stackp]; ref->index++; - } - // increment element pointer - if(ref->page | BRANCH_PAGE) - ref->element += sizeof(branch_elem); - else - ref->element += sizeof(leaf_elem); + }; // get current leaf element return leaf_element(c, key, value); } - -// int bolt_cursor_seek(bolt_cursor* c, bolt_val key, bolt_val *actual_key, bolt_val *value) - -// private functions - -page* page(bolt_cursor* c, pgid id) { - return (page*)(c->data + (c->pgsz * id)); -} - -branch_elem* branch_page_element(page* p, elemid index) { - return p + sizeof(page) + index * sizeof(branch_elem); -} - -leaf_elem* leaf_page_element(page* p, elemid index) { - return p + sizeof(page) + index * sizeof(leaf_elem); -} - -// return current leaf element -// if stack points at a branch page descend down to the first elemenet -// of the first leaf page -int leaf_element(bolt_cursor* c, bolt_val *key, bolt_val *value) { - elem_ref* ref = &c->stack[c->stackp]; - branch_elem* branch; - for(ref->page->flags | BRANCH_PAGE) { - branch = branch_page_element(ref->page,ref->index); - c->stackp++; - ref = &c->stack[c->stackp]; - ref->index = 0; - ref->element = branch; - ref->page = page(c, branch->pgid); - }; - set_key_value(leaf_page_element(ref->page,ref->index), key, value); - return 0 -} - -set_key_value(leaf_elem* leaf, bolt_val* key, bolt_val *value) { - key.size = leaf->ksize; - key.data = leaf + leaf->pos; - value.size = leaf->vsize; - value.data = key.data + key.size; -} - */ import "C" + import "github.com/boltdb/bolt" -func NewCursor(b *bolt.Bucket) *C.bolt_cursor { +type bolt_cursor *C.bolt_cursor + +func NewCursor(b *bolt.Bucket) bolt_cursor { data := (*C.void)(&b.tx.db.data[0]) pgsz := (C.size_t)(b.tx.db.pageSize) cursor := new(C.bolt_cursor) C.bolt_cursor_init(cursor, data, pgsz, (C.pgid)(b.root)) return cursor } + +func (c bolt_cursor) first() (key, value []byte) { + var k, v C.bolt_val + C.bolt_cursor_first(c, &k, &v) + return C.GoBytes(k.data, k.size), C.GoBytes(v.data, v.size) +} + +func (c bolt_cursor) next() (key, value []byte) { + var k, v C.bolt_val + C.bolt_cursor_next(c, &k, &v) + return C.GoBytes(k.data, k.size), C.GoBytes(v.data, v.size) +} diff --git a/c/cursor_test.go b/c/cursor_test.go index 12710d9..ff6d547 100644 --- a/c/cursor_test.go +++ b/c/cursor_test.go @@ -30,16 +30,11 @@ func TestIterate(t *testing.T) { // Iterate over all items and check consistency. var index = 0 tx, _ = db.Begin(false) - var k, v C.bolt_val c := NewCursor(tx.Bucket("widgets")) - C.bolt_cursor_first(c, &k, &v) - key := C.GoBytes(k.data, k.size) - for key != nil && index < len(items) { + for key, value := c.first(); key != nil && index < len(items); key, value = c.next() { assert.Equal(t, key, items[index].Key) - assert.Equal(t, C.GoBytes(v.data, v.size), items[index].Value) + assert.Equal(t, value, items[index].Value) index++ - C.bolt_cursor_next(c, &k, &v) - key := C.GoBytes(k.data, k.size) } assert.Equal(t, len(items), index) assert.Equal(t, len(items), index) |