1
0
mirror of https://github.com/taigrr/bitcask synced 2025-01-18 04:03:17 -08:00

Use []byte byte slices as keys directly avoiding serialing string(s) (#46) (#51)

This commit is contained in:
James Mills
2019-08-08 08:14:48 +10:00
committed by GitHub
parent d0c913ccee
commit 755b1879b5
15 changed files with 147 additions and 99 deletions

View File

@@ -6,7 +6,7 @@ import (
pb "github.com/prologic/bitcask/internal/proto"
)
func NewEntry(key string, value []byte) pb.Entry {
func NewEntry(key, value []byte) pb.Entry {
checksum := crc32.ChecksumIEEE(value)
return pb.Entry{

View File

@@ -17,51 +17,58 @@ type Item struct {
type Keydir struct {
sync.RWMutex
kv map[string]Item
keys map[uint64][]byte
items map[uint64]Item
}
func NewKeydir() *Keydir {
return &Keydir{
kv: make(map[string]Item),
keys: make(map[uint64][]byte),
items: make(map[uint64]Item),
}
}
func (k *Keydir) Add(key string, fileid int, offset, size int64) Item {
func (k *Keydir) Add(key []byte, fileid int, offset, size int64) Item {
item := Item{
FileID: fileid,
Offset: offset,
Size: size,
}
hash := Hash(key)
k.Lock()
k.kv[key] = item
k.keys[hash] = key
k.items[hash] = item
k.Unlock()
return item
}
func (k *Keydir) Get(key string) (Item, bool) {
func (k *Keydir) Get(key []byte) (Item, bool) {
k.RLock()
item, ok := k.kv[key]
item, ok := k.items[Hash(key)]
k.RUnlock()
return item, ok
}
func (k *Keydir) Delete(key string) {
func (k *Keydir) Delete(key []byte) {
hash := Hash(key)
k.Lock()
delete(k.kv, key)
delete(k.keys, hash)
delete(k.items, hash)
k.Unlock()
}
func (k *Keydir) Len() int {
return len(k.kv)
return len(k.keys)
}
func (k *Keydir) Keys() chan string {
ch := make(chan string)
func (k *Keydir) Keys() chan []byte {
ch := make(chan []byte)
go func() {
k.RLock()
for key := range k.kv {
for _, key := range k.keys {
ch <- key
}
close(ch)
@@ -73,8 +80,10 @@ func (k *Keydir) Keys() chan string {
func (k *Keydir) Bytes() ([]byte, error) {
var buf bytes.Buffer
enc := gob.NewEncoder(&buf)
err := enc.Encode(k.kv)
if err != nil {
if err := enc.Encode(k.keys); err != nil {
return nil, err
}
if err := enc.Encode(k.items); err != nil {
return nil, err
}
return buf.Bytes(), nil
@@ -88,7 +97,10 @@ func (k *Keydir) Load(fn string) error {
defer f.Close()
dec := gob.NewDecoder(f)
if err := dec.Decode(&k.kv); err != nil {
if err := dec.Decode(&k.keys); err != nil {
return err
}
if err := dec.Decode(&k.items); err != nil {
return err
}
@@ -107,8 +119,10 @@ func (k *Keydir) Save(fn string) error {
func NewKeydirFromBytes(r io.Reader) (*Keydir, error) {
k := NewKeydir()
dec := gob.NewDecoder(r)
err := dec.Decode(&k.kv)
if err != nil {
if err := dec.Decode(&k.keys); err != nil {
return nil, err
}
if err := dec.Decode(&k.items); err != nil {
return nil, err
}
return k, nil

View File

@@ -20,7 +20,7 @@ const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type Entry struct {
Checksum uint32 `protobuf:"varint,1,opt,name=Checksum,proto3" json:"Checksum,omitempty"`
Key string `protobuf:"bytes,2,opt,name=Key,proto3" json:"Key,omitempty"`
Key []byte `protobuf:"bytes,2,opt,name=Key,proto3" json:"Key,omitempty"`
Offset int64 `protobuf:"varint,3,opt,name=Offset,proto3" json:"Offset,omitempty"`
Value []byte `protobuf:"bytes,4,opt,name=Value,proto3" json:"Value,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
@@ -32,7 +32,7 @@ func (m *Entry) Reset() { *m = Entry{} }
func (m *Entry) String() string { return proto.CompactTextString(m) }
func (*Entry) ProtoMessage() {}
func (*Entry) Descriptor() ([]byte, []int) {
return fileDescriptor_entry_db5b99f271e6b4b6, []int{0}
return fileDescriptor_entry_085f82c8520d7cd0, []int{0}
}
func (m *Entry) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Entry.Unmarshal(m, b)
@@ -59,11 +59,11 @@ func (m *Entry) GetChecksum() uint32 {
return 0
}
func (m *Entry) GetKey() string {
func (m *Entry) GetKey() []byte {
if m != nil {
return m.Key
}
return ""
return nil
}
func (m *Entry) GetOffset() int64 {
@@ -84,16 +84,16 @@ func init() {
proto.RegisterType((*Entry)(nil), "proto.Entry")
}
func init() { proto.RegisterFile("entry.proto", fileDescriptor_entry_db5b99f271e6b4b6) }
func init() { proto.RegisterFile("entry.proto", fileDescriptor_entry_085f82c8520d7cd0) }
var fileDescriptor_entry_db5b99f271e6b4b6 = []byte{
// 126 bytes of a gzipped FileDescriptorProto
var fileDescriptor_entry_085f82c8520d7cd0 = []byte{
// 123 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4e, 0xcd, 0x2b, 0x29,
0xaa, 0xd4, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x05, 0x53, 0x4a, 0xc9, 0x5c, 0xac, 0xae,
0x20, 0x51, 0x21, 0x29, 0x2e, 0x0e, 0xe7, 0x8c, 0xd4, 0xe4, 0xec, 0xe2, 0xd2, 0x5c, 0x09, 0x46,
0x05, 0x46, 0x0d, 0xde, 0x20, 0x38, 0x5f, 0x48, 0x80, 0x8b, 0xd9, 0x3b, 0xb5, 0x52, 0x82, 0x49,
0x81, 0x51, 0x83, 0x33, 0x08, 0xc4, 0x14, 0x12, 0xe3, 0x62, 0xf3, 0x4f, 0x4b, 0x2b, 0x4e, 0x2d,
0x81, 0x51, 0x83, 0x27, 0x08, 0xc4, 0x14, 0x12, 0xe3, 0x62, 0xf3, 0x4f, 0x4b, 0x2b, 0x4e, 0x2d,
0x91, 0x60, 0x56, 0x60, 0xd4, 0x60, 0x0e, 0x82, 0xf2, 0x84, 0x44, 0xb8, 0x58, 0xc3, 0x12, 0x73,
0x4a, 0x53, 0x25, 0x58, 0x14, 0x18, 0x35, 0x78, 0x82, 0x20, 0x9c, 0x24, 0x36, 0xb0, 0x5d, 0xc6,
0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x76, 0xd2, 0x3e, 0x83, 0x81, 0x00, 0x00, 0x00,
0x4a, 0x53, 0x25, 0x58, 0xc0, 0x6a, 0x21, 0x9c, 0x24, 0x36, 0xb0, 0x5d, 0xc6, 0x80, 0x00, 0x00,
0x00, 0xff, 0xff, 0x47, 0x6a, 0x41, 0xd4, 0x81, 0x00, 0x00, 0x00,
}

View File

@@ -4,7 +4,7 @@ package proto;
message Entry {
uint32 Checksum = 1;
string Key = 2;
bytes Key = 2;
int64 Offset = 3;
bytes Value = 4;
}

View File

@@ -2,6 +2,7 @@ package internal
import (
"fmt"
"hash/fnv"
"os"
"path/filepath"
"sort"
@@ -9,6 +10,12 @@ import (
"strings"
)
func Hash(key []byte) uint64 {
h := fnv.New64a()
h.Write(key)
return h.Sum64()
}
func Exists(path string) bool {
_, err := os.Stat(path)
return err == nil