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

     1  package list
     2  
     3  import "sync"
     4  
     5  var (
     6  	_ NodeElement[struct{}] = (*nodeElement[struct{}])(nil) // Type check assertion
     7  )
     8  
     9  // Alignment and size
    10  // interface size is 16bytes
    11  // pointer size is 8bytes
    12  // string size is 16bytes
    13  // rune size is 4bytes
    14  // int8 size is 1byte
    15  // int16 size is 2bytes
    16  // int32 size is 4bytes
    17  // int size is 8bytes
    18  // int64 size is 8bytes
    19  // bool size is 1byte
    20  // byte size is 1byte
    21  // struct{} size is 0byte
    22  
    23  type nodeElement[T comparable] struct {
    24  	prev, next NodeElement[T]     // alignment 8bytes * 2; size 16bytes * 2
    25  	list       BasicLinkedList[T] // alignment 8bytes; size 16bytes
    26  	lock       *sync.RWMutex      // alignment 8bytes; size 8bytes
    27  	value      T                  // alignment 8bytes; size up to datatype. The type of value may be a small size type.
    28  	// It should be placed at the end of the struct to avoid take too much padding.
    29  }
    30  
    31  func NewNodeElement[T comparable](v T) NodeElement[T] {
    32  	return newNodeElement[T](v, nil)
    33  }
    34  
    35  func newNodeElement[T comparable](v T, list BasicLinkedList[T]) *nodeElement[T] {
    36  	return &nodeElement[T]{
    37  		value: v,
    38  		list:  list,
    39  	}
    40  }
    41  
    42  func NewConcurrentNodeElement[T comparable](v T) NodeElement[T] {
    43  	return newConcurrentNodeElement[T](v, nil)
    44  }
    45  
    46  func newConcurrentNodeElement[T comparable](v T, list BasicLinkedList[T]) *nodeElement[T] {
    47  	return &nodeElement[T]{
    48  		value: v,
    49  		list:  list,
    50  		lock:  &sync.RWMutex{},
    51  	}
    52  }
    53  
    54  func (e *nodeElement[T]) hasLock() bool {
    55  	return e.lock != nil
    56  }
    57  
    58  func (e *nodeElement[T]) HasNext() bool {
    59  	return e.next != nil
    60  }
    61  
    62  func (e *nodeElement[T]) HasPrev() bool {
    63  	return e.prev != nil
    64  }
    65  
    66  func (e *nodeElement[T]) GetNext() NodeElement[T] {
    67  	if e.next == nil {
    68  		return nil
    69  	}
    70  	if _, ok := e.next.(*nodeElement[T]); !ok {
    71  		return nil
    72  	}
    73  	return e.next
    74  }
    75  
    76  func (e *nodeElement[T]) GetPrev() NodeElement[T] {
    77  	if e.prev == nil {
    78  		return nil
    79  	}
    80  	if _, ok := e.prev.(*nodeElement[T]); !ok {
    81  		return nil
    82  	}
    83  	return e.prev
    84  }
    85  
    86  func (e *nodeElement[T]) GetValue() T {
    87  	if e.lock != nil {
    88  		e.lock.RLock()
    89  		defer e.lock.RUnlock()
    90  	}
    91  	return e.value
    92  }
    93  
    94  func (e *nodeElement[T]) SetValue(v T) {
    95  	if e.lock != nil {
    96  		e.lock.Lock()
    97  		defer e.lock.Unlock()
    98  	}
    99  	e.value = v
   100  }