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 }