github.com/leslie-fei/fastcache@v0.0.0-20240520092641-b7a9eb05711f/list.go (about) 1 package fastcache 2 3 import "unsafe" 4 5 var ( 6 sizeOfLRUNode = unsafe.Sizeof(listNode{}) 7 sizeOfLRU = unsafe.Sizeof(list{}) 8 ) 9 10 // listNode of list 11 type listNode struct { 12 prev uint64 // prev listNode 13 next uint64 // next listNode 14 //dataNode uint64 // current DataNode offset 15 } 16 17 func (ln *listNode) SetPrev(base uintptr, node *listNode) { 18 ln.prev = uint64(uintptr(unsafe.Pointer(node)) - base) 19 } 20 21 func (ln *listNode) SetNext(base uintptr, node *listNode) { 22 ln.next = uint64(uintptr(unsafe.Pointer(node)) - base) 23 } 24 25 func (ln *listNode) Prev(base uintptr) *listNode { 26 return (*listNode)(unsafe.Pointer(base + uintptr(ln.prev))) 27 } 28 29 func (ln *listNode) Next(base uintptr) *listNode { 30 return (*listNode)(unsafe.Pointer(base + uintptr(ln.next))) 31 } 32 33 // Offset return *listNode offset base ptr 34 func (ln *listNode) Offset(base uintptr) uint64 { 35 return uint64(uintptr(unsafe.Pointer(ln)) - base) 36 } 37 38 // list double linked list 39 type list struct { 40 root listNode 41 len uint64 42 } 43 44 func (l *list) Init(base uintptr) { 45 l.root.SetNext(base, &l.root) 46 l.root.SetPrev(base, &l.root) 47 l.len = 0 48 } 49 50 func (l *list) Len() uint64 { 51 return l.len 52 } 53 54 func (l *list) Front(base uintptr) *listNode { 55 if l.len == 0 { 56 return nil 57 } 58 return l.root.Next(base) 59 } 60 61 func (l *list) Back(base uintptr) *listNode { 62 if l.len == 0 { 63 return nil 64 } 65 return l.root.Prev(base) 66 } 67 68 func (l *list) Remove(base uintptr, e *listNode) { 69 l.remove(base, e) 70 } 71 72 func (l *list) PushFront(base uintptr, e *listNode) *listNode { 73 return l.insert(base, e, &l.root) 74 } 75 76 func (l *list) PushBack(base uintptr, e *listNode) *listNode { 77 return l.insert(base, e, l.root.Prev(base)) 78 } 79 80 func (l *list) MoveToFront(base uintptr, e *listNode) { 81 /** 82 if e.list != l || l.root.next == e { 83 return 84 } 85 l.move(e, &l.root) 86 */ 87 if l.root.next == e.Offset(base) { 88 return 89 } 90 l.move(base, e, &l.root) 91 } 92 93 func (l *list) MoveToBack(base uintptr, e *listNode) { 94 /** 95 if e.list != l || l.root.prev == e { 96 return 97 } 98 l.move(e, l.root.prev) 99 */ 100 if l.root.prev == e.Offset(base) { 101 return 102 } 103 l.move(base, e, l.root.Prev(base)) 104 } 105 106 func (l *list) insert(base uintptr, e, at *listNode) *listNode { 107 /** 108 e.prev = at 109 e.next = at.next 110 e.prev.next = e 111 e.next.prev = e 112 e.hashMapBucket = l 113 l.len++ 114 */ 115 e.SetPrev(base, at) 116 e.SetNext(base, at.Next(base)) 117 e.Prev(base).SetNext(base, e) 118 e.Next(base).SetPrev(base, e) 119 l.len++ 120 return e 121 } 122 123 func (l *list) remove(base uintptr, e *listNode) { 124 /** 125 e.prev.next = e.next 126 e.next.prev = e.prev 127 e.next = nil // avoid memory leaks 128 e.prev = nil // avoid memory leaks 129 e.list = nil 130 l.len-- 131 */ 132 e.Prev(base).SetNext(base, e.Next(base)) 133 e.Next(base).SetPrev(base, e.Prev(base)) 134 135 l.len-- 136 } 137 138 func (l *list) move(base uintptr, e, at *listNode) { 139 /** 140 if e == at { 141 return 142 } 143 e.prev.next = e.next 144 e.next.prev = e.prev 145 146 e.prev = at 147 e.next = at.next 148 e.prev.next = e 149 e.next.prev = e 150 */ 151 if e == at { 152 return 153 } 154 155 e.Prev(base).SetNext(base, e.Next(base)) 156 e.Next(base).SetPrev(base, e.Prev(base)) 157 e.SetPrev(base, at) 158 e.SetNext(base, at.Next(base)) 159 e.Prev(base).SetNext(base, e) 160 e.Next(base).SetPrev(base, e) 161 }