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.
master
Ben Johnson 2014-05-05 07:56:54 -06:00
parent 383ddb246a
commit c3903d38a1
10 changed files with 120 additions and 139 deletions

30
bolt.go
View File

@ -1,29 +1,9 @@
// +build !linux
package bolt package bolt
import ( import "os"
"fmt"
"os"
)
// ErrorList represents a slice of errors. func fdatasync(f *os.File) error {
type ErrorList []error return f.Sync()
// 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...)
} }

View File

@ -7,6 +7,14 @@ import (
"unsafe" "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 ( var (
// ErrBucketNotFound is returned when trying to access a bucket that has // ErrBucketNotFound is returned when trying to access a bucket that has
// not been created yet. // not been created yet.
@ -37,6 +45,13 @@ var (
ErrSequenceOverflow = errors.New("sequence overflow") 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. // Bucket represents a collection of key/value pairs inside the database.
type Bucket struct { type Bucket struct {
*bucket *bucket

View File

@ -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
)

88
db.go
View File

@ -3,6 +3,7 @@ package bolt
import ( import (
"errors" "errors"
"fmt" "fmt"
"hash/fnv"
"io" "io"
"os" "os"
"sync" "sync"
@ -16,6 +17,12 @@ const minMmapSize = 1 << 22 // 4MB
// The largest step that can be taken when remapping the mmap. // The largest step that can be taken when remapping the mmap.
const maxMmapStep = 1 << 30 // 1GB 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 ( var (
// ErrDatabaseNotOpen is returned when a DB instance is accessed before it // ErrDatabaseNotOpen is returned when a DB instance is accessed before it
// is opened or after it is closed. // is opened or after it is closed.
@ -24,6 +31,16 @@ var (
// ErrDatabaseOpen is returned when opening a database that is // ErrDatabaseOpen is returned when opening a database that is
// already open. // already open.
ErrDatabaseOpen = errors.New("database 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. // DB represents a collection of buckets persisted to a file on disk.
@ -652,3 +669,74 @@ type Info struct {
Data []byte Data []byte
PageSize int 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...)
}

View File

@ -353,6 +353,18 @@ func TestDBStats_Sub(t *testing.T) {
assert.Equal(t, 7, diff.TxStats.PageCount) 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() { func ExampleDB_Update() {
// Open the database. // Open the database.
db, _ := Open(tempfile(), 0666) db, _ := Open(tempfile(), 0666)

69
meta.go
View File

@ -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()
}

View File

@ -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)
}

View File

@ -1,9 +0,0 @@
// +build !linux
package bolt
import "os"
func fdatasync(f *os.File) error {
return f.Sync()
}