github.com/searKing/golang/go@v1.2.117/container/lru/lru.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  // LRU takes advantage of list's sequence and map's efficient locate
    14  type LRU struct {
    15  	ll   *list.List // list.Element.Value type is of interface{}
    16  	m    map[any]*list.Element
    17  	once sync.Once
    18  }
    19  type Pair struct {
    20  	Key   any
    21  	Value any
    22  }
    23  
    24  // lazyInit lazily initializes a zero List value.
    25  func (lru *LRU) lazyInit() {
    26  	lru.once.Do(func() {
    27  		lru.ll = &list.List{}
    28  		lru.m = make(map[any]*list.Element)
    29  	})
    30  }
    31  
    32  func (lru *LRU) Keys() []any {
    33  	var keys []any
    34  	for key := range lru.m {
    35  		keys = append(keys, key)
    36  	}
    37  	return keys
    38  }
    39  func (lru *LRU) Values() []any {
    40  	var values []any
    41  	for _, value := range lru.m {
    42  		values = append(values, value)
    43  	}
    44  	return values
    45  }
    46  
    47  func (lru *LRU) Pairs() []Pair {
    48  	var pairs []Pair
    49  	for key, value := range lru.m {
    50  		pairs = append(pairs, Pair{
    51  			Key:   key,
    52  			Value: value,
    53  		})
    54  	}
    55  	return pairs
    56  }
    57  func (lru *LRU) AddPair(pair Pair) error {
    58  	return lru.Add(pair.Key, pair.Value)
    59  }
    60  
    61  // Add adds Key to the head of the linked list.
    62  func (lru *LRU) Add(key any, value any) error {
    63  	lru.lazyInit()
    64  	ele := lru.ll.PushFront(Pair{
    65  		Key:   key,
    66  		Value: value,
    67  	})
    68  	if _, ok := lru.m[key]; ok {
    69  		return errors.New("key was already in LRU")
    70  	}
    71  	lru.m[key] = ele
    72  	return nil
    73  }
    74  
    75  func (lru *LRU) AddOrUpdate(key any, value any) error {
    76  	lru.Remove(key)
    77  	return lru.Add(key, value)
    78  }
    79  
    80  func (lru *LRU) RemoveOldest() any {
    81  	if lru.ll == nil {
    82  		return nil
    83  	}
    84  	ele := lru.ll.Back()
    85  	pair := ele.Value.(Pair)
    86  	v := lru.ll.Remove(ele)
    87  	delete(lru.m, pair.Key)
    88  	return v
    89  }
    90  
    91  // Remove removes Key from cl.
    92  func (lru *LRU) Remove(key any) any {
    93  	if ele, ok := lru.m[key]; ok {
    94  		v := lru.ll.Remove(ele)
    95  		delete(lru.m, key)
    96  		return v
    97  	}
    98  	return nil
    99  }
   100  
   101  func (lru *LRU) Find(key any) (any, bool) {
   102  	e, ok := lru.m[key]
   103  	if !ok {
   104  		return nil, ok
   105  	}
   106  	return e.Value.(Pair).Value, true
   107  }
   108  
   109  func (lru *LRU) Peek(key any) (any, bool) {
   110  	e, ok := lru.m[key]
   111  	if ok {
   112  		lru.Remove(key)
   113  	}
   114  	return e.Value.(Pair).Value, ok
   115  }
   116  
   117  // Len returns the number of items in the cache.
   118  func (lru *LRU) Len() int {
   119  	return len(lru.m)
   120  }