github.com/maypok86/otter@v1.2.1/cache.go (about)

     1  // Copyright (c) 2024 Alexey Mayshev. All rights reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package otter
    16  
    17  import (
    18  	"time"
    19  
    20  	"github.com/maypok86/otter/internal/core"
    21  )
    22  
    23  // DeletionCause the cause why a cached entry was deleted.
    24  type DeletionCause = core.DeletionCause
    25  
    26  const (
    27  	// Explicit the entry was manually deleted by the user.
    28  	Explicit = core.Explicit
    29  	// Replaced the entry itself was not actually deleted, but its value was replaced by the user.
    30  	Replaced = core.Replaced
    31  	// Size the entry was evicted due to size constraints.
    32  	Size = core.Size
    33  	// Expired the entry's expiration timestamp has passed.
    34  	Expired = core.Expired
    35  )
    36  
    37  type baseCache[K comparable, V any] struct {
    38  	cache *core.Cache[K, V]
    39  }
    40  
    41  func newBaseCache[K comparable, V any](c core.Config[K, V]) baseCache[K, V] {
    42  	return baseCache[K, V]{
    43  		cache: core.NewCache(c),
    44  	}
    45  }
    46  
    47  // Has checks if there is an entry with the given key in the cache.
    48  func (bs baseCache[K, V]) Has(key K) bool {
    49  	return bs.cache.Has(key)
    50  }
    51  
    52  // Get returns the value associated with the key in this cache.
    53  func (bs baseCache[K, V]) Get(key K) (V, bool) {
    54  	return bs.cache.Get(key)
    55  }
    56  
    57  // Delete removes the association for this key from the cache.
    58  func (bs baseCache[K, V]) Delete(key K) {
    59  	bs.cache.Delete(key)
    60  }
    61  
    62  // DeleteByFunc removes the association for this key from the cache when the given function returns true.
    63  func (bs baseCache[K, V]) DeleteByFunc(f func(key K, value V) bool) {
    64  	bs.cache.DeleteByFunc(f)
    65  }
    66  
    67  // Range iterates over all entries in the cache.
    68  //
    69  // Iteration stops early when the given function returns false.
    70  func (bs baseCache[K, V]) Range(f func(key K, value V) bool) {
    71  	bs.cache.Range(f)
    72  }
    73  
    74  // Clear clears the hash table, all policies, buffers, etc.
    75  //
    76  // NOTE: this operation must be performed when no requests are made to the cache otherwise the behavior is undefined.
    77  func (bs baseCache[K, V]) Clear() {
    78  	bs.cache.Clear()
    79  }
    80  
    81  // Close clears the hash table, all policies, buffers, etc and stop all goroutines.
    82  //
    83  // NOTE: this operation must be performed when no requests are made to the cache otherwise the behavior is undefined.
    84  func (bs baseCache[K, V]) Close() {
    85  	bs.cache.Close()
    86  }
    87  
    88  // Size returns the current number of entries in the cache.
    89  func (bs baseCache[K, V]) Size() int {
    90  	return bs.cache.Size()
    91  }
    92  
    93  // Capacity returns the cache capacity.
    94  func (bs baseCache[K, V]) Capacity() int {
    95  	return bs.cache.Capacity()
    96  }
    97  
    98  // Stats returns a current snapshot of this cache's cumulative statistics.
    99  func (bs baseCache[K, V]) Stats() Stats {
   100  	return newStats(bs.cache.Stats())
   101  }
   102  
   103  // Extension returns access to inspect and perform low-level operations on this cache based on its runtime
   104  // characteristics. These operations are optional and dependent on how the cache was constructed
   105  // and what abilities the implementation exposes.
   106  func (bs baseCache[K, V]) Extension() Extension[K, V] {
   107  	return newExtension(bs.cache)
   108  }
   109  
   110  // Cache is a structure performs a best-effort bounding of a hash table using eviction algorithm
   111  // to determine which entries to evict when the capacity is exceeded.
   112  type Cache[K comparable, V any] struct {
   113  	baseCache[K, V]
   114  }
   115  
   116  func newCache[K comparable, V any](c core.Config[K, V]) Cache[K, V] {
   117  	return Cache[K, V]{
   118  		baseCache: newBaseCache(c),
   119  	}
   120  }
   121  
   122  // Set associates the value with the key in this cache.
   123  //
   124  // If it returns false, then the key-value pair had too much cost and the Set was dropped.
   125  func (c Cache[K, V]) Set(key K, value V) bool {
   126  	return c.cache.Set(key, value)
   127  }
   128  
   129  // SetIfAbsent if the specified key is not already associated with a value associates it with the given value.
   130  //
   131  // If the specified key is not already associated with a value, then it returns false.
   132  //
   133  // Also, it returns false if the key-value pair had too much cost and the SetIfAbsent was dropped.
   134  func (c Cache[K, V]) SetIfAbsent(key K, value V) bool {
   135  	return c.cache.SetIfAbsent(key, value)
   136  }
   137  
   138  // CacheWithVariableTTL is a structure performs a best-effort bounding of a hash table using eviction algorithm
   139  // to determine which entries to evict when the capacity is exceeded.
   140  type CacheWithVariableTTL[K comparable, V any] struct {
   141  	baseCache[K, V]
   142  }
   143  
   144  func newCacheWithVariableTTL[K comparable, V any](c core.Config[K, V]) CacheWithVariableTTL[K, V] {
   145  	return CacheWithVariableTTL[K, V]{
   146  		baseCache: newBaseCache(c),
   147  	}
   148  }
   149  
   150  // Set associates the value with the key in this cache and sets the custom ttl for this key-value pair.
   151  //
   152  // If it returns false, then the key-value pair had too much cost and the Set was dropped.
   153  func (c CacheWithVariableTTL[K, V]) Set(key K, value V, ttl time.Duration) bool {
   154  	return c.cache.SetWithTTL(key, value, ttl)
   155  }
   156  
   157  // SetIfAbsent if the specified key is not already associated with a value associates it with the given value
   158  // and sets the custom ttl for this key-value pair.
   159  //
   160  // If the specified key is not already associated with a value, then it returns false.
   161  //
   162  // Also, it returns false if the key-value pair had too much cost and the SetIfAbsent was dropped.
   163  func (c CacheWithVariableTTL[K, V]) SetIfAbsent(key K, value V, ttl time.Duration) bool {
   164  	return c.cache.SetIfAbsentWithTTL(key, value, ttl)
   165  }