diff --git a/0105/kv_entry.go b/0105/kv_entry.go index 27e5f3c..bff2ad3 100644 --- a/0105/kv_entry.go +++ b/0105/kv_entry.go @@ -1,20 +1,66 @@ package db0105 import ( + "encoding/binary" "errors" + "hash/crc32" "io" ) type Entry struct { + crc32 []byte key []byte val []byte deleted bool } -func (ent *Entry) Encode() []byte +func (ent *Entry) Encode() []byte { + data := make([]byte, 4+4+4+1+len(ent.key)+len(ent.val)) + binary.LittleEndian.PutUint32(data[4:8], uint32(len(ent.key))) + copy(data[13:], ent.key) + if ent.deleted { + data[12] = 1 + } else { + binary.LittleEndian.PutUint32(data[8:12], uint32(len(ent.val))) + copy(data[13+len(ent.key):], ent.val) + } + checksum := crc32.ChecksumIEEE(data[4:]) + binary.LittleEndian.PutUint32(data[0:4], checksum) + return data +} var ErrBadSum = errors.New("bad checksum") -func (ent *Entry) Decode(r io.Reader) error +func (ent *Entry) Decode(r io.Reader) error { + var header [13]byte + if _, err := io.ReadFull(r, header[:]); err != nil { + return err + } + klen := int(binary.LittleEndian.Uint32(header[4:8])) + vlen := int(binary.LittleEndian.Uint32(header[8:12])) + deleted := header[12] + + data := make([]byte, klen+vlen) + if _, err := io.ReadFull(r, data); err != nil { + return err + } + + checksum := crc32.NewIEEE() + checksum.Write(header[4:]) + checksum.Write(data) + + if checksum.Sum32() != binary.LittleEndian.Uint32(header[0:4]) { + return ErrBadSum + } + + ent.key = data[:klen] + if deleted != 0 { + ent.deleted = true + } else { + ent.deleted = false + ent.val = data[klen:] + } + return nil +} // QzBQWVJJOUhU https://trialofcode.org/ diff --git a/0105/log.go b/0105/log.go index f67a430..a5be976 100644 --- a/0105/log.go +++ b/0105/log.go @@ -1,6 +1,7 @@ package db0105 import ( + "io" "os" ) @@ -25,6 +26,16 @@ func (log *Log) Write(ent *Entry) error { return log.fp.Sync() // fsync } -func (log *Log) Read(ent *Entry) (eof bool, err error) +func (log *Log) Read(ent *Entry) (eof bool, err error) { + err = ent.Decode(log.fp) + if err == io.EOF || err == io.ErrUnexpectedEOF || err == ErrBadSum { + return true, nil + } else if err != nil { + return false, err + + } else { + return false, nil + } +} // QzBQWVJJOUhU https://trialofcode.org/