package db0304 import ( "bytes" ) type KV struct { log Log mem map[string][]byte } func (kv *KV) Open() error { if err := kv.log.Open(); err != nil { return err } kv.mem = map[string][]byte{} for { ent := Entry{} eof, err := kv.log.Read(&ent) if err != nil { return err } else if eof { break } if ent.deleted { delete(kv.mem, string(ent.key)) } else { kv.mem[string(ent.key)] = ent.val } } return nil } func (kv *KV) Close() error { return kv.log.Close() } func (kv *KV) Get(key []byte) (val []byte, ok bool, err error) { val, ok = kv.mem[string(key)] return } type UpdateMode int const ( ModeUpsert UpdateMode = 0 // insert or update ModeInsert UpdateMode = 1 // insert new ModeUpdate UpdateMode = 2 // update existing ) func (kv *KV) SetEx(key []byte, val []byte, mode UpdateMode) (updated bool, err error) { prev, exist := kv.mem[string(key)] switch mode { case ModeUpsert: updated = !exist || !bytes.Equal(prev, val) case ModeInsert: updated = !exist case ModeUpdate: updated = exist && !bytes.Equal(prev, val) default: panic("unreachable") } if updated { if err = kv.log.Write(&Entry{key: key, val: val}); err != nil { return false, err } kv.mem[string(key)] = val } return } func (kv *KV) Set(key []byte, val []byte) (updated bool, err error) { return kv.SetEx(key, val, ModeUpsert) } func (kv *KV) Del(key []byte) (deleted bool, err error) { _, deleted = kv.mem[string(key)] if deleted { if err = kv.log.Write(&Entry{key: key, deleted: true}); err != nil { return false, err } delete(kv.mem, string(key)) } return } // QzBQWVJJOUhU https://trialofcode.org/