mirror of
https://github.com/taigrr/bitcask
synced 2025-01-18 04:03:17 -08:00
This commit is contained in:
@@ -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{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ package proto;
|
||||
|
||||
message Entry {
|
||||
uint32 Checksum = 1;
|
||||
string Key = 2;
|
||||
bytes Key = 2;
|
||||
int64 Offset = 3;
|
||||
bytes Value = 4;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user