github.com/matrixorigin/matrixone@v0.7.0/pkg/vm/engine/tae/catalog/dbbase.go (about) 1 // Copyright 2021 Matrix Origin 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 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package catalog 16 17 import ( 18 "encoding/binary" 19 "fmt" 20 "io" 21 "sync" 22 23 "github.com/matrixorigin/matrixone/pkg/common/moerr" 24 "github.com/matrixorigin/matrixone/pkg/container/types" 25 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/common" 26 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/iface/txnif" 27 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/txn/txnbase" 28 ) 29 30 type DBBaseEntry struct { 31 *txnbase.MVCCChain 32 ID uint64 33 } 34 35 func NewReplayDBBaseEntry() *DBBaseEntry { 36 be := &DBBaseEntry{ 37 MVCCChain: txnbase.NewMVCCChain(CompareDBBaseNode, NewEmptyDBMVCCNode), 38 } 39 return be 40 } 41 42 func NewDBBaseEntry(id uint64) *DBBaseEntry { 43 return &DBBaseEntry{ 44 ID: id, 45 MVCCChain: txnbase.NewMVCCChain(CompareDBBaseNode, NewEmptyDBMVCCNode), 46 } 47 } 48 49 func (be *DBBaseEntry) StringLocked() string { 50 return fmt.Sprintf("[%d]%s", be.ID, be.MVCCChain.StringLocked()) 51 } 52 53 func (be *DBBaseEntry) String() string { 54 be.RLock() 55 defer be.RUnlock() 56 return be.StringLocked() 57 } 58 59 func (be *DBBaseEntry) PPString(level common.PPLevel, depth int, prefix string) string { 60 s := fmt.Sprintf("%s%s%s", common.RepeatStr("\t", depth), prefix, be.StringLocked()) 61 return s 62 } 63 64 func (be *DBBaseEntry) TryGetTerminatedTS(waitIfcommitting bool) (terminated bool, TS types.TS) { 65 node := be.GetLatestCommittedNode() 66 if node == nil { 67 return 68 } 69 if node.(*DBMVCCNode).HasDropCommitted() { 70 return true, node.(*DBMVCCNode).DeletedAt 71 } 72 return 73 } 74 func (be *DBBaseEntry) GetID() uint64 { return be.ID } 75 76 func (be *DBBaseEntry) CreateWithTS(ts types.TS) { 77 node := &DBMVCCNode{ 78 EntryMVCCNode: &EntryMVCCNode{ 79 CreatedAt: ts, 80 }, 81 TxnMVCCNode: txnbase.NewTxnMVCCNodeWithTS(ts), 82 } 83 be.Insert(node) 84 } 85 86 func (be *DBBaseEntry) CreateWithTxn(txn txnif.AsyncTxn) { 87 node := &DBMVCCNode{ 88 EntryMVCCNode: &EntryMVCCNode{ 89 CreatedAt: txnif.UncommitTS, 90 }, 91 TxnMVCCNode: txnbase.NewTxnMVCCNodeWithTxn(txn), 92 } 93 be.Insert(node) 94 } 95 96 func (be *DBBaseEntry) getOrSetUpdateNode(txn txnif.TxnReader) (newNode bool, node *DBMVCCNode) { 97 entry := be.GetLatestNodeLocked() 98 if entry.IsSameTxn(txn.GetStartTS()) { 99 return false, entry.(*DBMVCCNode) 100 } else { 101 node := entry.CloneData().(*DBMVCCNode) 102 node.TxnMVCCNode = txnbase.NewTxnMVCCNodeWithTxn(txn) 103 be.Insert(node) 104 return true, node 105 } 106 } 107 108 func (be *DBBaseEntry) DeleteLocked(txn txnif.TxnReader) (isNewNode bool, err error) { 109 var node *DBMVCCNode 110 isNewNode, node = be.getOrSetUpdateNode(txn) 111 node.Delete() 112 return 113 } 114 115 func (be *DBBaseEntry) DeleteBefore(ts types.TS) bool { 116 createAt := be.GetDeleteAt() 117 if createAt.IsEmpty() { 118 return false 119 } 120 return createAt.Less(ts) 121 } 122 123 func (be *DBBaseEntry) NeedWaitCommitting(startTS types.TS) (bool, txnif.TxnReader) { 124 un := be.GetLatestNodeLocked() 125 if un == nil { 126 return false, nil 127 } 128 return un.NeedWaitCommitting(startTS) 129 } 130 131 func (be *DBBaseEntry) HasDropCommitted() bool { 132 be.RLock() 133 defer be.RUnlock() 134 return be.HasDropCommittedLocked() 135 } 136 137 func (be *DBBaseEntry) HasDropCommittedLocked() bool { 138 un := be.GetLatestCommittedNode() 139 if un == nil { 140 return false 141 } 142 return un.(*DBMVCCNode).HasDropCommitted() 143 } 144 145 func (be *DBBaseEntry) DoCompre(voe BaseEntry) int { 146 oe := voe.(*DBBaseEntry) 147 be.RLock() 148 defer be.RUnlock() 149 oe.RLock() 150 defer oe.RUnlock() 151 return CompareUint64(be.ID, oe.ID) 152 } 153 154 func (be *DBBaseEntry) ensureVisibleAndNotDropped(ts types.TS) bool { 155 visible, dropped := be.GetVisibilityLocked(ts) 156 if !visible { 157 return false 158 } 159 return !dropped 160 } 161 162 func (be *DBBaseEntry) GetVisibilityLocked(ts types.TS) (visible, dropped bool) { 163 un := be.GetVisibleNode(ts) 164 if un == nil { 165 return 166 } 167 visible = true 168 if un.IsSameTxn(ts) { 169 dropped = un.(*DBMVCCNode).HasDropIntent() 170 } else { 171 dropped = un.(*DBMVCCNode).HasDropCommitted() 172 } 173 return 174 } 175 176 func (be *DBBaseEntry) IsVisible(ts types.TS, mu *sync.RWMutex) (ok bool, err error) { 177 needWait, txnToWait := be.NeedWaitCommitting(ts) 178 if needWait { 179 mu.RUnlock() 180 txnToWait.GetTxnState(true) 181 mu.RLock() 182 } 183 ok = be.ensureVisibleAndNotDropped(ts) 184 return 185 } 186 187 func (be *DBBaseEntry) DropEntryLocked(txn txnif.TxnReader) (isNewNode bool, err error) { 188 err = be.CheckConflict(txn) 189 if err != nil { 190 return 191 } 192 if be.HasDropCommittedLocked() { 193 return false, moerr.GetOkExpectedEOB() 194 } 195 isNewNode, err = be.DeleteLocked(txn) 196 return 197 } 198 199 func (be *DBBaseEntry) PrepareAdd(txn txnif.TxnReader) (err error) { 200 be.RLock() 201 defer be.RUnlock() 202 if txn != nil { 203 needWait, waitTxn := be.NeedWaitCommitting(txn.GetStartTS()) 204 if needWait { 205 be.RUnlock() 206 waitTxn.GetTxnState(true) 207 be.RLock() 208 } 209 err = be.CheckConflict(txn) 210 if err != nil { 211 return 212 } 213 } 214 if txn == nil || be.GetTxn() != txn { 215 if !be.HasDropCommittedLocked() { 216 return moerr.GetOkExpectedDup() 217 } 218 } else { 219 if be.ensureVisibleAndNotDropped(txn.GetStartTS()) { 220 return moerr.GetOkExpectedDup() 221 } 222 } 223 return 224 } 225 226 func (be *DBBaseEntry) DeleteAfter(ts types.TS) bool { 227 un := be.GetLatestNodeLocked() 228 if un == nil { 229 return false 230 } 231 return un.(*DBMVCCNode).DeletedAt.Greater(ts) 232 } 233 234 func (be *DBBaseEntry) CloneCommittedInRange(start, end types.TS) BaseEntry { 235 chain := be.MVCCChain.CloneCommittedInRange(start, end) 236 if chain == nil { 237 return nil 238 } 239 return &DBBaseEntry{ 240 MVCCChain: chain, 241 ID: be.ID, 242 } 243 } 244 245 func (be *DBBaseEntry) GetCreatedAt() types.TS { 246 un := be.GetLatestNodeLocked() 247 if un == nil { 248 return types.TS{} 249 } 250 return un.(*DBMVCCNode).CreatedAt 251 } 252 253 func (be *DBBaseEntry) GetDeleteAt() types.TS { 254 un := be.GetLatestNodeLocked() 255 if un == nil { 256 return types.TS{} 257 } 258 return un.(*DBMVCCNode).DeletedAt 259 } 260 261 func (be *DBBaseEntry) GetVisibility(ts types.TS) (visible, dropped bool) { 262 be.RLock() 263 defer be.RUnlock() 264 needWait, txnToWait := be.NeedWaitCommitting(ts) 265 if needWait { 266 be.RUnlock() 267 txnToWait.GetTxnState(true) 268 be.RLock() 269 } 270 return be.GetVisibilityLocked(ts) 271 } 272 func (be *DBBaseEntry) WriteOneNodeTo(w io.Writer) (n int64, err error) { 273 if err = binary.Write(w, binary.BigEndian, be.ID); err != nil { 274 return 275 } 276 n += 8 277 var sn int64 278 sn, err = be.MVCCChain.WriteOneNodeTo(w) 279 if err != nil { 280 return 281 } 282 n += sn 283 return 284 } 285 func (be *DBBaseEntry) WriteAllTo(w io.Writer) (n int64, err error) { 286 if err = binary.Write(w, binary.BigEndian, be.ID); err != nil { 287 return 288 } 289 n += 8 290 var sn int64 291 sn, err = be.MVCCChain.WriteAllTo(w) 292 if err != nil { 293 return 294 } 295 n += sn 296 return 297 } 298 func (be *DBBaseEntry) ReadOneNodeFrom(r io.Reader) (n int64, err error) { 299 if err = binary.Read(r, binary.BigEndian, &be.ID); err != nil { 300 return 301 } 302 n += 8 303 var sn int64 304 sn, err = be.MVCCChain.ReadOneNodeFrom(r) 305 if err != nil { 306 return 307 } 308 n += sn 309 return 310 } 311 func (be *DBBaseEntry) ReadAllFrom(r io.Reader) (n int64, err error) { 312 if err = binary.Read(r, binary.BigEndian, &be.ID); err != nil { 313 return 314 } 315 n += 8 316 var sn int64 317 sn, err = be.MVCCChain.ReadAllFrom(r) 318 if err != nil { 319 return 320 } 321 n += sn 322 return 323 }