github.com/matrixorigin/matrixone@v0.7.0/pkg/vm/engine/tae/catalog/metabase.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 MetaBaseEntry struct { 31 //chain of MetadataMVCCNode 32 *txnbase.MVCCChain 33 ID uint64 34 } 35 36 func NewReplayMetaBaseEntry() *MetaBaseEntry { 37 be := &MetaBaseEntry{ 38 MVCCChain: txnbase.NewMVCCChain(CompareMetaBaseNode, NewEmptyMetadataMVCCNode), 39 } 40 return be 41 } 42 43 func NewMetaBaseEntry(id uint64) *MetaBaseEntry { 44 return &MetaBaseEntry{ 45 ID: id, 46 MVCCChain: txnbase.NewMVCCChain(CompareMetaBaseNode, NewEmptyMetadataMVCCNode), 47 } 48 } 49 50 func (be *MetaBaseEntry) StringLocked() string { 51 return fmt.Sprintf("[%d]%s", be.ID, be.MVCCChain.StringLocked()) 52 } 53 54 func (be *MetaBaseEntry) String() string { 55 be.RLock() 56 defer be.RUnlock() 57 return be.StringLocked() 58 } 59 60 func (be *MetaBaseEntry) PPString(level common.PPLevel, depth int, prefix string) string { 61 s := fmt.Sprintf("%s%s%s", common.RepeatStr("\t", depth), prefix, be.StringLocked()) 62 return s 63 } 64 func (be *MetaBaseEntry) HasPersistedData() bool { 65 return be.GetMetaLoc() != "" 66 } 67 func (be *MetaBaseEntry) GetMetaLoc() string { 68 be.RLock() 69 defer be.RUnlock() 70 if be.GetLatestNodeLocked() == nil { 71 return "" 72 } 73 str := be.GetLatestNodeLocked().(*MetadataMVCCNode).MetaLoc 74 return str 75 } 76 func (be *MetaBaseEntry) HasPersistedDeltaData() bool { 77 return be.GetDeltaLoc() != "" 78 } 79 func (be *MetaBaseEntry) GetDeltaLoc() string { 80 be.RLock() 81 defer be.RUnlock() 82 if be.GetLatestNodeLocked() == nil { 83 return "" 84 } 85 str := be.GetLatestNodeLocked().(*MetadataMVCCNode).DeltaLoc 86 return str 87 } 88 89 func (be *MetaBaseEntry) GetVisibleMetaLoc(ts types.TS) string { 90 be.RLock() 91 defer be.RUnlock() 92 str := be.GetVisibleNode(ts).(*MetadataMVCCNode).MetaLoc 93 return str 94 } 95 func (be *MetaBaseEntry) GetVisibleDeltaLoc(ts types.TS) string { 96 be.RLock() 97 defer be.RUnlock() 98 str := be.GetVisibleNode(ts).(*MetadataMVCCNode).DeltaLoc 99 return str 100 } 101 func (be *MetaBaseEntry) TryGetTerminatedTS(waitIfcommitting bool) (terminated bool, TS types.TS) { 102 node := be.GetLatestCommittedNode() 103 if node == nil { 104 return 105 } 106 if node.(*MetadataMVCCNode).HasDropCommitted() { 107 return true, node.(*MetadataMVCCNode).DeletedAt 108 } 109 return 110 } 111 func (be *MetaBaseEntry) GetID() uint64 { return be.ID } 112 113 func (be *MetaBaseEntry) CreateWithTS(ts types.TS) { 114 node := &MetadataMVCCNode{ 115 EntryMVCCNode: &EntryMVCCNode{ 116 CreatedAt: ts, 117 }, 118 TxnMVCCNode: txnbase.NewTxnMVCCNodeWithTS(ts), 119 } 120 be.Insert(node) 121 } 122 123 func (be *MetaBaseEntry) CreateWithLoc(ts types.TS, metaLoc string, deltaLoc string) { 124 node := &MetadataMVCCNode{ 125 EntryMVCCNode: &EntryMVCCNode{ 126 CreatedAt: ts, 127 }, 128 TxnMVCCNode: txnbase.NewTxnMVCCNodeWithTS(ts), 129 MetaLoc: metaLoc, 130 DeltaLoc: deltaLoc, 131 } 132 be.Insert(node) 133 } 134 135 func (be *MetaBaseEntry) CreateWithTxn(txn txnif.AsyncTxn) { 136 node := &MetadataMVCCNode{ 137 EntryMVCCNode: &EntryMVCCNode{ 138 CreatedAt: txnif.UncommitTS, 139 }, 140 TxnMVCCNode: txnbase.NewTxnMVCCNodeWithTxn(txn), 141 } 142 be.Insert(node) 143 } 144 145 func (be *MetaBaseEntry) CreateWithTxnAndMeta(txn txnif.AsyncTxn, metaLoc string, deltaLoc string) { 146 node := &MetadataMVCCNode{ 147 EntryMVCCNode: &EntryMVCCNode{ 148 CreatedAt: txnif.UncommitTS, 149 }, 150 TxnMVCCNode: txnbase.NewTxnMVCCNodeWithTxn(txn), 151 MetaLoc: metaLoc, 152 DeltaLoc: deltaLoc, 153 } 154 be.Insert(node) 155 } 156 157 func (be *MetaBaseEntry) getOrSetUpdateNode(txn txnif.TxnReader) (newNode bool, node *MetadataMVCCNode) { 158 entry := be.GetLatestNodeLocked() 159 if entry.IsSameTxn(txn.GetStartTS()) { 160 return false, entry.(*MetadataMVCCNode) 161 } else { 162 node := entry.CloneData().(*MetadataMVCCNode) 163 node.TxnMVCCNode = txnbase.NewTxnMVCCNodeWithTxn(txn) 164 be.Insert(node) 165 return true, node 166 } 167 } 168 169 func (be *MetaBaseEntry) DeleteLocked(txn txnif.TxnReader) (isNewNode bool, err error) { 170 var entry *MetadataMVCCNode 171 isNewNode, entry = be.getOrSetUpdateNode(txn) 172 entry.Delete() 173 return 174 } 175 176 func (be *MetaBaseEntry) UpdateMetaLoc(txn txnif.TxnReader, metaloc string) (isNewNode bool, err error) { 177 be.Lock() 178 defer be.Unlock() 179 needWait, txnToWait := be.NeedWaitCommitting(txn.GetStartTS()) 180 if needWait { 181 be.Unlock() 182 txnToWait.GetTxnState(true) 183 be.Lock() 184 } 185 err = be.CheckConflict(txn) 186 if err != nil { 187 return 188 } 189 var entry *MetadataMVCCNode 190 isNewNode, entry = be.getOrSetUpdateNode(txn) 191 entry.UpdateMetaLoc(metaloc) 192 return 193 } 194 195 func (be *MetaBaseEntry) UpdateDeltaLoc(txn txnif.TxnReader, deltaloc string) (isNewNode bool, err error) { 196 be.Lock() 197 defer be.Unlock() 198 needWait, txnToWait := be.NeedWaitCommitting(txn.GetStartTS()) 199 if needWait { 200 be.Unlock() 201 txnToWait.GetTxnState(true) 202 be.Lock() 203 } 204 err = be.CheckConflict(txn) 205 if err != nil { 206 return 207 } 208 var entry *MetadataMVCCNode 209 isNewNode, entry = be.getOrSetUpdateNode(txn) 210 entry.UpdateDeltaLoc(deltaloc) 211 return 212 } 213 214 func (be *MetaBaseEntry) DeleteBefore(ts types.TS) bool { 215 createAt := be.GetDeleteAt() 216 if createAt.IsEmpty() { 217 return false 218 } 219 return createAt.Less(ts) 220 } 221 222 func (be *MetaBaseEntry) NeedWaitCommitting(startTS types.TS) (bool, txnif.TxnReader) { 223 un := be.GetLatestNodeLocked() 224 if un == nil { 225 return false, nil 226 } 227 return un.NeedWaitCommitting(startTS) 228 } 229 230 func (be *MetaBaseEntry) HasDropCommitted() bool { 231 be.RLock() 232 defer be.RUnlock() 233 return be.HasDropCommittedLocked() 234 } 235 236 func (be *MetaBaseEntry) HasDropCommittedLocked() bool { 237 un := be.GetLatestCommittedNode() 238 if un == nil { 239 return false 240 } 241 return un.(*MetadataMVCCNode).HasDropCommitted() 242 } 243 244 func (be *MetaBaseEntry) DoCompre(voe BaseEntry) int { 245 oe := voe.(*MetaBaseEntry) 246 be.RLock() 247 defer be.RUnlock() 248 oe.RLock() 249 defer oe.RUnlock() 250 return CompareUint64(be.ID, oe.ID) 251 } 252 253 func (be *MetaBaseEntry) ensureVisibleAndNotDropped(ts types.TS) bool { 254 visible, dropped := be.GetVisibilityLocked(ts) 255 if !visible { 256 return false 257 } 258 return !dropped 259 } 260 261 func (be *MetaBaseEntry) GetVisibilityLocked(ts types.TS) (visible, dropped bool) { 262 un := be.GetVisibleNode(ts) 263 if un == nil { 264 return 265 } 266 visible = true 267 if un.IsSameTxn(ts) { 268 dropped = un.(*MetadataMVCCNode).HasDropIntent() 269 } else { 270 dropped = un.(*MetadataMVCCNode).HasDropCommitted() 271 } 272 return 273 } 274 275 func (be *MetaBaseEntry) IsVisible(ts types.TS, mu *sync.RWMutex) (ok bool, err error) { 276 needWait, txnToWait := be.NeedWaitCommitting(ts) 277 if needWait { 278 mu.RUnlock() 279 txnToWait.GetTxnState(true) 280 mu.RLock() 281 } 282 ok = be.ensureVisibleAndNotDropped(ts) 283 return 284 } 285 286 func (be *MetaBaseEntry) DropEntryLocked(txn txnif.TxnReader) (isNewNode bool, err error) { 287 err = be.CheckConflict(txn) 288 if err != nil { 289 return 290 } 291 if be.HasDropCommittedLocked() { 292 return false, moerr.GetOkExpectedEOB() 293 } 294 isNewNode, err = be.DeleteLocked(txn) 295 return 296 } 297 298 func (be *MetaBaseEntry) DeleteAfter(ts types.TS) bool { 299 un := be.GetLatestNodeLocked() 300 if un == nil { 301 return false 302 } 303 return un.(*MetadataMVCCNode).DeletedAt.Greater(ts) 304 } 305 306 func (be *MetaBaseEntry) CloneCommittedInRange(start, end types.TS) BaseEntry { 307 chain := be.MVCCChain.CloneCommittedInRange(start, end) 308 if chain == nil { 309 return nil 310 } 311 return &MetaBaseEntry{ 312 MVCCChain: chain, 313 ID: be.ID, 314 } 315 } 316 317 func (be *MetaBaseEntry) GetCreatedAt() types.TS { 318 un := be.GetLatestNodeLocked() 319 if un == nil { 320 return types.TS{} 321 } 322 return un.(*MetadataMVCCNode).CreatedAt 323 } 324 325 func (be *MetaBaseEntry) GetDeleteAt() types.TS { 326 un := be.GetLatestNodeLocked() 327 if un == nil { 328 return types.TS{} 329 } 330 return un.(*MetadataMVCCNode).DeletedAt 331 } 332 333 func (be *MetaBaseEntry) GetVisibility(ts types.TS) (visible, dropped bool) { 334 be.RLock() 335 defer be.RUnlock() 336 needWait, txnToWait := be.NeedWaitCommitting(ts) 337 if needWait { 338 be.RUnlock() 339 txnToWait.GetTxnState(true) 340 be.RLock() 341 } 342 return be.GetVisibilityLocked(ts) 343 } 344 func (be *MetaBaseEntry) WriteOneNodeTo(w io.Writer) (n int64, err error) { 345 if err = binary.Write(w, binary.BigEndian, be.ID); err != nil { 346 return 347 } 348 n += 8 349 var sn int64 350 sn, err = be.MVCCChain.WriteOneNodeTo(w) 351 if err != nil { 352 return 353 } 354 n += sn 355 return 356 } 357 func (be *MetaBaseEntry) WriteAllTo(w io.Writer) (n int64, err error) { 358 if err = binary.Write(w, binary.BigEndian, be.ID); err != nil { 359 return 360 } 361 n += 8 362 var sn int64 363 sn, err = be.MVCCChain.WriteAllTo(w) 364 if err != nil { 365 return 366 } 367 n += sn 368 return 369 } 370 func (be *MetaBaseEntry) ReadOneNodeFrom(r io.Reader) (n int64, err error) { 371 if err = binary.Read(r, binary.BigEndian, &be.ID); err != nil { 372 return 373 } 374 n += 8 375 var sn int64 376 sn, err = be.MVCCChain.ReadOneNodeFrom(r) 377 if err != nil { 378 return 379 } 380 n += sn 381 return 382 } 383 func (be *MetaBaseEntry) ReadAllFrom(r io.Reader) (n int64, err error) { 384 if err = binary.Read(r, binary.BigEndian, &be.ID); err != nil { 385 return 386 } 387 n += 8 388 var sn int64 389 sn, err = be.MVCCChain.ReadAllFrom(r) 390 if err != nil { 391 return 392 } 393 n += sn 394 return 395 }