cznicb KVStore batch uses <2 appends per Set/Delete
This commit is contained in:
parent
c5c59e61f4
commit
05d222f490
@ -58,12 +58,14 @@ type Iterator struct { // Assuming that iterators are used single-threaded.
|
|||||||
currErr error
|
currErr error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type op struct {
|
||||||
|
k []byte
|
||||||
|
v []byte
|
||||||
|
}
|
||||||
|
|
||||||
type Batch struct {
|
type Batch struct {
|
||||||
s *Store
|
s *Store
|
||||||
|
ops []op
|
||||||
m sync.Mutex
|
|
||||||
ks [][]byte
|
|
||||||
vs [][]byte
|
|
||||||
ms map[string]store.AssociativeMergeChain
|
ms map[string]store.AssociativeMergeChain
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +112,11 @@ func (s *Store) Delete(k []byte) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) NewBatch() store.KVBatch {
|
func (s *Store) NewBatch() store.KVBatch {
|
||||||
return &Batch{s: s, ms: map[string]store.AssociativeMergeChain{}}
|
return &Batch{
|
||||||
|
s: s,
|
||||||
|
ops: make([]op, 0, 100),
|
||||||
|
ms: map[string]store.AssociativeMergeChain{},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Iterator) SeekFirst() {
|
func (w *Iterator) SeekFirst() {
|
||||||
@ -196,41 +202,23 @@ func (w *Iterator) Close() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w *Batch) Set(k, v []byte) {
|
func (w *Batch) Set(k, v []byte) {
|
||||||
w.m.Lock()
|
w.ops = append(w.ops, op{k, v})
|
||||||
w.ks = append(w.ks, k)
|
|
||||||
w.vs = append(w.vs, v)
|
|
||||||
w.m.Unlock()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Batch) Delete(k []byte) {
|
func (w *Batch) Delete(k []byte) {
|
||||||
w.m.Lock()
|
w.ops = append(w.ops, op{k, nil})
|
||||||
w.ks = append(w.ks, k)
|
|
||||||
w.vs = append(w.vs, nil)
|
|
||||||
w.m.Unlock()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Batch) Merge(k []byte, oper store.AssociativeMerge) {
|
func (w *Batch) Merge(k []byte, oper store.AssociativeMerge) {
|
||||||
key := string(k)
|
w.ms[string(k)] = append(w.ms[string(k)], oper)
|
||||||
w.m.Lock()
|
|
||||||
w.ms[key] = append(w.ms[key], oper)
|
|
||||||
w.m.Unlock()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Batch) Execute() (err error) {
|
func (w *Batch) Execute() (err error) {
|
||||||
w.m.Lock()
|
|
||||||
ks := w.ks
|
|
||||||
w.ks = nil
|
|
||||||
vs := w.vs
|
|
||||||
w.vs = nil
|
|
||||||
ms := w.ms
|
|
||||||
w.ms = map[string]store.AssociativeMergeChain{}
|
|
||||||
w.m.Unlock()
|
|
||||||
|
|
||||||
w.s.m.Lock()
|
w.s.m.Lock()
|
||||||
defer w.s.m.Unlock()
|
defer w.s.m.Unlock()
|
||||||
|
|
||||||
t := w.s.t
|
t := w.s.t
|
||||||
for key, mc := range ms {
|
for key, mc := range w.ms {
|
||||||
k := []byte(key)
|
k := []byte(key)
|
||||||
b := []byte(nil)
|
b := []byte(nil)
|
||||||
v, ok := t.Get(k)
|
v, ok := t.Get(k)
|
||||||
@ -248,12 +236,11 @@ func (w *Batch) Execute() (err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, k := range ks {
|
for _, op := range w.ops {
|
||||||
v := vs[i]
|
if op.v != nil {
|
||||||
if v != nil {
|
t.Set(op.k, op.v)
|
||||||
t.Set(k, v)
|
|
||||||
} else {
|
} else {
|
||||||
t.Delete(k)
|
t.Delete(op.k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,10 +248,5 @@ func (w *Batch) Execute() (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w *Batch) Close() error {
|
func (w *Batch) Close() error {
|
||||||
w.m.Lock()
|
|
||||||
w.ks = nil
|
|
||||||
w.vs = nil
|
|
||||||
w.ms = nil
|
|
||||||
w.m.Unlock()
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user