aboutsummaryrefslogtreecommitdiff
path: root/c
diff options
context:
space:
mode:
authorMartin Kobetic <mkobetic@gmail.com>2014-04-14 19:21:15 +0000
committerSteven Normore <snormore@gmail.com>2014-04-16 13:27:48 +0000
commit4e01c9fd81eec87e54ed79a6b7c04f0d2e39ea50 (patch)
tree64956acc1d33682b56f26361f0ddaf857d740e96 /c
parentcleanup (diff)
downloaddedo-4e01c9fd81eec87e54ed79a6b7c04f0d2e39ea50.tar.gz
dedo-4e01c9fd81eec87e54ed79a6b7c04f0d2e39ea50.tar.xz
fix up the C bits to compile
Diffstat (limited to 'c')
-rw-r--r--c/cursor.go134
-rw-r--r--c/cursor_test.go9
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)