github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/tidb/kv/buffer_store.go (about) 1 // Copyright 2015 PingCAP, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package kv 15 16 import ( 17 "github.com/insionng/yougam/libraries/juju/errors" 18 ) 19 20 // BufferStore wraps a Retriever for read and a MemBuffer for buffered write. 21 // Common usage pattern: 22 // bs := NewBufferStore(r) // use BufferStore to wrap a Retriever 23 // defer bs.Release() // make sure it will be released 24 // // ... 25 // // read/write on bs 26 // // ... 27 // bs.SaveTo(m) // save above operations to a Mutator 28 type BufferStore struct { 29 MemBuffer 30 r Retriever 31 } 32 33 // NewBufferStore creates a BufferStore using r for read. 34 func NewBufferStore(r Retriever) *BufferStore { 35 return &BufferStore{ 36 r: r, 37 MemBuffer: &lazyMemBuffer{}, 38 } 39 } 40 41 // Get implements the Retriever interface. 42 func (s *BufferStore) Get(k Key) ([]byte, error) { 43 val, err := s.MemBuffer.Get(k) 44 if IsErrNotFound(err) { 45 val, err = s.r.Get(k) 46 } 47 if err != nil { 48 return nil, errors.Trace(err) 49 } 50 if len(val) == 0 { 51 return nil, errors.Trace(ErrNotExist) 52 } 53 return val, nil 54 } 55 56 // Seek implements the Retriever interface. 57 func (s *BufferStore) Seek(k Key) (Iterator, error) { 58 bufferIt, err := s.MemBuffer.Seek(k) 59 if err != nil { 60 return nil, errors.Trace(err) 61 } 62 retrieverIt, err := s.r.Seek(k) 63 if err != nil { 64 return nil, errors.Trace(err) 65 } 66 return newUnionIter(bufferIt, retrieverIt, false), nil 67 } 68 69 // SeekReverse implements the Retriever interface. 70 func (s *BufferStore) SeekReverse(k Key) (Iterator, error) { 71 buferIt, err := s.MemBuffer.SeekReverse(k) 72 if err != nil { 73 return nil, errors.Trace(err) 74 } 75 retrieverIt, err := s.r.SeekReverse(k) 76 if err != nil { 77 return nil, errors.Trace(err) 78 } 79 return newUnionIter(buferIt, retrieverIt, true), nil 80 } 81 82 // WalkBuffer iterates all buffered kv pairs. 83 func (s *BufferStore) WalkBuffer(f func(k Key, v []byte) error) error { 84 iter, err := s.MemBuffer.Seek(nil) 85 if err != nil { 86 return errors.Trace(err) 87 } 88 defer iter.Close() 89 for ; iter.Valid(); iter.Next() { 90 if err := f(iter.Key(), iter.Value()); err != nil { 91 return errors.Trace(err) 92 } 93 } 94 return nil 95 } 96 97 // SaveTo saves all buffered kv pairs into a Mutator. 98 func (s *BufferStore) SaveTo(m Mutator) error { 99 err := s.WalkBuffer(func(k Key, v []byte) error { 100 if len(v) == 0 { 101 return errors.Trace(m.Delete(k)) 102 } 103 return errors.Trace(m.Set(k, v)) 104 }) 105 return errors.Trace(err) 106 }