From c3903d38a10fda3c9a366d62705e06ddc558eb2d Mon Sep 17 00:00:00 2001 From: Ben Johnson Date: Mon, 5 May 2014 07:56:54 -0600 Subject: [PATCH] Consolidate code for clarity. This commit consolidates some of the smaller files into some of the larger files. The smaller files cluttered the file tree and made it harder to see the logical groupings of structs. --- bolt.go | 30 ++-------- syscall_linux.go => bolt_linux.go | 0 bucket.go | 15 +++++ const.go | 18 ------ db.go | 88 ++++++++++++++++++++++++++++++ db_test.go | 12 ++++ meta.go | 69 ----------------------- meta_test.go | 18 ------ bolt_test.go => simulation_test.go | 0 syscall.go | 9 --- 10 files changed, 120 insertions(+), 139 deletions(-) rename syscall_linux.go => bolt_linux.go (100%) delete mode 100644 const.go delete mode 100644 meta.go delete mode 100644 meta_test.go rename bolt_test.go => simulation_test.go (100%) delete mode 100644 syscall.go diff --git a/bolt.go b/bolt.go index f456582..c3a1bb5 100644 --- a/bolt.go +++ b/bolt.go @@ -1,29 +1,9 @@ +// +build !linux + package bolt -import ( - "fmt" - "os" -) +import "os" -// ErrorList represents a slice of errors. -type ErrorList []error - -// Error returns a readable count of the errors in the list. -func (l ErrorList) Error() string { - return fmt.Sprintf("%d errors occurred", len(l)) -} - -// _assert will panic with a given formatted message if the given condition is false. -func _assert(condition bool, msg string, v ...interface{}) { - if !condition { - panic(fmt.Sprintf("assertion failed: "+msg, v...)) - } -} - -func warn(v ...interface{}) { - fmt.Fprintln(os.Stderr, v...) -} - -func warnf(msg string, v ...interface{}) { - fmt.Fprintf(os.Stderr, msg+"\n", v...) +func fdatasync(f *os.File) error { + return f.Sync() } diff --git a/syscall_linux.go b/bolt_linux.go similarity index 100% rename from syscall_linux.go rename to bolt_linux.go diff --git a/bucket.go b/bucket.go index 0b9c17d..5dd79dd 100644 --- a/bucket.go +++ b/bucket.go @@ -7,6 +7,14 @@ import ( "unsafe" ) +const ( + // MaxKeySize is the maximum length of a key, in bytes. + MaxKeySize = 32768 + + // MaxValueSize is the maximum length of a value, in bytes. + MaxValueSize = 4294967295 +) + var ( // ErrBucketNotFound is returned when trying to access a bucket that has // not been created yet. @@ -37,6 +45,13 @@ var ( ErrSequenceOverflow = errors.New("sequence overflow") ) +const ( + maxUint = ^uint(0) + minUint = 0 + maxInt = int(^uint(0) >> 1) + minInt = -maxInt - 1 +) + // Bucket represents a collection of key/value pairs inside the database. type Bucket struct { *bucket diff --git a/const.go b/const.go deleted file mode 100644 index 4669347..0000000 --- a/const.go +++ /dev/null @@ -1,18 +0,0 @@ -package bolt - -const version = 2 - -const ( - maxUint = ^uint(0) - minUint = 0 - maxInt = int(^uint(0) >> 1) - minInt = -maxInt - 1 -) - -const ( - // MaxKeySize is the maximum length of a key, in bytes. - MaxKeySize = 32768 - - // MaxValueSize is the maximum length of a value, in bytes. - MaxValueSize = 4294967295 -) diff --git a/db.go b/db.go index 7e8dd7f..9754f21 100644 --- a/db.go +++ b/db.go @@ -3,6 +3,7 @@ package bolt import ( "errors" "fmt" + "hash/fnv" "io" "os" "sync" @@ -16,6 +17,12 @@ const minMmapSize = 1 << 22 // 4MB // The largest step that can be taken when remapping the mmap. const maxMmapStep = 1 << 30 // 1GB +// The data file format version. +const version = 2 + +// Represents a marker value to indicate that a file is a Bolt DB. +const magic uint32 = 0xED0CDAED + var ( // ErrDatabaseNotOpen is returned when a DB instance is accessed before it // is opened or after it is closed. @@ -24,6 +31,16 @@ var ( // ErrDatabaseOpen is returned when opening a database that is // already open. ErrDatabaseOpen = errors.New("database already open") + + // ErrInvalid is returned when a data file is not a Bolt-formatted database. + ErrInvalid = errors.New("invalid database") + + // ErrVersionMismatch is returned when the data file was created with a + // different version of Bolt. + ErrVersionMismatch = errors.New("version mismatch") + + // ErrChecksum is returned when either meta page checksum does not match. + ErrChecksum = errors.New("checksum error") ) // DB represents a collection of buckets persisted to a file on disk. @@ -652,3 +669,74 @@ type Info struct { Data []byte PageSize int } + +type meta struct { + magic uint32 + version uint32 + pageSize uint32 + flags uint32 + root bucket + freelist pgid + pgid pgid + txid txid + checksum uint64 +} + +// validate checks the marker bytes and version of the meta page to ensure it matches this binary. +func (m *meta) validate() error { + if m.checksum != 0 && m.checksum != m.sum64() { + return ErrChecksum + } else if m.magic != magic { + return ErrInvalid + } else if m.version != version { + return ErrVersionMismatch + } + return nil +} + +// copy copies one meta object to another. +func (m *meta) copy(dest *meta) { + *dest = *m +} + +// write writes the meta onto a page. +func (m *meta) write(p *page) { + // Page id is either going to be 0 or 1 which we can determine by the transaction ID. + p.id = pgid(m.txid % 2) + p.flags |= metaPageFlag + + // Calculate the checksum. + m.checksum = m.sum64() + + m.copy(p.meta()) +} + +// generates the checksum for the meta. +func (m *meta) sum64() uint64 { + var h = fnv.New64a() + _, _ = h.Write((*[unsafe.Offsetof(meta{}.checksum)]byte)(unsafe.Pointer(m))[:]) + return h.Sum64() +} + +// ErrorList represents a slice of errors. +type ErrorList []error + +// Error returns a readable count of the errors in the list. +func (l ErrorList) Error() string { + return fmt.Sprintf("%d errors occurred", len(l)) +} + +// _assert will panic with a given formatted message if the given condition is false. +func _assert(condition bool, msg string, v ...interface{}) { + if !condition { + panic(fmt.Sprintf("assertion failed: "+msg, v...)) + } +} + +func warn(v ...interface{}) { + fmt.Fprintln(os.Stderr, v...) +} + +func warnf(msg string, v ...interface{}) { + fmt.Fprintf(os.Stderr, msg+"\n", v...) +} diff --git a/db_test.go b/db_test.go index d0933e8..b7e2a2f 100644 --- a/db_test.go +++ b/db_test.go @@ -353,6 +353,18 @@ func TestDBStats_Sub(t *testing.T) { assert.Equal(t, 7, diff.TxStats.PageCount) } +// Ensure that meta with bad magic is invalid. +func TestMeta_validate_magic(t *testing.T) { + m := &meta{magic: 0x01234567} + assert.Equal(t, m.validate(), ErrInvalid) +} + +// Ensure that meta with a bad version is invalid. +func TestMeta_validate_version(t *testing.T) { + m := &meta{magic: magic, version: 200} + assert.Equal(t, m.validate(), ErrVersionMismatch) +} + func ExampleDB_Update() { // Open the database. db, _ := Open(tempfile(), 0666) diff --git a/meta.go b/meta.go deleted file mode 100644 index 4212252..0000000 --- a/meta.go +++ /dev/null @@ -1,69 +0,0 @@ -package bolt - -import ( - "errors" - "hash/fnv" - "unsafe" -) - -const magic uint32 = 0xED0CDAED - -var ( - // ErrInvalid is returned when a data file is not a Bolt-formatted database. - ErrInvalid = errors.New("invalid database") - - // ErrVersionMismatch is returned when the data file was created with a - // different version of Bolt. - ErrVersionMismatch = errors.New("version mismatch") - - // ErrChecksum is returned when either meta page checksum does not match. - ErrChecksum = errors.New("checksum error") -) - -type meta struct { - magic uint32 - version uint32 - pageSize uint32 - flags uint32 - root bucket - freelist pgid - pgid pgid - txid txid - checksum uint64 -} - -// validate checks the marker bytes and version of the meta page to ensure it matches this binary. -func (m *meta) validate() error { - if m.checksum != 0 && m.checksum != m.sum64() { - return ErrChecksum - } else if m.magic != magic { - return ErrInvalid - } else if m.version != version { - return ErrVersionMismatch - } - return nil -} - -// copy copies one meta object to another. -func (m *meta) copy(dest *meta) { - *dest = *m -} - -// write writes the meta onto a page. -func (m *meta) write(p *page) { - // Page id is either going to be 0 or 1 which we can determine by the transaction ID. - p.id = pgid(m.txid % 2) - p.flags |= metaPageFlag - - // Calculate the checksum. - m.checksum = m.sum64() - - m.copy(p.meta()) -} - -// generates the checksum for the meta. -func (m *meta) sum64() uint64 { - var h = fnv.New64a() - _, _ = h.Write((*[unsafe.Offsetof(meta{}.checksum)]byte)(unsafe.Pointer(m))[:]) - return h.Sum64() -} diff --git a/meta_test.go b/meta_test.go deleted file mode 100644 index 1a2d6b5..0000000 --- a/meta_test.go +++ /dev/null @@ -1,18 +0,0 @@ -package bolt - -import ( - "github.com/stretchr/testify/assert" - "testing" -) - -// Ensure that meta with bad magic is invalid. -func TestMeta_validate_magic(t *testing.T) { - m := &meta{magic: 0x01234567} - assert.Equal(t, m.validate(), ErrInvalid) -} - -// Ensure that meta with a bad version is invalid. -func TestMeta_validate_version(t *testing.T) { - m := &meta{magic: magic, version: 200} - assert.Equal(t, m.validate(), ErrVersionMismatch) -} diff --git a/bolt_test.go b/simulation_test.go similarity index 100% rename from bolt_test.go rename to simulation_test.go diff --git a/syscall.go b/syscall.go deleted file mode 100644 index c3a1bb5..0000000 --- a/syscall.go +++ /dev/null @@ -1,9 +0,0 @@ -// +build !linux - -package bolt - -import "os" - -func fdatasync(f *os.File) error { - return f.Sync() -}