github.com/aacfactory/fns@v1.2.86-0.20240310083819-80d667fc0a17/commons/caches/lru/entry.go (about)

     1  /*
     2   * Copyright 2023 Wang Min Xiang
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   * 	http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   *
    16   */
    17  
    18  package lru
    19  
    20  import "time"
    21  
    22  type Entry[K comparable, V any] struct {
    23  	next         *Entry[K, V]
    24  	prev         *Entry[K, V]
    25  	list         *List[K, V]
    26  	Key          K
    27  	Value        V
    28  	ExpiresAt    time.Time
    29  	ExpireBucket uint8
    30  }
    31  
    32  func (e *Entry[K, V]) PrevEntry() *Entry[K, V] {
    33  	if p := e.prev; e.list != nil && p != &e.list.root {
    34  		return p
    35  	}
    36  	return nil
    37  }
    38  
    39  type List[K comparable, V any] struct {
    40  	root Entry[K, V]
    41  	len  int
    42  }
    43  
    44  func (l *List[K, V]) Init() *List[K, V] {
    45  	l.root.next = &l.root
    46  	l.root.prev = &l.root
    47  	l.len = 0
    48  	return l
    49  }
    50  
    51  func NewList[K comparable, V any]() *List[K, V] { return new(List[K, V]).Init() }
    52  
    53  func (l *List[K, V]) Length() int { return l.len }
    54  
    55  func (l *List[K, V]) Back() *Entry[K, V] {
    56  	if l.len == 0 {
    57  		return nil
    58  	}
    59  	return l.root.prev
    60  }
    61  
    62  func (l *List[K, V]) lazyInit() {
    63  	if l.root.next == nil {
    64  		l.Init()
    65  	}
    66  }
    67  
    68  func (l *List[K, V]) insert(e, at *Entry[K, V]) *Entry[K, V] {
    69  	e.prev = at
    70  	e.next = at.next
    71  	e.prev.next = e
    72  	e.next.prev = e
    73  	e.list = l
    74  	l.len++
    75  	return e
    76  }
    77  
    78  func (l *List[K, V]) insertValue(k K, v V, expiresAt time.Time, at *Entry[K, V]) *Entry[K, V] {
    79  	return l.insert(&Entry[K, V]{Value: v, Key: k, ExpiresAt: expiresAt}, at)
    80  }
    81  
    82  func (l *List[K, V]) Remove(e *Entry[K, V]) V {
    83  	e.prev.next = e.next
    84  	e.next.prev = e.prev
    85  	e.next = nil
    86  	e.prev = nil
    87  	e.list = nil
    88  	l.len--
    89  
    90  	return e.Value
    91  }
    92  
    93  func (l *List[K, V]) move(e, at *Entry[K, V]) {
    94  	if e == at {
    95  		return
    96  	}
    97  	e.prev.next = e.next
    98  	e.next.prev = e.prev
    99  
   100  	e.prev = at
   101  	e.next = at.next
   102  	e.prev.next = e
   103  	e.next.prev = e
   104  }
   105  
   106  func (l *List[K, V]) PushFront(k K, v V) *Entry[K, V] {
   107  	l.lazyInit()
   108  	return l.insertValue(k, v, time.Time{}, &l.root)
   109  }
   110  
   111  func (l *List[K, V]) PushFrontExpirable(k K, v V, expiresAt time.Time) *Entry[K, V] {
   112  	l.lazyInit()
   113  	return l.insertValue(k, v, expiresAt, &l.root)
   114  }
   115  
   116  func (l *List[K, V]) MoveToFront(e *Entry[K, V]) {
   117  	if e.list != l || l.root.next == e {
   118  		return
   119  	}
   120  	l.move(e, &l.root)
   121  }