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  }