aboutsummaryrefslogtreecommitdiff
path: root/meta.go
diff options
context:
space:
mode:
Diffstat (limited to 'meta.go')
-rw-r--r--meta.go28
1 files changed, 20 insertions, 8 deletions
diff --git a/meta.go b/meta.go
index cc62637..abb2a93 100644
--- a/meta.go
+++ b/meta.go
@@ -2,6 +2,8 @@ package bolt
import (
"errors"
+ "hash/fnv"
+ "unsafe"
)
const magic uint32 = 0xED0CDAED
@@ -13,6 +15,9 @@ var (
// 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 {
@@ -24,11 +29,14 @@ type meta struct {
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.magic != magic {
+ if m.checksum != 0 && m.checksum != m.sum64() {
+ return ErrChecksum
+ } else if m.magic != magic {
return ErrInvalid
} else if m.version != version {
return ErrVersionMismatch
@@ -38,13 +46,7 @@ func (m *meta) validate() error {
// copy copies one meta object to another.
func (m *meta) copy(dest *meta) {
- dest.magic = m.magic
- dest.version = m.version
- dest.pageSize = m.pageSize
- dest.buckets = m.buckets
- dest.freelist = m.freelist
- dest.pgid = m.pgid
- dest.txid = m.txid
+ *dest = *m
}
// write writes the meta onto a page.
@@ -53,5 +55,15 @@ func (m *meta) write(p *page) {
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()
+}