github.com/matrixorigin/matrixone@v0.7.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/container/types" 23 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/common" 24 ) 25 26 type nodeList[T any] struct { 27 common.SSLLNode 28 getter func(uint64) *common.GenericDLNode[T] 29 visibilityFn func(*common.GenericDLNode[T], types.TS) (bool, bool) 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], types.TS) (bool, bool), 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(ts types.TS) ( 138 dn *common.GenericDLNode[T], err error) { 139 fn := func(nn *nameNode[T]) bool { 140 dlNode := nn.GetNode() 141 visible, dropped := n.visibilityFn(dlNode, ts) 142 if !visible { 143 return true 144 } 145 if dropped { 146 return false 147 } 148 dn = dlNode 149 return true 150 } 151 n.ForEachNodes(fn) 152 if dn == nil && err == nil { 153 err = moerr.GetOkExpectedEOB() 154 } 155 return 156 } 157 158 func (n *nodeList[T]) PString(level common.PPLevel) string { 159 curr := n.GetNext() 160 if curr == nil { 161 return fmt.Sprintf("TableNode[\"%s\"](Len=0)", n.name) 162 } 163 node := curr.(*nameNode[T]) 164 s := fmt.Sprintf("TableNode[\"%s\"](Len=%d)->[%d", n.name, n.Length(), node.id) 165 if level == common.PPL0 { 166 s = fmt.Sprintf("%s]", s) 167 return s 168 } 169 170 curr = curr.GetNext() 171 for curr != nil { 172 node := curr.(*nameNode[T]) 173 s = fmt.Sprintf("%s->%d", s, node.id) 174 curr = curr.GetNext() 175 } 176 s = fmt.Sprintf("%s]", s) 177 return s 178 } 179 180 type nameNode[T any] struct { 181 common.SSLLNode 182 getter func(uint64) *common.GenericDLNode[T] 183 id uint64 184 } 185 186 func newNameNode[T any](id uint64, 187 getter func(uint64) *common.GenericDLNode[T]) *nameNode[T] { 188 return &nameNode[T]{ 189 SSLLNode: *common.NewSSLLNode(), 190 getter: getter, 191 id: id, 192 } 193 } 194 195 func (n *nameNode[T]) GetNode() *common.GenericDLNode[T] { 196 if n == nil { 197 return nil 198 } 199 return n.getter(n.id) 200 }