aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cursor.go1
-rw-r--r--db.go23
-rw-r--r--db_test.go16
-rw-r--r--meta.go11
-rw-r--r--page.go30
5 files changed, 43 insertions, 38 deletions
diff --git a/cursor.go b/cursor.go
index e6b2c31..f6f0168 100644
--- a/cursor.go
+++ b/cursor.go
@@ -39,7 +39,6 @@ func (c *Cursor) Get(key []byte) []byte {
func (c *Cursor) Goto(key []byte) bool {
// TODO(benbjohnson): Optimize for specific use cases.
- // TODO: Check if len(key) > 0.
// TODO: Start from root page and traverse to correct page.
return false
diff --git a/db.go b/db.go
index 275c4f5..bca4d56 100644
--- a/db.go
+++ b/db.go
@@ -91,11 +91,11 @@ func (db *DB) Open(path string, mode os.FileMode) error {
// Read the first meta page to determine the page size.
var buf [minPageSize]byte
if _, err := db.file.ReadAt(buf[:], 0); err == nil {
- if m, err := db.pageInBuffer(buf[:], 0).meta(); err != nil {
- return &Error{"meta bootstrap error", err}
- } else if m != nil {
- db.pageSize = int(m.pageSize)
+ m := db.pageInBuffer(buf[:], 0).meta()
+ if err := m.validate(); err != nil {
+ return &Error{"meta error", err}
}
+ db.pageSize = int(m.pageSize)
}
}
@@ -126,10 +126,14 @@ func (db *DB) mmap() error {
}
// Save references to the meta pages.
- if db.meta0, err = db.page(0).meta(); err != nil {
+ db.meta0 = db.page(0).meta()
+ db.meta1 = db.page(1).meta()
+
+ // Validate the meta pages.
+ if err := db.meta0.validate(); err != nil {
return &Error{"meta0 error", err}
}
- if db.meta1, err = db.page(1).meta(); err != nil {
+ if err := db.meta1.validate(); err != nil {
return &Error{"meta1 error", err}
}
@@ -146,7 +150,12 @@ func (db *DB) init() error {
for i := 0; i < 2; i++ {
p := db.pageInBuffer(buf[:], pgid(i))
p.id = pgid(i)
- p.init(db.pageSize)
+ p.flags = p_meta
+
+ m := p.meta()
+ m.magic = magic
+ m.version = Version
+ m.pageSize = uint32(db.pageSize)
}
// Write the buffer to our data file.
diff --git a/db_test.go b/db_test.go
index 20ed51c..7430081 100644
--- a/db_test.go
+++ b/db_test.go
@@ -121,13 +121,18 @@ func TestDBMmapError(t *testing.T) {
// Ensure that corrupt meta0 page errors get returned.
func TestDBCorruptMeta0(t *testing.T) {
withMockDB(func(db *DB, mockos *mockos, mocksyscall *mocksyscall, path string) {
+ var m meta
+ m.magic = magic
+ m.version = Version
+ m.pageSize = 0x8000
+
// Create a file with bad magic.
b := make([]byte, 0x10000)
p0, p1 := (*page)(unsafe.Pointer(&b[0x0000])), (*page)(unsafe.Pointer(&b[0x8000]))
- p0.init(0x8000)
- p1.init(0x8000)
- m, _ := p0.meta()
- m.magic = 0
+ p0.meta().magic = 0
+ p0.meta().version = Version
+ p1.meta().magic = magic
+ p1.meta().version = Version
// Mock file access.
file, metafile := &mockfile{}, &mockfile{}
@@ -141,7 +146,8 @@ func TestDBCorruptMeta0(t *testing.T) {
// Open the database.
err := db.Open(path, 0666)
- assert.Equal(t, err, &Error{"meta bootstrap error", InvalidMetaPageError})
+ warn(err)
+ assert.Equal(t, err, &Error{"meta error", InvalidError})
})
}
diff --git a/meta.go b/meta.go
index a473ff0..5fafa1d 100644
--- a/meta.go
+++ b/meta.go
@@ -3,7 +3,6 @@ package bolt
var (
InvalidError = &Error{"Invalid database", nil}
VersionMismatchError = &Error{"version mismatch", nil}
- InvalidMetaPageError = &Error{"invalid meta page", nil}
)
const magic uint32 = 0xC0DEC0DE
@@ -12,10 +11,10 @@ const version uint32 = 1
type meta struct {
magic uint32
version uint32
- sys bucket
pageSize uint32
pgid pgid
txnid txnid
+ sys bucket
}
// validate checks the marker bytes and version of the meta page to ensure it matches this binary.
@@ -27,3 +26,11 @@ func (m *meta) validate() error {
}
return nil
}
+
+// copy copies one meta object to another.
+func (m *meta) copy(dest *meta) {
+ dest.pageSize = m.pageSize
+ dest.pgid = m.pgid
+ dest.txnid = m.txnid
+ dest.sys = m.sys
+}
diff --git a/page.go b/page.go
index dbfff64..d45d336 100644
--- a/page.go
+++ b/page.go
@@ -27,32 +27,16 @@ type page struct {
}
// meta returns a pointer to the metadata section of the page.
-func (p *page) meta() (*meta, error) {
- // Exit if page is not a meta page.
- if (p.flags & p_meta) == 0 {
- return nil, InvalidMetaPageError
- }
-
- // Cast the meta section and validate before returning.
- m := (*meta)(unsafe.Pointer(&p.ptr))
- if err := m.validate(); err != nil {
- return nil, err
- }
- return m, nil
-}
-
-// init initializes a page as a new meta page.
-func (p *page) init(pageSize int) {
- p.flags = p_meta
- m := (*meta)(unsafe.Pointer(&p.ptr))
- m.magic = magic
- m.version = version
- m.pageSize = uint32(pageSize)
- m.pgid = 1
- m.sys.root = 0
+func (p *page) meta() *meta {
+ return (*meta)(unsafe.Pointer(&p.ptr))
}
// lnode retrieves the leaf node by index
func (p *page) lnode(index int) *lnode {
return &((*[maxNodesPerPage]lnode)(unsafe.Pointer(&p.ptr)))[index]
}
+
+// bnode retrieves the branch node by index
+func (p *page) bnode(index int) *bnode {
+ return &((*[maxNodesPerPage]bnode)(unsafe.Pointer(&p.ptr)))[index]
+}