github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/causetstore/ekv/union_store.go (about) 1 // Copyright 2020 WHTCORPS INC, 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 ekv 15 16 import ( 17 "context" 18 ) 19 20 // UnionStore is a causetstore that wraps a snapshot for read and a MemBuffer for buffered write. 21 // Also, it provides some transaction related utilities. 22 type UnionStore interface { 23 Retriever 24 25 // HasPresumeKeyNotExists returns whether the key presumed key not exists error for the lazy check. 26 HasPresumeKeyNotExists(k Key) bool 27 // DeleteKeyExistErrInfo deletes the key presume key not exists error flag for the lazy check. 28 UnmarkPresumeKeyNotExists(k Key) 29 // CacheIndexName caches the index name. 30 // PresumeKeyNotExists will use this to help decode error message. 31 CacheIndexName(blockID, indexID int64, name string) 32 // GetIndexName returns the cached index name. 33 // If there is no such index already inserted through CacheIndexName, it will return UNKNOWN. 34 GetIndexName(blockID, indexID int64) string 35 36 // SetOption sets an option with a value, when val is nil, uses the default 37 // value of this option. 38 SetOption(opt Option, val interface{}) 39 // DelOption deletes an option. 40 DelOption(opt Option) 41 // GetOption gets an option. 42 GetOption(opt Option) interface{} 43 // GetMemBuffer return the MemBuffer binding to this unionStore. 44 GetMemBuffer() MemBuffer 45 } 46 47 // AssertionType is the type of a assertion. 48 type AssertionType int 49 50 // The AssertionType constants. 51 const ( 52 None AssertionType = iota 53 Exist 54 NotExist 55 ) 56 57 // Option is used for customizing ekv causetstore's behaviors during a transaction. 58 type Option int 59 60 // Options is an interface of a set of options. Each option is associated with a value. 61 type Options interface { 62 // Get gets an option value. 63 Get(opt Option) (v interface{}, ok bool) 64 } 65 66 type idxNameKey struct { 67 blockID, indexID int64 68 } 69 70 // unionStore is an in-memory CausetStore which contains a buffer for write and a 71 // snapshot for read. 72 type unionStore struct { 73 memBuffer *memdb 74 snapshot Snapshot 75 idxNameCache map[idxNameKey]string 76 opts options 77 } 78 79 // NewUnionStore builds a new unionStore. 80 func NewUnionStore(snapshot Snapshot) UnionStore { 81 return &unionStore{ 82 snapshot: snapshot, 83 memBuffer: newMemDB(), 84 idxNameCache: make(map[idxNameKey]string), 85 opts: make(map[Option]interface{}), 86 } 87 } 88 89 // GetMemBuffer return the MemBuffer binding to this unionStore. 90 func (us *unionStore) GetMemBuffer() MemBuffer { 91 return us.memBuffer 92 } 93 94 // Get implements the Retriever interface. 95 func (us *unionStore) Get(ctx context.Context, k Key) ([]byte, error) { 96 v, err := us.memBuffer.Get(ctx, k) 97 if IsErrNotFound(err) { 98 v, err = us.snapshot.Get(ctx, k) 99 } 100 if err != nil { 101 return v, err 102 } 103 if len(v) == 0 { 104 return nil, ErrNotExist 105 } 106 return v, nil 107 } 108 109 // Iter implements the Retriever interface. 110 func (us *unionStore) Iter(k Key, upperBound Key) (Iterator, error) { 111 bufferIt, err := us.memBuffer.Iter(k, upperBound) 112 if err != nil { 113 return nil, err 114 } 115 retrieverIt, err := us.snapshot.Iter(k, upperBound) 116 if err != nil { 117 return nil, err 118 } 119 return NewUnionIter(bufferIt, retrieverIt, false) 120 } 121 122 // IterReverse implements the Retriever interface. 123 func (us *unionStore) IterReverse(k Key) (Iterator, error) { 124 bufferIt, err := us.memBuffer.IterReverse(k) 125 if err != nil { 126 return nil, err 127 } 128 retrieverIt, err := us.snapshot.IterReverse(k) 129 if err != nil { 130 return nil, err 131 } 132 return NewUnionIter(bufferIt, retrieverIt, true) 133 } 134 135 // HasPresumeKeyNotExists gets the key exist error info for the lazy check. 136 func (us *unionStore) HasPresumeKeyNotExists(k Key) bool { 137 flags, err := us.memBuffer.GetFlags(k) 138 if err != nil { 139 return false 140 } 141 return flags.HasPresumeKeyNotExists() 142 } 143 144 // DeleteKeyExistErrInfo deletes the key exist error info for the lazy check. 145 func (us *unionStore) UnmarkPresumeKeyNotExists(k Key) { 146 us.memBuffer.UFIDelateFlags(k, DelPresumeKeyNotExists) 147 } 148 149 func (us *unionStore) GetIndexName(blockID, indexID int64) string { 150 key := idxNameKey{blockID: blockID, indexID: indexID} 151 name, ok := us.idxNameCache[key] 152 if !ok { 153 return "UNKNOWN" 154 } 155 return name 156 } 157 158 func (us *unionStore) CacheIndexName(blockID, indexID int64, name string) { 159 key := idxNameKey{blockID: blockID, indexID: indexID} 160 us.idxNameCache[key] = name 161 } 162 163 // SetOption implements the unionStore SetOption interface. 164 func (us *unionStore) SetOption(opt Option, val interface{}) { 165 us.opts[opt] = val 166 } 167 168 // DelOption implements the unionStore DelOption interface. 169 func (us *unionStore) DelOption(opt Option) { 170 delete(us.opts, opt) 171 } 172 173 // GetOption implements the unionStore GetOption interface. 174 func (us *unionStore) GetOption(opt Option) interface{} { 175 return us.opts[opt] 176 } 177 178 type options map[Option]interface{} 179 180 func (opts options) Get(opt Option) (interface{}, bool) { 181 v, ok := opts[opt] 182 return v, ok 183 }