mirror of
https://github.com/geektutu/7days-golang.git
synced 2024-04-21 12:32:11 +00:00
init geebolt
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
module geebolt
|
||||
|
||||
go 1.13
|
||||
@@ -0,0 +1,33 @@
|
||||
package geebolt
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"hash/fnv"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Represent a marker value to indicate that a file is a gee-bolt DB
|
||||
const magic uint32 = 0xED0CDAED
|
||||
|
||||
type meta struct {
|
||||
magic uint32
|
||||
pageSize uint32
|
||||
pgid uint64
|
||||
checksum uint64
|
||||
}
|
||||
|
||||
func (m *meta) sum64() uint64 {
|
||||
var h = fnv.New64a()
|
||||
_, _ = h.Write((*[unsafe.Offsetof(meta{}.checksum)]byte)(unsafe.Pointer(m))[:])
|
||||
return h.Sum64()
|
||||
}
|
||||
|
||||
func (m *meta) validate() error {
|
||||
if m.magic != magic {
|
||||
return errors.New("invalid magic number")
|
||||
}
|
||||
if m.checksum != m.sum64() {
|
||||
return errors.New("invalid checksum")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package geebolt
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const pageHeaderSize = unsafe.Sizeof(page{})
|
||||
const branchPageElementSize = unsafe.Sizeof(branchPageElement{})
|
||||
const leafPageElementSize = unsafe.Sizeof(leafPageElement{})
|
||||
const maxKeysPerPage = 1024
|
||||
|
||||
const (
|
||||
branchPageFlag uint16 = iota
|
||||
leafPageFlag
|
||||
metaPageFlag
|
||||
freelistPageFlag
|
||||
)
|
||||
|
||||
type page struct {
|
||||
id uint64
|
||||
flags uint16
|
||||
count uint16
|
||||
overflow uint32
|
||||
}
|
||||
|
||||
type leafPageElement struct {
|
||||
pos uint32
|
||||
ksize uint32
|
||||
vsize uint32
|
||||
}
|
||||
|
||||
type branchPageElement struct {
|
||||
pos uint32
|
||||
ksize uint32
|
||||
pgid uint64
|
||||
}
|
||||
|
||||
func (p *page) typ() string {
|
||||
switch p.flags {
|
||||
case branchPageFlag:
|
||||
return "branch"
|
||||
case leafPageFlag:
|
||||
return "leaf"
|
||||
case metaPageFlag:
|
||||
return "meta"
|
||||
case freelistPageFlag:
|
||||
return "freelist"
|
||||
}
|
||||
return fmt.Sprintf("unknown<%02x>", p.flags)
|
||||
}
|
||||
|
||||
func (p *page) meta() *meta {
|
||||
return (*meta)(unsafe.Pointer(uintptr(unsafe.Pointer(p)) + pageHeaderSize))
|
||||
}
|
||||
|
||||
func (p *page) dataPtr() unsafe.Pointer {
|
||||
return unsafe.Pointer(&reflect.SliceHeader{
|
||||
Data: uintptr(unsafe.Pointer(p)) + pageHeaderSize,
|
||||
Len: int(p.count),
|
||||
Cap: int(p.count),
|
||||
})
|
||||
}
|
||||
|
||||
func (p *page) leafPageElement(index uint16) *leafPageElement {
|
||||
off := pageHeaderSize + uintptr(index)*leafPageElementSize
|
||||
return (*leafPageElement)(unsafe.Pointer(uintptr(unsafe.Pointer(p)) + off))
|
||||
}
|
||||
|
||||
func (p *page) leafPageElements() []leafPageElement {
|
||||
if p.count == 0 {
|
||||
return nil
|
||||
}
|
||||
return *(*[]leafPageElement)(p.dataPtr())
|
||||
}
|
||||
|
||||
func (p *page) branchPageElement(index uint16) *branchPageElement {
|
||||
off := pageHeaderSize + uintptr(index)*branchPageElementSize
|
||||
return (*branchPageElement)(unsafe.Pointer(uintptr(unsafe.Pointer(p)) + off))
|
||||
}
|
||||
|
||||
func (p *page) branchPageElements() []branchPageElement {
|
||||
if p.count == 0 {
|
||||
return nil
|
||||
}
|
||||
return *(*[]branchPageElement)(p.dataPtr())
|
||||
}
|
||||
Reference in New Issue
Block a user