github.com/matrixorigin/matrixone@v1.2.0/pkg/vm/engine/tae/catalog/node.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 "fmt" 19 "sync" 20 21 "github.com/matrixorigin/matrixone/pkg/common/moerr" 22 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/common" 23 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/iface/txnif" 24 ) 25 26 type nodeList[T any] struct { 27 common.SSLLNode 28 getter func(uint64) *common.GenericDLNode[T] 29 visibilityFn func(*common.GenericDLNode[T], txnif.TxnReader) (bool, bool, string) 30 rwlocker *sync.RWMutex 31 name string 32 } 33 34 func newNodeList[T any](getter func(uint64) *common.GenericDLNode[T], 35 visibilityFn func(*common.GenericDLNode[T], txnif.TxnReader) (bool, bool, string), 36 rwlocker *sync.RWMutex, 37 name string) *nodeList[T] { 38 return &nodeList[T]{ 39 SSLLNode: *common.NewSSLLNode(), 40 getter: getter, 41 visibilityFn: visibilityFn, 42 rwlocker: rwlocker, 43 name: name, 44 } 45 } 46 47 func (n *nodeList[T]) CreateNode(id uint64) *nameNode[T] { 48 nn := newNameNode(id, n.getter) 49 n.rwlocker.Lock() 50 defer n.rwlocker.Unlock() 51 n.Insert(nn) 52 return nn 53 } 54 55 func (n *nodeList[T]) DeleteNode(id uint64) (deleted *nameNode[T], empty bool) { 56 n.rwlocker.Lock() 57 defer n.rwlocker.Unlock() 58 var prev common.ISSLLNode 59 prev = n 60 curr := n.GetNext() 61 depth := 0 62 for curr != nil { 63 nid := curr.(*nameNode[T]).id 64 if id == nid { 65 prev.ReleaseNextNode() 66 deleted = curr.(*nameNode[T]) 67 next := curr.GetNext() 68 if next == nil && depth == 0 { 69 empty = true 70 } 71 break 72 } 73 prev = curr 74 curr = curr.GetNext() 75 depth++ 76 } 77 return 78 } 79 80 func (n *nodeList[T]) ForEachNodes(fn func(*nameNode[T]) bool) { 81 n.rwlocker.RLock() 82 defer n.rwlocker.RUnlock() 83 n.ForEachNodesLocked(fn) 84 } 85 86 func (n *nodeList[T]) ForEachNodesLocked(fn func(*nameNode[T]) bool) { 87 curr := n.GetNext() 88 for curr != nil { 89 nn := curr.(*nameNode[T]) 90 if ok := fn(nn); !ok { 91 break 92 } 93 curr = curr.GetNext() 94 } 95 } 96 97 func (n *nodeList[T]) LengthLocked() int { 98 length := 0 99 fn := func(*nameNode[T]) bool { 100 length++ 101 return true 102 } 103 n.ForEachNodesLocked(fn) 104 return length 105 } 106 107 func (n *nodeList[T]) Length() int { 108 n.rwlocker.RLock() 109 defer n.rwlocker.RUnlock() 110 return n.LengthLocked() 111 } 112 113 func (n *nodeList[T]) GetNode() *common.GenericDLNode[T] { 114 n.rwlocker.RLock() 115 defer n.rwlocker.RUnlock() 116 return n.GetNext().(*nameNode[T]).GetNode() 117 } 118 119 // Create Deleted 120 // | | 121 // 122 // --+------+-+------------+--+------+-+--+-------+--+-----> 123 // 124 // | | | | | | | | | | 125 // | +-|------Txn2--|--+ | | +--Txn5-|--+ 126 // +--Txn1--+ +----Txn3-|-+ | 127 // +----Txn4----+ 128 // 129 // 1. Txn1 start and create a table "tb1" 130 // 2. Txn2 start and cannot find "tb1". 131 // 3. Txn1 commit 132 // 4. Txn3 start and drop table "tb1" 133 // 6. Txn4 start and can find "tb1" 134 // 7. Txn3 commit 135 // 8. Txn4 can still find "tb1" 136 // 9. Txn5 start and cannot find "tb1" 137 func (n *nodeList[T]) TxnGetNodeLocked(txn txnif.TxnReader, targetName string) ( 138 tn *common.GenericDLNode[T], err error) { 139 fn := func(nn *nameNode[T]) bool { 140 dlNode := nn.GetNode() 141 visible, dropped, visibleName := n.visibilityFn(dlNode, txn) 142 if !visible { 143 // the txn is ancient, it is needed to check older history 144 return true 145 } 146 if dropped { 147 return true 148 } 149 if targetName != visibleName { 150 return true 151 } 152 tn = dlNode 153 return false 154 } 155 n.ForEachNodes(fn) 156 if tn == nil && err == nil { 157 err = moerr.GetOkExpectedEOB() 158 } 159 return 160 } 161 162 func (n *nodeList[T]) PString(level common.PPLevel) string { 163 curr := n.GetNext() 164 if curr == nil { 165 return fmt.Sprintf("TableNode[\"%s\"](Len=0)", n.name) 166 } 167 node := curr.(*nameNode[T]) 168 s := fmt.Sprintf("TableNode[\"%s\"](Len=%d)->[%d", n.name, n.Length(), node.id) 169 if level == common.PPL0 { 170 s = fmt.Sprintf("%s]", s) 171 return s 172 } 173 174 curr = curr.GetNext() 175 for curr != nil { 176 node := curr.(*nameNode[T]) 177 s = fmt.Sprintf("%s->%d", s, node.id) 178 curr = curr.GetNext() 179 } 180 s = fmt.Sprintf("%s]", s) 181 return s 182 } 183 184 type nameNode[T any] struct { 185 common.SSLLNode 186 getter func(uint64) *common.GenericDLNode[T] 187 id uint64 188 } 189 190 func newNameNode[T any](id uint64, 191 getter func(uint64) *common.GenericDLNode[T]) *nameNode[T] { 192 return &nameNode[T]{ 193 SSLLNode: *common.NewSSLLNode(), 194 getter: getter, 195 id: id, 196 } 197 } 198 199 func (n *nameNode[T]) GetNode() *common.GenericDLNode[T] { 200 if n == nil { 201 return nil 202 } 203 return n.getter(n.id) 204 }