TTLCache

具有项目过期和泛型功能的内存缓存。「An in-memory cache with item expiration and generics」

Github星跟蹤圖

TTLCache - an in-memory cache with item expiration and generics

Go Reference
Build Status
Coverage Status
Go Report Card

Features

  • Simple API
  • Type parameters
  • Item expiration and automatic deletion
  • Automatic expiration time extension on each Get call
  • Loader interface that may be used to load/lazily initialize missing cache items
  • Thread safety
  • Event handlers (insertion, update, and eviction)
  • Metrics

Installation

go get github.com/jellydator/ttlcache/v3

Status

The ttlcache package is stable and used by Jellydator,
as well as thousands of other projects and organizations in production.

Usage

The main type of ttlcache is Cache. It represents a single
in-memory data store.

To create a new instance of ttlcache.Cache, the ttlcache.New() function
should be called:

func main() {
	cache := ttlcache.New[string, string]()
}

Note that by default, a new cache instance does not let any of its
items to expire or be automatically deleted. However, this feature
can be activated by passing a few additional options into the
ttlcache.New() function and calling the cache.Start() method:

func main() {
	cache := ttlcache.New[string, string](
		ttlcache.WithTTL[string, string](30 * time.Minute),
	)

	go cache.Start() // starts automatic expired item deletion
}

Even though the cache.Start() method handles expired item deletion well,
there may be times when the system that uses ttlcache needs to determine
when to delete the expired items itself. For example, it may need to
delete them only when the resource load is at its lowest (e.g., after
midnight, when the number of users/HTTP requests drops). So, in situations
like these, instead of calling cache.Start(), the system could
periodically call cache.DeleteExpired():

func main() {
	cache := ttlcache.New[string, string](
		ttlcache.WithTTL[string, string](30 * time.Minute),
	)

	for {
		time.Sleep(4 * time.Hour)
		cache.DeleteExpired()
	}
}

The data stored in ttlcache.Cache can be retrieved, checked and updated with
Set, Get, Delete, Has etc. methods:

func main() {
	cache := ttlcache.New[string, string](
		ttlcache.WithTTL[string, string](30 * time.Minute),
	)

	// insert data
	cache.Set("first", "value1", ttlcache.DefaultTTL)
	cache.Set("second", "value2", ttlcache.NoTTL)
	cache.Set("third", "value3", ttlcache.DefaultTTL)

	// retrieve data
	item := cache.Get("first")
	fmt.Println(item.Value(), item.ExpiresAt())

	// check key 
	ok := cache.Has("third")
	
	// delete data
	cache.Delete("second")
	cache.DeleteExpired()
	cache.DeleteAll()

	// retrieve data if in cache otherwise insert data
	item, retrieved := cache.GetOrSet("fourth", "value4", WithTTL[string, string](ttlcache.DefaultTTL))

	// retrieve and delete data
	item, present := cache.GetAndDelete("fourth")
}

To subscribe to insertion, update and eviction events, cache.OnInsertion(), cache.OnUpdate() and
cache.OnEviction() methods should be used:

func main() {
	cache := ttlcache.New[string, string](
		ttlcache.WithTTL[string, string](30 * time.Minute),
		ttlcache.WithCapacity[string, string](300),
	)

	cache.OnInsertion(func(ctx context.Context, item *ttlcache.Item[string, string]) {
		fmt.Println(item.Value(), item.ExpiresAt())
	})
	cache.OnUpdate(func(ctx context.Context, item *ttlcache.Item[string, string]) {
		fmt.Println(item.Value(), item.ExpiresAt())
	})
	cache.OnEviction(func(ctx context.Context, reason ttlcache.EvictionReason, item *ttlcache.Item[string, string]) {
		if reason == ttlcache.EvictionReasonCapacityReached {
			fmt.Println(item.Key(), item.Value())
		}
	})

	cache.Set("first", "value1", ttlcache.DefaultTTL)
	cache.DeleteAll()
}

To load data when the cache does not have it, a custom or
existing implementation of ttlcache.Loader can be used:

func main() {
	loader := ttlcache.LoaderFunc[string, string](
		func(c *ttlcache.Cache[string, string], key string) *ttlcache.Item[string, string] {
			// load from file/make an HTTP request
			item := c.Set("key from file", "value from file")
			return item
		},
	)
	cache := ttlcache.New[string, string](
		ttlcache.WithLoader[string, string](loader),
	)

	item := cache.Get("key from file")
}

To restrict the cache's capacity based on criteria beyond the number
of items it can hold, the ttlcache.WithMaxCost option allows for
implementing custom strategies. The following example shows how to limit
memory usage for cached entries to ~5KiB.

import (
    "github.com/jellydator/ttlcache"
)

func main() {
    cache := ttlcache.New[string, string](
        ttlcache.WithMaxCost[string, string](5120, func(item ttlcache.CostItem[string, string]) uint64 {
            // Note: The below line doesn't include memory used by internal
            // structures or string metadata for the key and the value.
            return len(item.Key) + len(item.Value)
        }), 
    )

    cache.Set("first", "value1", ttlcache.DefaultTTL)
}

Examples & Tutorials

See the example
directory for applications demonstrating how to use ttlcache.

If you want to learn and follow along as these example applications are
built, check out the tutorials below:

主要指標

概覽
名稱與所有者jellydator/ttlcache
主編程語言Go
編程語言Go (語言數: 1)
平台
許可證MIT License
所有者活动
創建於2014-12-13 01:55:40
推送於2025-06-17 18:34:57
最后一次提交2024-02-19 17:00:56
發布數34
最新版本名稱v3.4.0 (發布於 )
第一版名稱1.0.0 (發布於 2015-05-27 21:48:28)
用户参与
星數1.1k
關注者數14
派生數128
提交數251
已啟用問題?
問題數95
打開的問題數9
拉請求數67
打開的拉請求數4
關閉的拉請求數13
项目设置
已啟用Wiki?
已存檔?
是復刻?
已鎖定?
是鏡像?
是私有?