aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bucket.go21
-rw-r--r--const.go15
-rw-r--r--cursor.go44
-rw-r--r--db.go19
-rw-r--r--error.go30
-rw-r--r--info.go10
-rw-r--r--meta.go32
-rw-r--r--node.go40
-rw-r--r--page.go44
-rw-r--r--reader.go5
-rw-r--r--stat.go10
-rw-r--r--transaction.go33
-rw-r--r--warn.go14
-rw-r--r--xcursor.go8
14 files changed, 325 insertions, 0 deletions
diff --git a/bucket.go b/bucket.go
new file mode 100644
index 0000000..16f8be3
--- /dev/null
+++ b/bucket.go
@@ -0,0 +1,21 @@
+package bolt
+
+// TODO: #define MDB_VALID 0x8000 /**< DB handle is valid, for me_dbflags */
+// TODO: #define PERSISTENT_FLAGS (0xffff & ~(MDB_VALID))
+// TODO: #define VALID_FLAGS (MDB_REVERSEKEY|MDB_DUPSORT|MDB_INTEGERKEY|MDB_DUPFIXED|MDB_INTEGERDUP|MDB_REVERSEDUP|MDB_CREATE)
+// TODO: #define FREE_DBI 0
+// TODO: #define MAIN_DBI 1
+
+type Bucket interface {
+}
+
+type bucket struct {
+ pad int
+ flags int
+ depth int
+ branchPageCount int
+ leafPageCount int
+ overflowPageCount int
+ entryCount int
+ rootID int
+}
diff --git a/const.go b/const.go
new file mode 100644
index 0000000..3bbb8dc
--- /dev/null
+++ b/const.go
@@ -0,0 +1,15 @@
+package bolt
+
+const Version = 1
+
+const magic int32 = 0xBEEFC0DE
+
+const (
+ MaxKeySize = 511
+ MaxDataSize = 0xffffffff
+)
+
+const (
+ DefaultMapSize = 1048576
+ DefaultReaderCount = 126
+)
diff --git a/cursor.go b/cursor.go
new file mode 100644
index 0000000..8399b88
--- /dev/null
+++ b/cursor.go
@@ -0,0 +1,44 @@
+package bolt
+
+// TODO: #define CURSOR_STACK 32
+
+// TODO: #define C_INITIALIZED 0x01 /**< cursor has been initialized and is valid */
+// TODO: #define C_EOF 0x02 /**< No more data */
+// TODO: #define C_SUB 0x04 /**< Cursor is a sub-cursor */
+// TODO: #define C_DEL 0x08 /**< last op was a cursor_del */
+// TODO: #define C_SPLITTING 0x20 /**< Cursor is in page_split */
+// TODO: #define C_UNTRACK 0x40 /**< Un-track cursor when closing */
+
+type Cursor interface {
+ First() error
+ FirstDup() error
+ Get() ([]byte, []byte, error)
+ GetRange() ([]byte, []byte, error)
+ Current() ([]byte, []byte, error)
+ Last()
+ LastDup()
+ Next() ([]byte, []byte, error)
+ NextDup() ([]byte, []byte, error)
+ NextNoDup() ([]byte, []byte, error)
+ Prev() ([]byte, []byte, error)
+ PrevDup() ([]byte, []byte, error)
+ PrevNoDup() ([]byte, []byte, error)
+ Set() ([]byte, []byte, error)
+ SetRange() ([]byte, []byte, error)
+}
+
+type cursor struct {
+ flags int
+ next *cursor
+ backup *cursor
+ xcursor *xcursor
+ transaction *transaction
+ bucketId int
+ bucket *bucket
+ bucketx *bucketx
+ bucketFlag int
+ snum int
+ top int
+ page []*page
+ ki []int /**< stack of page indices */
+}
diff --git a/db.go b/db.go
new file mode 100644
index 0000000..914cd18
--- /dev/null
+++ b/db.go
@@ -0,0 +1,19 @@
+package bolt
+
+const (
+ NoSync = iota
+ NoMetaSync
+ DupSort
+ IntegerKey
+ IntegerDupKey
+)
+
+type DB interface {
+}
+
+type db struct {
+}
+
+func NewDB() DB {
+ return &db{}
+}
diff --git a/error.go b/error.go
new file mode 100644
index 0000000..caed282
--- /dev/null
+++ b/error.go
@@ -0,0 +1,30 @@
+package bolt
+
+var (
+ KeyExistError = &Error{"Key/data pair already exists"}
+ NotFoundError = &Error{"No matching key/data pair found"}
+ PageNotFoundError = &Error{"Requested page not found"}
+ CorruptedError = &Error{"Located page was wrong type"}
+ PanicError = &Error{"Update of meta page failed"}
+ VersionMismatchError = &Error{"Database environment version mismatch"}
+ InvalidError = &Error{"File is not an MDB file"}
+ MapFullError = &Error{"Environment mapsize limit reached"}
+ BucketFullError = &Error{"Environment maxdbs limit reached"}
+ ReadersFullError = &Error{"Environment maxreaders limit reached"}
+ TransactionFullError = &Error{"Transaction has too many dirty pages - transaction too big"}
+ CursorFullError = &Error{"Internal error - cursor stack limit reached"}
+ PageFullError = &Error{"Internal error - page has no more space"}
+ MapResizedError = &Error{"Database contents grew beyond environment mapsize"}
+ IncompatibleError = &Error{"Operation and DB incompatible, or DB flags changed"}
+ BadReaderSlotError = &Error{"Invalid reuse of reader locktable slot"}
+ BadTransactionError = &Error{"Transaction cannot recover - it must be aborted"}
+ BadValueSizeError = &Error{"Too big key/data, key is empty, or wrong DUPFIXED size"}
+)
+
+type Error struct {
+ message string
+}
+
+func (e *Error) Error() {
+ return e.message
+}
diff --git a/info.go b/info.go
new file mode 100644
index 0000000..d9642a5
--- /dev/null
+++ b/info.go
@@ -0,0 +1,10 @@
+package bolt
+
+// info contains information about the database.
+type info struct {
+ MapSize int
+ LastPageID int
+ LastTransactionID int
+ MaxReaders int
+ ReaderCount int
+}
diff --git a/meta.go b/meta.go
new file mode 100644
index 0000000..defa85b
--- /dev/null
+++ b/meta.go
@@ -0,0 +1,32 @@
+package bolt
+
+type meta struct {
+ magic int32
+ version int32
+ mapSize int
+ free *bucket
+ main *bucket
+ lastPageNumber int
+ transactionID int
+}
+
+// TODO: #define mm_psize mm_dbs[0].md_pad
+// TODO: #define mm_flags mm_dbs[0].md_flags
+
+// TODO:
+// typedef union MDB_metabuf {
+// MDB_page mb_page;
+// struct {
+// char mm_pad[PAGEHDRSZ];
+// MDB_meta mm_meta;
+// } mb_metabuf;
+// } MDB_metabuf;
+
+// TODO:
+// typedef struct MDB_dbx {
+// MDB_val md_name; /**< name of the database */
+// MDB_cmp_func *md_cmp; /**< function for comparing keys */
+// MDB_cmp_func *md_dcmp; /**< function for comparing data items */
+// MDB_rel_func *md_rel; /**< user relocate function */
+// void *md_relctx; /**< user-provided context for md_rel */
+// } MDB_dbx;
diff --git a/node.go b/node.go
new file mode 100644
index 0000000..38b0293
--- /dev/null
+++ b/node.go
@@ -0,0 +1,40 @@
+package bolt
+
+const (
+ bigNode = 0x01
+ subNode = 0x02
+ dupNode = 0x04
+)
+
+type node struct {
+ lo int
+ hi int
+ flags int
+ keySize int
+ data []byte
+}
+
+func (n *node) setFlags(f int) {
+ // Valid flags: (F_DUPDATA|F_SUBDATA|MDB_RESERVE|MDB_APPEND)
+ // TODO
+}
+
+func (n *node) size() int {
+ return 0 // TODO: offsetof(MDB_node, mn_data)
+}
+
+// TODO: #define INDXSIZE(k) (NODESIZE + ((k) == NULL ? 0 : (k)->mv_size))
+// TODO: #define LEAFSIZE(k, d) (NODESIZE + (k)->mv_size + (d)->mv_size)
+// TODO: #define NODEPTR(p, i) ((MDB_node *)((char *)(p) + (p)->mp_ptrs[i]))
+// TODO: #define NODEKEY(node) (void *)((node)->mn_data)
+// TODO: #define NODEDATA(node) (void *)((char *)(node)->mn_data + (node)->mn_ksize)
+// TODO: #define NODEPGNO(node) ((node)->mn_lo | ((pgno_t) (node)->mn_hi << 16) | (PGNO_TOPWORD ? ((pgno_t) (node)->mn_flags << PGNO_TOPWORD) : 0))
+// TODO: #define SETPGNO(node,pgno) do { (node)->mn_lo = (pgno) & 0xffff; (node)->mn_hi = (pgno) >> 16; if (PGNO_TOPWORD) (node)->mn_flags = (pgno) >> PGNO_TOPWORD; } while(0)
+// TODO: #define NODEDSZ(node) ((node)->mn_lo | ((unsigned)(node)->mn_hi << 16))
+// TODO: #define SETDSZ(node,size) do { (node)->mn_lo = (size) & 0xffff; (node)->mn_hi = (size) >> 16;} while(0)
+// TODO: #define NODEKSZ(node) ((node)->mn_ksize)
+
+// TODO: #define LEAF2KEY(p, i, ks) ((char *)(p) + PAGEHDRSZ + ((i)*(ks)))
+
+// TODO: #define MDB_GET_KEY(node, keyptr) { if ((keyptr) != NULL) { (keyptr)->mv_size = NODEKSZ(node); (keyptr)->mv_data = NODEKEY(node); } }
+// TODO: #define MDB_GET_KEY2(node, key) { key.mv_size = NODEKSZ(node); key.mv_data = NODEKEY(node); }
diff --git a/page.go b/page.go
new file mode 100644
index 0000000..3f1e6b3
--- /dev/null
+++ b/page.go
@@ -0,0 +1,44 @@
+package bolt
+
+import (
+ "unsafe"
+)
+
+const MinPageKeys = 2
+const FillThreshold = 250 // 25%
+
+const (
+ BranchPage = 0x01
+ LeafPage = 0x02
+ OverflowPage = 0x04
+ MetaPage = 0x08
+ DirtyPage = 0x10 /**< dirty page, also set for #P_SUBP pages */
+ SubPage = 0x40
+ KeepPage = 0x8000 /**< leave this page alone during spill */
+)
+
+type page struct {
+ header struct {
+ id int
+ next *page // (?)
+ lower int
+ upper int
+ overflowPageCount int
+ }
+ metadata []byte
+}
+
+// nodeCount returns the number of nodes on the page.
+func (p *page) nodeCount() int {
+ return 0 // (p.header.lower - unsafe.Sizeof(p.header) >> 1
+}
+
+// remainingSize returns the number of bytes left in the page.
+func (p *page) remainingSize() int {
+ return p.header.upper - p.header.lower
+}
+
+// remainingSize returns the number of bytes left in the page.
+func (p *page) remainingSize() int {
+ return p.header.upper - p.header.lower
+}
diff --git a/reader.go b/reader.go
new file mode 100644
index 0000000..c51517c
--- /dev/null
+++ b/reader.go
@@ -0,0 +1,5 @@
+package bolt
+
+type reader struct {
+ int transactionID
+}
diff --git a/stat.go b/stat.go
new file mode 100644
index 0000000..b01fa99
--- /dev/null
+++ b/stat.go
@@ -0,0 +1,10 @@
+package bolt
+
+type Stat struct {
+ PageSize int
+ Depth int
+ BranchPageCount int
+ LeafPageCount int
+ OverflowPageCount int
+ EntryCount int
+}
diff --git a/transaction.go b/transaction.go
new file mode 100644
index 0000000..74118d1
--- /dev/null
+++ b/transaction.go
@@ -0,0 +1,33 @@
+package bolt
+
+// TODO: #define DB_DIRTY 0x01 /**< DB was modified or is DUPSORT data */
+// TODO: #define DB_STALE 0x02 /**< Named-DB record is older than txnID */
+// TODO: #define DB_NEW 0x04 /**< Named-DB handle opened in this txn */
+// TODO: #define DB_VALID 0x08 /**< DB handle is valid, see also #MDB_VALID */
+
+// TODO: #define MDB_TXN_RDONLY 0x01 /**< read-only transaction */
+// TODO: #define MDB_TXN_ERROR 0x02 /**< an error has occurred */
+// TODO: #define MDB_TXN_DIRTY 0x04 /**< must write, even if dirty list is empty */
+// TODO: #define MDB_TXN_SPILLS 0x08 /**< txn or a parent has spilled pages */
+
+type Transaction interface {
+}
+
+type transaction struct {
+ id int
+ flags int
+ db *db
+ parent *transaction
+ child *transaction
+ nextPageNumber int
+ freePages []int
+ spillPages []int
+ dirtyList []int
+ reader *reader
+ // TODO: bucketxs []*bucketx
+ buckets []*bucket
+ bucketFlags []int
+ cursors []*cursor
+ // Implicit from slices? TODO: MDB_dbi mt_numdbs;
+ mt_dirty_room int
+}
diff --git a/warn.go b/warn.go
new file mode 100644
index 0000000..7e9a2a7
--- /dev/null
+++ b/warn.go
@@ -0,0 +1,14 @@
+package bolt
+
+import (
+ "fmt"
+ "os"
+)
+
+func warn(v ...interface{}) {
+ fmt.Fprintln(os.Stderr, v...)
+}
+
+func warnf(msg string, v ...interface{}) {
+ fmt.Fprintf(os.Stderr, msg, v...)
+}
diff --git a/xcursor.go b/xcursor.go
new file mode 100644
index 0000000..fa0e915
--- /dev/null
+++ b/xcursor.go
@@ -0,0 +1,8 @@
+package bolt
+
+type xcursor struct {
+ cursor cursor
+ bucket *bucket
+ bucketx *bucketx
+ bucketFlag int
+}