github.com/matrixorigin/matrixone@v1.2.0/pkg/vm/engine/tae/common/linklist.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 common 16 17 import "sync" 18 19 type ISLLNode interface { 20 IRef 21 } 22 23 type ISSLLNode interface { 24 Insert(ISSLLNode) 25 GetNext() ISSLLNode 26 SetNext(ISSLLNode) 27 ReleaseNextNode() ISSLLNode 28 ReleaseFollowing() ISSLLNode 29 } 30 31 type SSLLNode struct { 32 next ISSLLNode 33 } 34 35 func NewSSLLNode() *SSLLNode { 36 return new(SSLLNode) 37 } 38 39 func (n *SSLLNode) Insert(nn ISSLLNode) { 40 next := n.next 41 n.next = nn 42 nn.SetNext(next) 43 } 44 45 func (n *SSLLNode) SetNext(next ISSLLNode) { 46 n.next = next 47 } 48 49 func (n *SSLLNode) GetNext() ISSLLNode { 50 return n.next 51 } 52 53 func (n *SSLLNode) ReleaseNextNode() ISSLLNode { 54 if n.next != nil { 55 next := n.next.GetNext() 56 r := n.next 57 n.next = next 58 return r 59 } 60 return nil 61 } 62 63 func (n *SSLLNode) ReleaseFollowing() ISSLLNode { 64 if n.next != nil { 65 next := n.next 66 n.next = nil 67 return next 68 } 69 return nil 70 } 71 72 // SLLNode represent a single node in linked list. 73 // It is thread-safe. 74 type SLLNode struct { 75 RefHelper 76 *sync.RWMutex 77 Next ISLLNode 78 } 79 80 func NewSLLNode(mu *sync.RWMutex) *SLLNode { 81 mtx := mu 82 if mtx == nil { 83 mtx = &sync.RWMutex{} 84 } 85 return &SLLNode{ 86 RWMutex: mtx, 87 } 88 } 89 90 func (l *SLLNode) SetNextNode(next ISLLNode) { 91 l.Lock() 92 defer l.Unlock() 93 l.SetNextNodeNoLock(next) 94 } 95 96 func (l *SLLNode) SetNextNodeNoLock(next ISLLNode) { 97 if l.Next != nil { 98 l.Next.Unref() 99 } 100 l.Next = next 101 } 102 103 func (l *SLLNode) Insert(n ISLLNode) { 104 l.Lock() 105 defer l.Unlock() 106 next := l.Next 107 l.Next = n 108 n.(*SLLNode).Next = next 109 } 110 111 func (l *SLLNode) GetNextNode() ISLLNode { 112 var r ISLLNode 113 l.RLock() 114 if l.Next != nil { 115 l.Next.Ref() 116 r = l.Next 117 } 118 l.RUnlock() 119 return r 120 } 121 122 func (l *SLLNode) ReleaseNextNode() { 123 l.Lock() 124 defer l.Unlock() 125 if l.Next != nil { 126 l.Next.Unref() 127 l.Next = nil 128 } 129 }