github.com/benz9527/toy-box/algo@v0.0.0-20240221120937-66c0c6bd5abd/list/singly_linkedlist_ginkgo.go (about)

     1  package list
     2  
     3  import (
     4  	"sync"
     5  	"sync/atomic"
     6  )
     7  
     8  var (
     9  	_ BasicLinkedList[struct{}] = (*singlyLinkedList[struct{}])(nil)           // Type check assertion
    10  	_ BasicLinkedList[struct{}] = (*concurrentSinglyLinkedList[struct{}])(nil) // Type check assertion
    11  )
    12  
    13  type singlyLinkedList[T comparable] struct {
    14  	// sentinel list element.
    15  	root nodeElement[T]
    16  	len  atomic.Int64
    17  }
    18  
    19  func newSinglyLinkedList[T comparable](concurrent bool) BasicLinkedList[T] {
    20  	l := new(singlyLinkedList[T]).init()
    21  	if concurrent {
    22  		l.root.lock = &sync.RWMutex{}
    23  	}
    24  	return l
    25  }
    26  
    27  func NewSinglyLinkedList[T comparable]() BasicLinkedList[T] {
    28  	return newSinglyLinkedList[T](false)
    29  }
    30  
    31  func (l *singlyLinkedList[T]) getRoot() NodeElement[T] {
    32  	return &l.root
    33  }
    34  
    35  func (l *singlyLinkedList[T]) getRootHead() NodeElement[T] {
    36  	return l.root.next
    37  }
    38  
    39  func (l *singlyLinkedList[T]) setRootHead(targetE NodeElement[T]) {
    40  	l.root.next = targetE
    41  }
    42  
    43  func (l *singlyLinkedList[T]) getRootTail() NodeElement[T] {
    44  	return l.root.prev
    45  }
    46  
    47  func (l *singlyLinkedList[T]) setRootTail(targetE NodeElement[T]) {
    48  	l.root.prev = targetE
    49  }
    50  
    51  func (l *singlyLinkedList[T]) init() *singlyLinkedList[T] {
    52  	l.setRootHead(&l.root)
    53  	l.setRootTail(&l.root)
    54  	l.root.list = l
    55  	l.len.Store(0)
    56  	return l
    57  }
    58  
    59  func (l *singlyLinkedList[T]) Len() int64 {
    60  	return l.len.Load()
    61  }
    62  
    63  func (l *singlyLinkedList[T]) isListElement(targetE NodeElement[T]) bool {
    64  	if targetE == nil {
    65  		return false
    66  	}
    67  	target, ok := targetE.(*nodeElement[T])
    68  	res := ok && target.hasLock() == l.root.hasLock()
    69  	if res && target.list != nil {
    70  		res = target.list == l
    71  	}
    72  	return res
    73  }
    74  
    75  func (l *singlyLinkedList[T]) append(e NodeElement[T]) NodeElement[T] {
    76  	if !l.isListElement(e) {
    77  		return nil
    78  	}
    79  	if e.(*nodeElement[T]).list == nil {
    80  		e.(*nodeElement[T]).list = l
    81  	}
    82  	if l.len.Load() <= 0 {
    83  		l.setRootHead(e)
    84  	} else {
    85  		l.getRootTail().(*nodeElement[T]).next = e
    86  	}
    87  	l.setRootTail(e)
    88  	l.len.Add(1)
    89  	return e
    90  }
    91  
    92  func (l *singlyLinkedList[T]) Append(elements ...NodeElement[T]) []NodeElement[T] {
    93  	for i := 0; i < len(elements); i++ {
    94  		if elements[i] == nil {
    95  			continue
    96  		}
    97  		e, ok := elements[i].(*nodeElement[T])
    98  		if !ok {
    99  			continue
   100  		}
   101  		elements[i] = l.append(e)
   102  	}
   103  	return elements
   104  }
   105  
   106  func (l *singlyLinkedList[T]) AppendValue(values ...T) []NodeElement[T] {
   107  	newElements := make([]NodeElement[T], 0, len(values))
   108  	for _, v := range values {
   109  		newElements = append(newElements, newNodeElement(v, l))
   110  	}
   111  	return l.Append(newElements...)
   112  }
   113  
   114  func (l *singlyLinkedList[T]) InsertAfter(v T, dstE NodeElement[T]) NodeElement[T] {
   115  	if !l.isListElement(dstE) {
   116  		return nil
   117  	}
   118  
   119  	newE := newNodeElement[T](v, l)
   120  	if dstE == l.getRoot() || dstE == l.getRootTail() {
   121  		l.setRootTail(newE)
   122  	}
   123  
   124  	newE.next, dstE.(*nodeElement[T]).next = dstE.(*nodeElement[T]).next, newE
   125  	l.len.Add(1)
   126  	return newE
   127  }
   128  
   129  func (l *singlyLinkedList[T]) InsertBefore(v T, dstE NodeElement[T]) NodeElement[T] {
   130  	if !l.isListElement(dstE) {
   131  		return nil
   132  	}
   133  
   134  	newE := newNodeElement[T](v, l)
   135  	var iterator NodeElement[T] = nil
   136  	if dstE == l.getRootHead() {
   137  		l.setRootHead(newE)
   138  	} else {
   139  		iterator = l.getRoot()
   140  		for iterator.HasNext() && iterator.GetNext() != dstE {
   141  			iterator = iterator.GetNext()
   142  		}
   143  		// not found
   144  		if iterator == nil {
   145  			return nil
   146  		}
   147  		iterator.(*nodeElement[T]).next = newE
   148  	}
   149  	newE.next = dstE
   150  	l.len.Add(1)
   151  	return newE
   152  }
   153  
   154  func (l *singlyLinkedList[T]) Remove(targetE NodeElement[T]) NodeElement[T] {
   155  	if !l.isListElement(targetE) || targetE.(*nodeElement[T]).list == nil || l.len.Load() == 0 {
   156  		return nil
   157  	}
   158  
   159  	defer func() {
   160  		if l.len.Load() == 0 {
   161  			l.setRootHead(l.getRoot())
   162  			l.setRootTail(l.getRoot())
   163  		}
   164  	}()
   165  
   166  	var iterator = l.getRoot()
   167  	// find previous element of targetE
   168  	for iterator.HasNext() && iterator.GetNext() != targetE {
   169  		iterator = iterator.GetNext()
   170  	}
   171  	// not found
   172  	if iterator == nil {
   173  		return nil
   174  	}
   175  	iterator.(*nodeElement[T]).next = targetE.GetNext()
   176  	if targetE == l.getRootTail() {
   177  		l.setRootTail(iterator)
   178  	}
   179  	l.len.Add(-1)
   180  	return targetE
   181  }
   182  
   183  func (l *singlyLinkedList[T]) ForEach(fn func(idx int64, e NodeElement[T])) {
   184  	if fn == nil || l.len.Load() == 0 || l.getRootHead() == l.getRoot() {
   185  		return
   186  	}
   187  	var (
   188  		iterator       = l.getRoot()
   189  		idx      int64 = 0
   190  	)
   191  	for iterator.HasNext() {
   192  		fn(idx, iterator.GetNext())
   193  		iterator, idx = iterator.GetNext(), idx+1
   194  	}
   195  }
   196  
   197  func (l *singlyLinkedList[T]) FindFirst(targetV T, compareFn ...func(e NodeElement[T]) bool) (NodeElement[T], bool) {
   198  	if l.len.Load() == 0 || l.getRootHead() == l.getRoot() {
   199  		return nil, false
   200  	}
   201  
   202  	if len(compareFn) <= 0 {
   203  		compareFn = []func(e NodeElement[T]) bool{
   204  			func(e NodeElement[T]) bool {
   205  				return e.GetValue() == targetV
   206  			},
   207  		}
   208  	}
   209  
   210  	var iterator = l.getRoot()
   211  	for iterator.HasNext() {
   212  		if compareFn[0](iterator.GetNext()) {
   213  			return iterator.GetNext(), true
   214  		}
   215  		iterator = iterator.GetNext()
   216  	}
   217  	return nil, false
   218  }
   219  
   220  type concurrentSinglyLinkedList[T comparable] struct {
   221  	lock sync.RWMutex
   222  	list BasicLinkedList[T]
   223  }
   224  
   225  func NewConcurrentSinglyLinkedList[T comparable]() BasicLinkedList[T] {
   226  	slist := &concurrentSinglyLinkedList[T]{
   227  		lock: sync.RWMutex{},
   228  		list: newSinglyLinkedList[T](true),
   229  	}
   230  	return slist
   231  }
   232  
   233  func (l *concurrentSinglyLinkedList[T]) Len() int64 {
   234  	l.lock.RLock()
   235  	defer l.lock.RUnlock()
   236  	return l.list.Len()
   237  }
   238  
   239  func (l *concurrentSinglyLinkedList[T]) Append(elements ...NodeElement[T]) []NodeElement[T] {
   240  	l.lock.Lock()
   241  	defer l.lock.Unlock()
   242  	elements = l.list.Append(elements...)
   243  	return elements
   244  }
   245  
   246  func (l *concurrentSinglyLinkedList[T]) AppendValue(values ...T) []NodeElement[T] {
   247  	elements := make([]NodeElement[T], 0, len(values))
   248  	for _, v := range values {
   249  		elements = append(elements, newConcurrentNodeElement[T](v, l.list))
   250  	}
   251  	elements = l.Append(elements...)
   252  	return elements
   253  }
   254  
   255  func (l *concurrentSinglyLinkedList[T]) InsertAfter(v T, dstE NodeElement[T]) NodeElement[T] {
   256  	l.lock.Lock()
   257  	defer l.lock.Unlock()
   258  	dstE = l.list.InsertAfter(v, dstE)
   259  	return dstE
   260  }
   261  
   262  func (l *concurrentSinglyLinkedList[T]) InsertBefore(v T, dstE NodeElement[T]) NodeElement[T] {
   263  	l.lock.Lock()
   264  	defer l.lock.Unlock()
   265  	dstE = l.list.InsertBefore(v, dstE)
   266  	return dstE
   267  }
   268  
   269  func (l *concurrentSinglyLinkedList[T]) Remove(targetE NodeElement[T]) NodeElement[T] {
   270  	l.lock.Lock()
   271  	defer l.lock.Unlock()
   272  	targetE = l.list.Remove(targetE)
   273  	return targetE
   274  }
   275  
   276  func (l *concurrentSinglyLinkedList[T]) ForEach(fn func(idx int64, e NodeElement[T])) {
   277  	l.lock.RLock()
   278  	defer l.lock.RUnlock()
   279  	l.list.ForEach(fn)
   280  }
   281  
   282  func (l *concurrentSinglyLinkedList[T]) FindFirst(v T, compareFn ...func(e NodeElement[T]) bool) (NodeElement[T], bool) {
   283  	l.lock.RLock()
   284  	defer l.lock.RUnlock()
   285  	e, ok := l.list.FindFirst(v, compareFn...)
   286  	return e, ok
   287  }