imcache

package module
v1.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 17, 2024 License: MIT Imports: 5 Imported by: 10

README

imcache

GitHub Workflow Status Go Report Card Go Version GoDoc Coverage Status

imcache is a zero-dependency generic in-memory cache Go library.

It supports absolute expiration, sliding expiration, max entries limit, eviction callbacks and sharding. It's safe for concurrent use by multiple goroutines.

import "github.com/erni27/imcache"

Usage

package main

import (
	"fmt"

	"github.com/erni27/imcache"
)

func main() {
	// Zero value Cache is a valid non-sharded cache
	// with no expiration, no sliding expiration,
	// no entry limit and no eviction callback.
	var c imcache.Cache[uint32, string]
	c.Set(1, "one", imcache.WithNoExpiration())
	value, ok := c.Get(1)
	if !ok {
		panic("value for the key '1' not found")
	}
	fmt.Println(value)
}
Expiration

imcache supports the following expiration options:

  • WithNoExpiration - the entry will never expire.
  • WithExpiration - the entry will expire after a certain time.
  • WithExpirationDate - the entry will expire at a certain date.
  • WithSlidingExpiration - the entry will expire after a certain time if it hasn't been accessed. The expiration time is reset every time the entry is accessed. It is slided to now + sliding expiration time when now is the time when the entry was accessed.
// The entry will never expire.
c.Set(1, "one", imcache.WithNoExpiration())
// The entry will expire after 1 second.
c.Set(2, "two", imcache.WithExpiration(time.Second))
// The entry will expire at the given date.
c.Set(3, "three", imcache.WithExpirationDate(time.Now().Add(time.Second)))
// The entry will expire after 1 second if it hasn't been accessed.
// Otherwise, the expiration time will slide to the access time + 1 second.
c.Set(4, "four", imcache.WithSlidingExpiration(time.Second))

One can also use the WithExpirationOption and WithSlidingExpirationOption options to set the default expiration time for the given cache instance. By default, the default expiration time is set to no expiration.

// Create a new cache instance with the default expiration time equal to 1 second.
c1 := imcache.New[int32, string](imcache.WithDefaultExpirationOption[int32, string](time.Second))
// The entry will expire after 1 second (the default expiration time).
c1.Set(1, "one", imcache.WithDefaultExpiration())

// Create a new cache instance with the default sliding expiration time equal to 1 second.
c2 := imcache.New[int32, string](imcache.WithDefaultSlidingExpirationOption[int32, string](time.Second))
// The entry will expire after 1 second (the default expiration time) if it hasn't been accessed.
// Otherwise, the expiration time will slide to the access time + 1 second.
c2.Set(1, "one", imcache.WithDefaultExpiration())
Key eviction

imcache actively evicts expired entries. It removes expired entries when they are accessed by most of Cache methods (both read and write). Peek, PeekMultiple and PeekAll methods are the exception. They don't remove the expired entries and do not slide the expiration time (if the sliding expiration is set).

It is possible to use the Cleaner to periodically remove expired entries from the cache. The Cleaner is a background goroutine that periodically removes expired entries from the cache. The Cleaner is disabled by default. One can use the WithCleanerOption option to enable the Cleaner and set the cleaning interval.

// Create a new Cache with a Cleaner which will remove expired entries every 5 minutes.
c := imcache.New[string, string](imcache.WithCleanerOption[string, string](5 * time.Minute))
// Close the Cache. This will stop the Cleaner if it is running.
defer c.Close()

To be notified when the entry is evicted from the cache, one can use the EvictionCallback. It's a function that accepts the key and the value of the evicted entry along with the reason why the entry was evicted. One can use the WithEvictionCallbackOption option to set the EvictionCallback for the given cache instance.

package main

import (
	"log"
	"time"

	"github.com/erni27/imcache"
)

func LogEvictedEntry(key string, value interface{}, reason imcache.EvictionReason) {
	log.Printf("Evicted entry: %s=%v (%s)", key, value, reason)
}

func main() {
	c := imcache.New[string, interface{}](
		imcache.WithDefaultExpirationOption[string, interface{}](time.Second),
		imcache.WithEvictionCallbackOption[string, interface{}](LogEvictedEntry),
	)
	c.Set("foo", "bar", imcache.WithDefaultExpiration())

	time.Sleep(time.Second)

	_, ok := c.Get("foo")
	if ok {
		panic("expected entry to be expired")
	}
}

EvictionCallback is invoked in a separate goroutine to not block any Cache method.

Max entries limit

imcache supports setting the max entries limit. When the max entries limit is reached, the entry is evicted according to the chosen eviction policy. imcache supports the following eviction policies:

  • EvictionPolicyLRU - the least recently used entry is evicted.
  • EvictionPolicyLFU - the least frequently used entry is evicted.
  • EvictionPolicyRandom - a random entry is evicted.

One can use the WithMaxEntriesLimitOption option to set the max entries limit and the eviction policy for the given cache instance.

c := imcache.New[uint32, string](imcache.WithMaxEntriesLimitOption[uint32, string](1000, imcache.EvictionPolicyLRU))
Sharding

imcache supports sharding. Each shard is a separate Cache instance. A shard for a given key is selected by computing the hash of the key and taking the modulus of the number of shards. imcache exposes the Hasher64 interface that wraps Sum64 accepting a key and returning a 64-bit hash of the input key. It can be used to implement custom sharding algorithms.

A Sharded instance can be created by calling the NewSharded method.

c := imcache.NewSharded[string, string](4, imcache.DefaultStringHasher64{})

All previous examples apply to Sharded type as well. Note that Option(s) are applied to each shard (Cache instance separately) not to the Sharded instance itself.

Performance

imcache was compared to the vanilla Go map with simple locking mechanism. The benchmarks were run on an Apple M1 Pro 8-core CPU with 32 GB of RAM running macOS Ventura 13.4.1 using Go 1.21.6.

Reads
go version
go version go1.21.6 darwin/arm64
go test -benchmem -bench "Get_|Get$|Peek_|Peek$"
goos: darwin
goarch: arm64
pkg: github.com/erni27/imcache
BenchmarkCache_Get-8                                                                 2655246	       428.5 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get/2_Shards-8                                                      2810713	       436.8 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get/4_Shards-8                                                      2732820	       444.9 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get/8_Shards-8                                                      2957444	       445.7 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get/16_Shards-8                                                     2773999	       447.0 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get/32_Shards-8                                                     2752075	       443.4 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get/64_Shards-8                                                     2752899	       439.7 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get/128_Shards-8                                                    2771691	       456.3 ns/op	      23 B/op	       1 allocs/op
BenchmarkCache_Get_MaxEntriesLimit_EvictionPolicyLRU-8                               2410712	       526.8 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyLRU/2_Shards-8                    2346715	       543.2 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyLRU/4_Shards-8                    2317453	       566.2 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyLRU/8_Shards-8                    2293774	       556.5 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyLRU/16_Shards-8                   2292554	       557.7 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyLRU/32_Shards-8                   2262634	       542.0 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyLRU/64_Shards-8                   2318079	       544.2 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyLRU/128_Shards-8                  2278434	       565.6 ns/op	      23 B/op	       1 allocs/op
BenchmarkCache_Get_MaxEntriesLimit_EvictionPolicyLFU-8                               2482602	       528.0 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyLFU/2_Shards-8                    2403782	       534.2 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyLFU/4_Shards-8                    2286364	       548.8 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyLFU/8_Shards-8                    2239857	       576.0 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyLFU/16_Shards-8                   2198414	       556.7 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyLFU/32_Shards-8                   2109063	       554.7 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyLFU/64_Shards-8                   2251125	       550.6 ns/op	      23 B/op	       2 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyLFU/128_Shards-8                  2172662	       551.0 ns/op	      23 B/op	       2 allocs/op
BenchmarkCache_Get_MaxEntriesLimit_EvictionPolicyRandom-8                            2959924	       433.1 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyRandom/2_Shards-8                 2909020	       429.9 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyRandom/4_Shards-8                 2890734	       438.4 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyRandom/8_Shards-8                 2947471	       432.5 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyRandom/16_Shards-8                2937757	       456.9 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyRandom/32_Shards-8                2963146	       427.1 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyRandom/64_Shards-8                2794441	       430.1 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyRandom/128_Shards-8               2965760	       466.8 ns/op	      23 B/op	       1 allocs/op
BenchmarkCache_Peek-8                                                                3034557	       419.7 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Peek/2_Shards-8                                                     2907327	       452.0 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Peek/4_Shards-8                                                     2918097	       441.8 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Peek/8_Shards-8                                                     2923375	       442.1 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Peek/16_Shards-8                                                    2927227	       443.9 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Peek/32_Shards-8                                                    2843028	       439.9 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Peek/64_Shards-8                                                    2898458	       461.5 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Peek/128_Shards-8                                                   2805452	       460.1 ns/op	      23 B/op	       1 allocs/op
BenchmarkMap_Get-8                                                                   4693522	       327.8 ns/op	      23 B/op	       1 allocs/op
BenchmarkCache_Get_Parallel-8                                                        2272208	       546.0 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_Parallel/2_Shards-8                                             3216616	       416.7 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_Parallel/4_Shards-8                                             3898989	       327.8 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_Parallel/8_Shards-8                                             5443684	       241.1 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_Parallel/16_Shards-8                                            6995467	       186.5 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_Parallel/32_Shards-8                                            8505585	       154.6 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_Parallel/64_Shards-8                                            10256752	       170.9 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_Parallel/128_Shards-8                                           12003910	       113.5 ns/op	      23 B/op	       1 allocs/op
BenchmarkCache_Get_MaxEntriesLimit_EvictionPolicyLRU_Parallel-8                      1995304	       627.3 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyLRU_Parallel/2_Shards-8           2628376	       474.5 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyLRU_Parallel/4_Shards-8           3056476	       407.5 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyLRU_Parallel/8_Shards-8           4281996	       304.3 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyLRU_Parallel/16_Shards-8          5438091	       237.2 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyLRU_Parallel/32_Shards-8          6442630	       209.5 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyLRU_Parallel/64_Shards-8          8096386	       177.4 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyLRU_Parallel/128_Shards-8         9417211	       137.3 ns/op	      23 B/op	       1 allocs/op
BenchmarkCache_Get_MaxEntriesLimit_EvictionPolicyLFU_Parallel-8                      1463374	       796.4 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyLFU_Parallel/2_Shards-8           2112945	       591.5 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyLFU_Parallel/4_Shards-8           3008568	       412.4 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyLFU_Parallel/8_Shards-8           4302746	       296.3 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyLFU_Parallel/16_Shards-8          5671981	       231.8 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyLFU_Parallel/32_Shards-8          6828380	       186.5 ns/op	      23 B/op	       2 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyLFU_Parallel/64_Shards-8          7074661	       161.5 ns/op	      23 B/op	       2 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyLFU_Parallel/128_Shards-8         9294237	       139.2 ns/op	      23 B/op	       2 allocs/op
BenchmarkCache_Get_MaxEntriesLimit_EvictionPolicyRandom_Parallel-8                   1838180	       675.1 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyRandom_Parallel/2_Shards-8        2781007	       455.5 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyRandom_Parallel/4_Shards-8        4072056	       341.4 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyRandom_Parallel/8_Shards-8        5529966	       227.5 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyRandom_Parallel/16_Shards-8       7354364	       211.7 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyRandom_Parallel/32_Shards-8       8624466	       138.5 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyRandom_Parallel/64_Shards-8       11442829	       161.4 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Get_MaxEntriesLimit_EvictionPolicyRandom_Parallel/128_Shards-8      12071902	       104.4 ns/op	      23 B/op	       1 allocs/op
BenchmarkCache_Peek_Parallel-8                                                       7957777	       155.1 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Peek_Parallel/2_Shards-8                                            7781154	       163.5 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Peek_Parallel/4_Shards-8                                           12301404	       112.0 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Peek_Parallel/8_Shards-8                                           12828216	       106.2 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Peek_Parallel/16_Shards-8                                          13837890	       94.11 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Peek_Parallel/32_Shards-8                                          14921073	       89.67 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Peek_Parallel/64_Shards-8                                          15708536	       87.81 ns/op	      23 B/op	       1 allocs/op
BenchmarkSharded_Peek_Parallel/128_Shards-8                                         16547871	       84.76 ns/op	      23 B/op	       1 allocs/op
BenchmarkMap_Get_Parallel-8                                                          3098846	       453.0 ns/op	      23 B/op	       1 allocs/op
PASS
ok  	github.com/erni27/imcache	366.377s
Writes
go version
go version go1.21.6 darwin/arm64
go test -benchmem -bench "_Set"
goos: darwin
goarch: arm64
pkg: github.com/erni27/imcache
BenchmarkCache_Set-8                                                                 2942062	       461.7 ns/op	     161 B/op	       2 allocs/op
BenchmarkSharded_Set/2_Shards-8                                                      2939275	       487.5 ns/op	     162 B/op	       2 allocs/op
BenchmarkSharded_Set/4_Shards-8                                                      2827146	       497.1 ns/op	     166 B/op	       2 allocs/op
BenchmarkSharded_Set/8_Shards-8                                                      2837316	       509.1 ns/op	     165 B/op	       2 allocs/op
BenchmarkSharded_Set/16_Shards-8                                                     2818513	       495.7 ns/op	     166 B/op	       2 allocs/op
BenchmarkSharded_Set/32_Shards-8                                                     2793490	       506.3 ns/op	     167 B/op	       2 allocs/op
BenchmarkSharded_Set/64_Shards-8                                                     2815544	       499.7 ns/op	     166 B/op	       2 allocs/op
BenchmarkSharded_Set/128_Shards-8                                                    2738779	       511.2 ns/op	     170 B/op	       2 allocs/op
BenchmarkCache_Set_MaxEntriesLimit_EvictionPolicyLRU-8                               3217950	       423.2 ns/op	      65 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyLRU/2_Shards-8                    2893335	       458.4 ns/op	      69 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyLRU/4_Shards-8                    2940762	       460.9 ns/op	      69 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyLRU/8_Shards-8                    2976267	       462.5 ns/op	      69 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyLRU/16_Shards-8                   2849967	       478.1 ns/op	      69 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyLRU/32_Shards-8                   2859116	       472.2 ns/op	      69 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyLRU/64_Shards-8                   2842370	       466.6 ns/op	      68 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyLRU/128_Shards-8                  2863222	       481.6 ns/op	      68 B/op	       2 allocs/op
BenchmarkCache_Set_MaxEntriesLimit_EvictionPolicyLFU-8                               3198320	       417.6 ns/op	      65 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyLFU/2_Shards-8                    2944507	       450.2 ns/op	      69 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyLFU/4_Shards-8                    2915707	       456.9 ns/op	      69 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyLFU/8_Shards-8                    2820458	       464.4 ns/op	      68 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyLFU/16_Shards-8                   2833208	       479.6 ns/op	      68 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyLFU/32_Shards-8                   2864629	       460.9 ns/op	      69 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyLFU/64_Shards-8                   2846596	       491.7 ns/op	      68 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyLFU/128_Shards-8                  2841228	       493.6 ns/op	      68 B/op	       2 allocs/op
BenchmarkCache_Set_MaxEntriesLimit_EvictionPolicyRandom-8                            2988330	       459.8 ns/op	      59 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyRandom/2_Shards-8                 2713388	       495.6 ns/op	      57 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyRandom/4_Shards-8                 2756364	       493.7 ns/op	      58 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyRandom/8_Shards-8                 2691565	       484.5 ns/op	      57 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyRandom/16_Shards-8                2710840	       479.6 ns/op	      57 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyRandom/32_Shards-8                2728695	       496.0 ns/op	      57 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyRandom/64_Shards-8                2690887	       507.6 ns/op	      57 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyRandom/128_Shards-8               2663871	       495.1 ns/op	      57 B/op	       2 allocs/op
BenchmarkMap_Set-8                                                                   5847526	       339.0 ns/op	     106 B/op	       2 allocs/op
BenchmarkCache_Set_Parallel-8                                                        2347249	       527.7 ns/op	     123 B/op	       2 allocs/op
BenchmarkSharded_Set_Parallel/2_Shards-8                                             3112208	       444.3 ns/op	     156 B/op	       2 allocs/op
BenchmarkSharded_Set_Parallel/4_Shards-8                                             3323001	       401.2 ns/op	     149 B/op	       2 allocs/op
BenchmarkSharded_Set_Parallel/8_Shards-8                                             4130948	       291.3 ns/op	     131 B/op	       2 allocs/op
BenchmarkSharded_Set_Parallel/16_Shards-8                                            5516203	       274.4 ns/op	     169 B/op	       2 allocs/op
BenchmarkSharded_Set_Parallel/32_Shards-8                                            6069385	       219.0 ns/op	     158 B/op	       2 allocs/op
BenchmarkSharded_Set_Parallel/64_Shards-8                                            7290878	       187.9 ns/op	     141 B/op	       2 allocs/op
BenchmarkSharded_Set_Parallel/128_Shards-8                                           8021259	       163.6 ns/op	     133 B/op	       2 allocs/op
BenchmarkCache_Set_MaxEntriesLimit_EvictionPolicyLRU_Parallel-8                      2402929	       555.8 ns/op	      66 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyLRU_Parallel/2_Shards-8           2835458	       418.2 ns/op	      69 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyLRU_Parallel/4_Shards-8           3219746	       393.8 ns/op	      65 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyLRU_Parallel/8_Shards-8           4225972	       301.9 ns/op	      65 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyLRU_Parallel/16_Shards-8          5186444	       246.7 ns/op	      67 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyLRU_Parallel/32_Shards-8          6100933	       222.6 ns/op	      70 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyLRU_Parallel/64_Shards-8          7518198	       180.7 ns/op	      65 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyLRU_Parallel/128_Shards-8         8257630	       180.1 ns/op	      65 B/op	       2 allocs/op
BenchmarkCache_Set_MaxEntriesLimit_EvictionPolicyLFU_Parallel-8                      2344273	       543.1 ns/op	      66 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyLFU_Parallel/2_Shards-8           2973801	       442.6 ns/op	      69 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyLFU_Parallel/4_Shards-8           3416180	       383.2 ns/op	      65 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyLFU_Parallel/8_Shards-8           4511509	       293.7 ns/op	      65 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyLFU_Parallel/16_Shards-8          5374215	       230.7 ns/op	      68 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyLFU_Parallel/32_Shards-8          6602998	       205.1 ns/op	      65 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyLFU_Parallel/64_Shards-8          7730086	       171.8 ns/op	      65 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyLFU_Parallel/128_Shards-8         8232051	       154.6 ns/op	      65 B/op	       2 allocs/op
BenchmarkCache_Set_MaxEntriesLimit_EvictionPolicyRandom_Parallel-8                   2186001	       592.0 ns/op	      55 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyRandom_Parallel/2_Shards-8        2716564	       438.3 ns/op	      57 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyRandom_Parallel/4_Shards-8        3548733	       366.0 ns/op	      55 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyRandom_Parallel/8_Shards-8        4665452	       296.7 ns/op	      55 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyRandom_Parallel/16_Shards-8       6088111	       240.0 ns/op	      59 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyRandom_Parallel/32_Shards-8       7442355	       197.1 ns/op	      55 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyRandom_Parallel/64_Shards-8       8089219	       163.0 ns/op	      55 B/op	       2 allocs/op
BenchmarkSharded_Set_MaxEntriesLimit_EvictionPolicyRandom_Parallel/128_Shards-8      9815180	       144.8 ns/op	      56 B/op	       2 allocs/op
BenchmarkMap_Set_Parallel-8                                                          3541270	       407.3 ns/op	      92 B/op	       2 allocs/op
PASS
ok  	github.com/erni27/imcache	135.166s

Documentation

Overview

Package imcache provides a generic in-memory cache. It supports absolute expiration, sliding expiration, max entries limit, eviction callbacks and sharding. It's safe for concurrent use by multiple goroutines.

The New function creates a new in-memory non-sharded cache instance.

The NewSharded function creates a new in-memory sharded cache instance.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Decrement deprecated added in v0.5.0

func Decrement[V Number](old V) V

Decrement decrements the given number by one.

Deprecated: Decrement function is deprecated. It is easy to write your own function. imcache's goal is to be simple. Creating artificial types or functions that are not even needed conflicts with this goal.

func Increment deprecated added in v0.5.0

func Increment[V Number](old V) V

Increment increments the given number by one.

Deprecated: Increment function is deprecated. It is easy to write your own function. imcache's goal is to be simple. Creating artificial types or functions that are not even needed conflicts with this goal.

Types

type Cache

type Cache[K comparable, V any] struct {
	// contains filtered or unexported fields
}

Cache is a non-sharded in-memory cache.

By default, it has no default expiration, no default sliding expiration no entry limit and no eviction callback.

The zero value Cache is ready to use.

If you want to configure a Cache, use the New function and provide proper Option(s).

Example:

c := imcache.New[string, interface{}](
	imcache.WithDefaultExpirationOption[string, interface{}](time.Second),
	imcache.WithCleanerOption[string, interface{}](5*time.Minute),
	imcache.WithMaxEntriesOption[string, interface{}](10000),
	imcache.WithEvictionCallbackOption[string, interface{}](LogEvictedEntry),
)

func New

func New[K comparable, V any](opts ...Option[K, V]) *Cache[K, V]

New returns a new Cache instance.

By default, a returned Cache has no default expiration, no default sliding expiration, no entry limit and no eviction callback.

Option(s) can be used to customize the returned Cache.

func (*Cache[K, V]) Close added in v0.10.0

func (c *Cache[K, V]) Close()

Close closes the cache. It purges all entries and stops the cleaner if it is running. After Close, all other methods are NOP returning zero values immediately.

It is safe to call Close multiple times.

It's not necessary to call Close if the cache is no longer referenced and there is no cleaner running. Garbage collector will collect the cache.

func (*Cache[K, V]) CompareAndSwap added in v1.1.0

func (c *Cache[K, V]) CompareAndSwap(key K, expected, new V, compare func(V, V) bool, exp Expiration) (swapped, present bool)

CompareAndSwap replaces the value for the given key if the current value is equal to the expected value.

Equality is defined by the given compare function.

If it encounters an expired entry, the expired entry is evicted.

func (*Cache[K, V]) Get

func (c *Cache[K, V]) Get(key K) (V, bool)

Get returns the value for the given key.

If it encounters an expired entry, the expired entry is evicted.

func (*Cache[K, V]) GetAll added in v0.3.0

func (c *Cache[K, V]) GetAll() map[K]V

GetAll returns a copy of all entries in the cache.

If it encounters an expired entry, the expired entry is evicted.

func (*Cache[K, V]) GetMultiple added in v1.1.0

func (c *Cache[K, V]) GetMultiple(keys ...K) map[K]V

GetMultiple returns the values for the given keys. If the Cache is not closed, then the returned map is always a non-nil one.

If it encounters an expired entry, the expired entry is evicted.

func (*Cache[K, V]) GetOrSet added in v0.4.0

func (c *Cache[K, V]) GetOrSet(key K, val V, exp Expiration) (value V, present bool)

GetOrSet returns the value for the given key and true if it exists, otherwise it sets the value for the given key and returns the set value and false.

If it encounters an expired entry, the expired entry is evicted.

func (*Cache[K, V]) Len added in v0.3.0

func (c *Cache[K, V]) Len() int

Len returns the number of entries in the cache.

func (*Cache[K, V]) Peek added in v1.2.0

func (c *Cache[K, V]) Peek(key K) (V, bool)

Peek returns the value for the given key without actively evicting the entry if it is expired and updating the entry's sliding expiration.

If the max entries limit is set, it doesn't update the entry's position in the eviction queue.

func (*Cache[K, V]) PeekAll added in v1.2.0

func (c *Cache[K, V]) PeekAll() map[K]V

PeekAll returns a copy of all entries in the cache without actively evicting the encountered entry if it is expired and updating the entry's sliding expiration.

If the max entries limit is set, it doesn't update the encountered entry's position in the eviction queue.

func (*Cache[K, V]) PeekMultiple added in v1.2.0

func (c *Cache[K, V]) PeekMultiple(keys ...K) map[K]V

PeekMultiple returns the values for the given keys without actively evicting the encountered entry if it is expired and updating the entry's sliding expiration. If the Cache is not closed, then the returned map is always a non-nil one.

If the max entries limit is set, it doesn't update the encountered entry's position in the eviction queue.

func (*Cache[K, V]) Remove

func (c *Cache[K, V]) Remove(key K) (present bool)

Remove removes the cache entry for the given key.

It returns true if the entry is present and removed, otherwise it returns false.

If it encounters an expired entry, the expired entry is evicted. It results in calling the eviction callback with EvictionReasonExpired, not EvictionReasonRemoved. If entry is expired, it returns false.

func (*Cache[K, V]) RemoveAll

func (c *Cache[K, V]) RemoveAll()

RemoveAll removes all entries.

If an eviction callback is set, it is called for each removed entry.

If it encounters an expired entry, the expired entry is evicted. It results in calling the eviction callback with EvictionReasonExpired, not EvictionReasonRemoved.

func (*Cache[K, V]) RemoveExpired added in v0.9.0

func (c *Cache[K, V]) RemoveExpired()

RemoveExpired removes all expired entries.

If an eviction callback is set, it is called for each removed entry.

func (*Cache[K, V]) Replace

func (c *Cache[K, V]) Replace(key K, val V, exp Expiration) (present bool)

Replace replaces the value for the given key. It returns true if the value is present and replaced, otherwise it returns false.

If it encounters an expired entry, the expired entry is evicted.

If you want to add or replace an entry, use the Set method instead.

func (*Cache[K, V]) ReplaceKey added in v0.11.0

func (c *Cache[K, V]) ReplaceKey(old, new K, exp Expiration) (present bool)

ReplaceKey replaces the given old key with the new key. The value remains the same. It returns true if the key is present and replaced, otherwise it returns false. If there is an existing entry for the new key, it is replaced.

If it encounters an expired entry, the expired entry is evicted.

func (*Cache[K, V]) ReplaceWithFunc added in v0.5.0

func (c *Cache[K, V]) ReplaceWithFunc(key K, f func(current V) (new V), exp Expiration) (present bool)

ReplaceWithFunc replaces the value for the given key with the result of the given function that takes the current value as an argument. It returns true if the value is present and replaced, otherwise it returns false.

If it encounters an expired entry, the expired entry is evicted.

If you want to replace the value with a new value not depending on the current value, use the Replace method instead.

Example showing how to increment the value by 1 using ReplaceWithFunc:

var c imcache.Cache[string, int32]
c.Set("foo", 997, imcache.WithNoExpiration())
_ = c.ReplaceWithFunc(
	"foo",
	func(current int32) int32 { return current + 1 },
	imcache.WithNoExpiration(),
)

func (*Cache[K, V]) Set

func (c *Cache[K, V]) Set(key K, val V, exp Expiration)

Set sets the value for the given key. If the entry already exists, it is replaced.

If it encounters an expired entry, it is evicted and a new entry is added.

If you don't want to replace an existing entry, use the GetOrSet method instead. If you don't want to add a new entry if it doesn't exist, use the Replace method instead.

type DefaultStringHasher64 added in v0.2.0

type DefaultStringHasher64 struct{}

DefaultStringHasher64 is the default hasher for string keys. It uses the FNV-1a hash function.

func (DefaultStringHasher64) Sum64 added in v0.2.0

func (DefaultStringHasher64) Sum64(key string) uint64

Sum64 returns the 64-bit hash of the input key.

type EvictionCallback

type EvictionCallback[K comparable, V any] func(key K, val V, reason EvictionReason)

EvictionCallback is the callback function that is called when an entry is evicted.

type EvictionPolicy added in v1.2.0

type EvictionPolicy int32

EvictionPolicy represents the eviction policy.

const (
	// EvictionPolicyLRU is the least recently used eviction policy.
	EvictionPolicyLRU EvictionPolicy = iota + 1
	// EvictionPolicyLFU is the least frequently used eviction policy.
	EvictionPolicyLFU
	// EvictionPolicyRandom is the random eviction policy.
	// It evicts the entry randomly when the max entries limit exceeded.
	EvictionPolicyRandom
)

type EvictionReason

type EvictionReason int32

EvictionReason is the reason why an entry was evicted.

const (
	// EvictionReasonExpired indicates that the entry was evicted
	// because it expired.
	EvictionReasonExpired EvictionReason = iota + 1
	// EvictionReasonRemoved indicates that the entry was evicted
	// because it was removed.
	EvictionReasonRemoved
	// EvictionReasonReplaced indicates that the entry was evicted
	// because it was replaced.
	EvictionReasonReplaced
	// EvictionReasonMaxEntriesExceeded indicates that the entry was evicted
	// because the max entries limit was exceeded.
	//
	// imcache uses LRU eviction policy when the cache exceeds the max entries
	// limit. The least recently used entry is evicted regardless of the
	// entry's expiration time.
	EvictionReasonMaxEntriesExceeded
	// EvictionReasonKeyReplaced indicates that the entry was evicted
	// because the key was replaced.
	EvictionReasonKeyReplaced
)

func (EvictionReason) String added in v0.3.0

func (r EvictionReason) String() string

type Expiration

type Expiration interface {
	// contains filtered or unexported methods
}

Expiration is the expiration time of an entry.

func WithDefaultExpiration

func WithDefaultExpiration() Expiration

WithDefaultExpiration returns an Expiration that sets the expiration time to the default expiration time.

func WithExpiration

func WithExpiration(d time.Duration) Expiration

WithExpiration returns an Expiration that sets the expiration time to now + d.

func WithExpirationDate added in v0.4.0

func WithExpirationDate(t time.Time) Expiration

WithExpirationDate returns an Expiration that sets the expiration time to t.

func WithNoExpiration

func WithNoExpiration() Expiration

WithNoExpiration returns an Expiration that sets the expiration time to never expire.

func WithSlidingExpiration

func WithSlidingExpiration(d time.Duration) Expiration

WithSlidingExpiration returns an Expiration that sets the expiration time to now + d and sets the sliding expiration to d.

The sliding expiration is the time after which the entry is considered expired if it has not been accessed. If the entry has been accessed, the expiration time is reset to now + d where now is the time of the access.

type Hasher64 added in v0.2.0

type Hasher64[K comparable] interface {
	// Sum64 returns the 64-bit hash of the input key.
	Sum64(K) uint64
}

Hasher64 is the interface that wraps the Sum64 method.

type Number deprecated added in v0.5.0

type Number interface {
	~float32 | ~float64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr | ~int | ~int8 | ~int16 | ~int32 | ~int64
}

Number is a constraint that permits any numeric type except complex ones.

Deprecated: Number constraint is deprecated. It is easy to write your own constraint. imcache's goal is to be simple. Creating artificial types or functions that are not even needed conflicts with this goal.

type Option

type Option[K comparable, V any] interface {
	// contains filtered or unexported methods
}

Option configures the cache.

func WithCleanerOption added in v0.10.0

func WithCleanerOption[K comparable, V any](interval time.Duration) Option[K, V]

WithCleanerOption returns an Option that sets a cache cleaner that periodically removes expired entries from the cache.

A cleaner runs in a separate goroutine. It removes expired entries every interval. If the interval is less than or equal to zero, the cleaner is disabled.

A cleaner is stopped when the cache is closed.

func WithDefaultExpirationOption

func WithDefaultExpirationOption[K comparable, V any](d time.Duration) Option[K, V]

WithDefaultExpirationOption returns an Option that sets the cache default expiration.

func WithDefaultSlidingExpirationOption

func WithDefaultSlidingExpirationOption[K comparable, V any](d time.Duration) Option[K, V]

WithDefaultSlidingExpirationOption returns an Option that sets the cache default sliding expiration.

func WithEvictionCallbackOption

func WithEvictionCallbackOption[K comparable, V any](f EvictionCallback[K, V]) Option[K, V]

WithEvictionCallbackOption returns an Option that sets the cache eviction callback.

func WithMaxEntriesLimitOption added in v1.2.0

func WithMaxEntriesLimitOption[K comparable, V any](limit int, policy EvictionPolicy) Option[K, V]

WithMaxEntriesLimitOption returns an Option that sets the cache maximum number of entries. When the limit is exceeded, the entry is evicted according to the eviction policy.

If used with Sharded type, the maximum size is per shard, not the total size of all shards.

func WithMaxEntriesOption deprecated added in v0.8.0

func WithMaxEntriesOption[K comparable, V any](n int) Option[K, V]

WithMaxEntriesOption returns an Option that sets the cache maximum number of entries. When the maximum number of entries is exceeded, the entry is evicted according to the LRU eviction policy.

If used with Sharded type, the maximum size is per shard, not the total size of all shards.

Deprecated: Use WithMaxEntriesLimitOption instead.

type Sharded added in v0.7.0

type Sharded[K comparable, V any] struct {
	// contains filtered or unexported fields
}

Sharded is a sharded in-memory cache. It is a cache consisting of n shards and sharded by the given Hasher64.

Each shard is a separate Cache instance.

By default, it has no default expiration, no default sliding expiration no entry limit and no eviction callback.

The zero value Sharded is NOT ready to use. The NewSharded function must be used to create a new Sharded.

Example:

c := imcache.NewSharded[string, interface{}](8, imcache.DefaultStringHasher64{},
	imcache.WithDefaultExpirationOption[string, interface{}](time.Second),
	imcache.WithCleanerOption[string, interface{}](5*time.Minute),
	imcache.WithMaxEntriesOption[string, interface{}](10000),
	imcache.WithEvictionCallbackOption[string, interface{}](LogEvictedEntry),
)

func NewSharded

func NewSharded[K comparable, V any](n int, hasher Hasher64[K], opts ...Option[K, V]) *Sharded[K, V]

NewSharded returns a new Sharded instance. It panics if n is not greater than 0 or hasher is nil.

By default, a returned Sharded has no default expiration, no default sliding expiration, no entry limit and no eviction callback.

Option(s) can be used to customize the returned Sharded. Note that Option(s) are applied to each shard (Cache instance) not to the Sharded instance itself.

func (*Sharded[K, V]) Close added in v0.10.0

func (s *Sharded[K, V]) Close()

Close closes the cache. It purges all entries and stops the cleaner if it is running. After Close, all other methods are NOP returning zero values immediately.

It is safe to call Close multiple times.

It's not necessary to call Close if the cache is no longer referenced and there is no cleaner running. Garbage collector will collect the cache.

func (*Sharded[K, V]) CompareAndSwap added in v1.1.0

func (s *Sharded[K, V]) CompareAndSwap(key K, expected, new V, compare func(V, V) bool, exp Expiration) (swapped, present bool)

CompareAndSwap replaces the value for the given key if the current value is equal to the expected value.

Equality is defined by the given compare function.

If it encounters an expired entry, the expired entry is evicted.

func (*Sharded[K, V]) Get added in v0.7.0

func (s *Sharded[K, V]) Get(key K) (value V, present bool)

Get returns the value for the given key.

If it encounters an expired entry, the expired entry is evicted.

func (*Sharded[K, V]) GetAll added in v0.7.0

func (s *Sharded[K, V]) GetAll() map[K]V

GetAll returns a copy of all entries in the cache.

If it encounters an expired entry, the expired entry is evicted.

func (*Sharded[K, V]) GetMultiple added in v1.1.0

func (s *Sharded[K, V]) GetMultiple(keys ...K) map[K]V

GetMultiple returns the values for the given keys. If the Sharded is not closed, then the returned map is always a non-nil one.

If it encounters an expired entry, the expired entry is evicted.

func (*Sharded[K, V]) GetOrSet added in v0.7.0

func (s *Sharded[K, V]) GetOrSet(key K, val V, exp Expiration) (value V, present bool)

GetOrSet returns the value for the given key and true if it exists, otherwise it sets the value for the given key and returns the set value and false.

If it encounters an expired entry, the expired entry is evicted.

func (*Sharded[K, V]) Len added in v0.7.0

func (s *Sharded[K, V]) Len() int

Len returns the number of entries in the cache.

func (*Sharded[K, V]) Peek added in v1.2.0

func (s *Sharded[K, V]) Peek(key K) (V, bool)

Peek returns the value for the given key without actively evicting the entry if it is expired and updating the entry's sliding expiration.

If the max entries limit is set, it doesn't update the entry's position in the eviction queue.

func (*Sharded[K, V]) PeekAll added in v1.2.0

func (s *Sharded[K, V]) PeekAll() map[K]V

PeekAll returns a copy of all entries in the cache without actively evicting the encountered entry if it is expired and updating the entry's sliding expiration.

If the max entries limit is set, it doesn't update the encountered entry's position in the eviction queue.

func (*Sharded[K, V]) PeekMultiple added in v1.2.0

func (s *Sharded[K, V]) PeekMultiple(keys ...K) map[K]V

PeekMultiple returns the values for the given keys without actively evicting the encountered entry if it is expired and updating the entry's sliding expiration. If the Sharded is not closed, then the returned map is always a non-nil one.

If the max entries limit is set, it doesn't update the encountered entry's position in the eviction queue.

func (*Sharded[K, V]) Remove added in v0.7.0

func (s *Sharded[K, V]) Remove(key K) (present bool)

Remove removes the cache entry for the given key.

It returns true if the entry is present and removed, otherwise it returns false.

If it encounters an expired entry, the expired entry is evicted. It results in calling the eviction callback with EvictionReasonExpired, not EvictionReasonRemoved. If entry is expired, it returns false.

func (*Sharded[K, V]) RemoveAll added in v0.7.0

func (s *Sharded[K, V]) RemoveAll()

RemoveAll removes all entries.

If an eviction callback is set, it is called for each removed entry.

If it encounters an expired entry, the expired entry is evicted. It results in calling the eviction callback with EvictionReasonExpired, not EvictionReasonRemoved.

func (*Sharded[K, V]) RemoveExpired added in v0.9.0

func (s *Sharded[K, V]) RemoveExpired()

RemoveExpired removes all expired entries.

If an eviction callback is set, it is called for each removed entry.

func (*Sharded[K, V]) Replace added in v0.7.0

func (s *Sharded[K, V]) Replace(key K, val V, exp Expiration) (present bool)

Replace replaces the value for the given key. It returns true if the value is present and replaced, otherwise it returns false.

If it encounters an expired entry, the expired entry is evicted.

If you want to add or replace an entry, use the Set method instead.

func (*Sharded[K, V]) ReplaceKey added in v0.11.0

func (s *Sharded[K, V]) ReplaceKey(old, new K, exp Expiration) (present bool)

ReplaceKey replaces the given old key with the new key. The value remains the same. It returns true if the key is present and replaced, otherwise it returns false. If there is an existing entry for the new key, it is replaced.

If it encounters an expired entry, the expired entry is evicted.

func (*Sharded[K, V]) ReplaceWithFunc added in v0.7.0

func (s *Sharded[K, V]) ReplaceWithFunc(key K, fn func(V) V, exp Expiration) (present bool)

ReplaceWithFunc replaces the value for the given key with the result of the given function that takes the old value as an argument. It returns true if the value is present and replaced, otherwise it returns false.

If it encounters an expired entry, the expired entry is evicted.

If you want to replace the value with a new value not depending on the old value, use the Replace method instead.

imcache provides the Increment and Decrement functions that can be used as f to increment or decrement the old numeric type value.

Example:

c := imcache.NewSharded[string, int32](4, imcache.DefaultStringHasher64{})
c.Set("foo", 997, imcache.WithNoExpiration())
_ = c.ReplaceWithFunc("foo", imcache.Increment[int32], imcache.WithNoExpiration())

func (*Sharded[K, V]) Set added in v0.7.0

func (s *Sharded[K, V]) Set(key K, val V, exp Expiration)

Set sets the value for the given key. If the entry already exists, it is replaced.

If it encounters an expired entry, it is evicted and a new entry is added.

If you don't want to replace an existing entry, use the GetOrSet method instead. If you don't want to add a new entry if it doesn't exist, use the Replace method instead.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL