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