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  }