github.com/searKing/golang/go@v1.2.117/container/lru/keylru.go (about)

     1  // Copyright 2020 The searKing Author. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package lru
     6  
     7  import (
     8  	"container/list"
     9  	"errors"
    10  	"sync"
    11  )
    12  
    13  // KeyLRU takes advantage of list's sequence and map's efficient locate
    14  type KeyLRU struct {
    15  	ll   *list.List // list.Element.Value type is of interface{}
    16  	m    map[any]*list.Element
    17  	once sync.Once
    18  }
    19  
    20  // lazyInit lazily initializes a zero List value.
    21  func (lru *KeyLRU) lazyInit() {
    22  	lru.once.Do(func() {
    23  		lru.ll = &list.List{}
    24  		lru.m = make(map[any]*list.Element)
    25  	})
    26  }
    27  func (lru *KeyLRU) Keys() []any {
    28  	var keys []any
    29  	for key := range lru.m {
    30  		keys = append(keys, key)
    31  	}
    32  	return keys
    33  }
    34  
    35  // add adds Key to the head of the linked list.
    36  func (lru *KeyLRU) Add(key any) error {
    37  	lru.lazyInit()
    38  	ele := lru.ll.PushFront(key)
    39  	if _, ok := lru.m[key]; ok {
    40  		return errors.New("key was already in LRU")
    41  	}
    42  	lru.m[key] = ele
    43  	return nil
    44  }
    45  func (lru *KeyLRU) AddOrUpdate(key any) error {
    46  	lru.Remove(key)
    47  	return lru.Add(key)
    48  }
    49  
    50  func (lru *KeyLRU) RemoveOldest() any {
    51  	if lru.ll == nil {
    52  		return nil
    53  	}
    54  	ele := lru.ll.Back()
    55  	key := ele.Value.(any)
    56  	lru.ll.Remove(ele)
    57  	delete(lru.m, key)
    58  	return key
    59  }
    60  
    61  // Remove removes Key from cl.
    62  func (lru *KeyLRU) Remove(key any) any {
    63  	if ele, ok := lru.m[key]; ok {
    64  		v := lru.ll.Remove(ele)
    65  		delete(lru.m, key)
    66  		return v
    67  	}
    68  	return nil
    69  }
    70  
    71  func (lru *KeyLRU) Find(key any) (any, bool) {
    72  	e, ok := lru.m[key]
    73  	return e, ok
    74  }
    75  
    76  func (lru *KeyLRU) Peek(key any) (any, bool) {
    77  	e, ok := lru.m[key]
    78  	if ok {
    79  		lru.Remove(key)
    80  	}
    81  	return e, ok
    82  }
    83  
    84  // Len returns the number of items in the cache.
    85  func (lru *KeyLRU) Len() int {
    86  	return len(lru.m)
    87  }