// Copyright 2009 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE_list file.package internalimport// Entry is an LRU EntrytypeEntry[ comparable, any] struct {// Next and previous pointers in the doubly-linked list of elements. // To simplify the implementation, internally a list l is implemented // as a ring, such that &l.root is both the next element of the last // list element (l.Back()) and the previous element of the first list // element (l.Front()). next, prev *Entry[, ]// The list to which this element belongs. list *LruList[, ]// The LRU Key of this element. Key // The Value stored with this element. Value // The time this element would be cleaned up, optional ExpiresAt time.Time// The expiry bucket item was put in, optional ExpireBucket uint8}// PrevEntry returns the previous list element or nil.func ( *Entry[, ]) () *Entry[, ] {if := .prev; .list != nil && != &.list.root {return }returnnil}// LruList represents a doubly linked list.// The zero Value for LruList is an empty list ready to use.typeLruList[ comparable, any] struct { root Entry[, ] // sentinel list element, only &root, root.prev, and root.next are used len int// current list Length excluding (this) sentinel element}// Init initializes or clears list l.func ( *LruList[, ]) () *LruList[, ] { .root.next = &.root .root.prev = &.root .len = 0return}// NewList returns an initialized list.func [ comparable, any]() *LruList[, ] { returnnew(LruList[, ]).Init() }// Length returns the number of elements of list l.// The complexity is O(1).func ( *LruList[, ]) () int { return .len }// Back returns the last element of list l or nil if the list is empty.func ( *LruList[, ]) () *Entry[, ] {if .len == 0 {returnnil }return .root.prev}// lazyInit lazily initializes a zero List Value.func ( *LruList[, ]) () {if .root.next == nil { .Init() }}// insert inserts e after at, increments l.len, and returns e.func ( *LruList[, ]) (, *Entry[, ]) *Entry[, ] { .prev = .next = .next .prev.next = .next.prev = .list = .len++return}// insertValue is a convenience wrapper for insert(&Entry{Value: v, ExpiresAt: ExpiresAt}, at).func ( *LruList[, ]) ( , , time.Time, *Entry[, ]) *Entry[, ] {return .insert(&Entry[, ]{Value: , Key: , ExpiresAt: }, )}// Remove removes e from its list, decrements l.lenfunc ( *LruList[, ]) ( *Entry[, ]) { .prev.next = .next .next.prev = .prev .next = nil// avoid memory leaks .prev = nil// avoid memory leaks .list = nil .len--return .Value}// move moves e to next to at.func ( *LruList[, ]) (, *Entry[, ]) {if == {return } .prev.next = .next .next.prev = .prev .prev = .next = .next .prev.next = .next.prev = }// PushFront inserts a new element e with value v at the front of list l and returns e.func ( *LruList[, ]) ( , ) *Entry[, ] { .lazyInit()return .insertValue(, , time.Time{}, &.root)}// PushFrontExpirable inserts a new expirable element e with Value v at the front of list l and returns e.func ( *LruList[, ]) ( , , time.Time) *Entry[, ] { .lazyInit()return .insertValue(, , , &.root)}// MoveToFront moves element e to the front of list l.// If e is not an element of l, the list is not modified.// The element must not be nil.func ( *LruList[, ]) ( *Entry[, ]) {if .list != || .root.next == {return }// see comment in List.Remove about initialization of l .move(, &.root)}
The pages are generated with Goldsv0.8.2. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.