0
0

gtreap KVStore does 1 append for batch Set/Delete

This commit is contained in:
Steve Yen 2015-01-29 10:49:39 -08:00
parent 05d222f490
commit b054cddf76

View File

@ -53,13 +53,6 @@ type Reader struct {
t *gtreap.Treap t *gtreap.Treap
} }
type Writer struct {
s *Store
m sync.Mutex
t *gtreap.Treap
}
type Iterator struct { type Iterator struct {
t *gtreap.Treap t *gtreap.Treap
@ -75,19 +68,12 @@ func newIterator(t *gtreap.Treap) *Iterator {
} }
type Batch struct { type Batch struct {
w *Writer s *Store
items []*Item
m sync.Mutex ms map[string]store.AssociativeMergeChain
ks [][]byte
vs [][]byte
ms map[string]store.AssociativeMergeChain
} }
func (s *Store) Close() error { func (s *Store) Close() error {
s.m.Lock()
s.t = nil
s.m.Unlock()
return nil return nil
} }
@ -99,10 +85,7 @@ func (s *Store) Reader() (store.KVReader, error) {
} }
func (s *Store) Writer() (store.KVWriter, error) { func (s *Store) Writer() (store.KVWriter, error) {
s.m.Lock() return s, nil
t := s.t
s.m.Unlock()
return &Writer{s: s, t: t}, nil
} }
func (w *Reader) Get(k []byte) (v []byte, err error) { func (w *Reader) Get(k []byte) (v []byte, err error) {
@ -121,7 +104,7 @@ func (w *Reader) Close() error {
return nil return nil
} }
func (w *Writer) Get(k []byte) (v []byte, err error) { func (w *Store) Get(k []byte) (v []byte, err error) {
w.m.Lock() w.m.Lock()
t := w.t t := w.t
w.m.Unlock() w.m.Unlock()
@ -133,41 +116,33 @@ func (w *Writer) Get(k []byte) (v []byte, err error) {
return nil, nil return nil, nil
} }
func (w *Writer) Iterator(k []byte) store.KVIterator { func (w *Store) Iterator(k []byte) store.KVIterator {
w.m.Lock() w.m.Lock()
t := w.t t := w.t
w.m.Unlock() w.m.Unlock()
return newIterator(t).restart(&Item{k: k}) return newIterator(t).restart(&Item{k: k})
} }
func (w *Writer) Close() error { func (w *Store) Set(k, v []byte) (err error) {
w.m.Lock() w.m.Lock()
w.t = nil w.t = w.t.Upsert(&Item{k: k, v: v}, rand.Int())
w.m.Unlock() w.m.Unlock()
return nil return nil
} }
func (w *Writer) Set(k, v []byte) (err error) { func (w *Store) Delete(k []byte) (err error) {
w.s.m.Lock()
w.s.t = w.s.t.Upsert(&Item{k: k, v: v}, rand.Int())
t := w.s.t
w.s.m.Unlock()
w.m.Lock()
w.t = t
w.m.Unlock()
return nil
}
func (w *Writer) Delete(k []byte) (err error) {
w.m.Lock() w.m.Lock()
w.t = w.t.Delete(&Item{k: k}) w.t = w.t.Delete(&Item{k: k})
w.m.Unlock() w.m.Unlock()
return nil return nil
} }
func (w *Writer) NewBatch() store.KVBatch { func (w *Store) NewBatch() store.KVBatch {
return &Batch{w: w, ms: map[string]store.AssociativeMergeChain{}} return &Batch{
s: w,
items: make([]*Item, 0, 100),
ms: map[string]store.AssociativeMergeChain{},
}
} }
func (w *Iterator) SeekFirst() { func (w *Iterator) SeekFirst() {
@ -268,44 +243,26 @@ func (w *Iterator) Close() error {
} }
func (w *Batch) Set(k, v []byte) { func (w *Batch) Set(k, v []byte) {
w.m.Lock() w.items = append(w.items, &Item{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.items = append(w.items, &Item{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()
done := false done := false
for !done { for !done {
w.w.s.m.Lock() w.s.m.Lock()
torig := w.w.s.t torig := w.s.t
w.w.s.m.Unlock() w.s.m.Unlock()
t := torig t := torig
for key, mc := range ms { for key, mc := range w.ms {
k := []byte(key) k := []byte(key)
itm := t.Get(&Item{k: k}) itm := t.Get(&Item{k: k})
v := []byte(nil) v := []byte(nil)
@ -323,31 +280,26 @@ func (w *Batch) Execute() (err error) {
} }
} }
for i, k := range ks { for _, item := range w.items {
v := vs[i] v := item.v
if v != nil { if v != nil {
t = t.Upsert(&Item{k: k, v: v}, rand.Int()) t = t.Upsert(item, rand.Int())
} else { } else {
t = t.Delete(&Item{k: k}) t = t.Delete(item)
} }
} }
w.w.s.m.Lock() w.s.m.Lock()
if w.w.s.t == torig { if w.s.t == torig {
w.w.s.t = t w.s.t = t
done = true done = true
} }
w.w.s.m.Unlock() w.s.m.Unlock()
} }
return nil return nil
} }
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
} }