一、下载源码
在github上,地址github.com/allegro/bigcache,我们可以把代码源码clone到本地。
这里选择分支v3.1.0的代码。
二、源码目录
我们打开源码
.
├── LICENSE
├── README.md
├── assert_test.go
├── bigcache.go
├── bigcache_bench_test.go
├── bigcache_test.go
├── bytes.go
├── bytes_appengine.go
├── clock.go
├── config.go
├── encoding.go
├── encoding_test.go
├── entry_not_found_error.go
├── examples_test.go
├── fnv.go
├── fnv_bench_test.go
├── fnv_test.go
├── go.mod
├── go.sum
├── hash.go
├── hash_test.go
├── iterator.go
├── iterator_test.go
├── logger.go
├── queue
│ ├── bytes_queue.go
│ └── bytes_queue_test.go
├── server
│ ├── README.md
│ ├── cache_handlers.go
│ ├── middleware.go
│ ├── middleware_test.go
│ ├── server.go
│ ├── server_test.go
│ └── stats_handler.go
├── shard.go
├── stats.go
└── utils.go
2 directories, 36 files
比较重要的几个文件
queue目录
shard.go 分片
fnv.go Fnv hash算法
bigcache.go 初始化new结构体,以及set,get方法。
我们可以看上篇文档的示例:
func TestSetGet(t *testing.T) {
// new一个bigCache对象
cache, _ := bigcache.New(context.Background(), bigcache.DefaultConfig(10*time.Minute))
// get获取一个无值的key
vNil, err := cache.Get("key")
t.Log(vNil, err) // [] Entry not found 值为空的[]字节slice
// set 存储数据
cache.Set("key", []byte("value"))
// get 获取数据
v, _ := cache.Get("key")
t.Log(v) // 输出 [118 97 108 117 101]
t.Log(string(v)) // 输出 value
}
那么我们先找到这个
第一行对应的
cache, _ := bigcache.New(context.Background(), bigcache.DefaultConfig(10*time.Minute))
在源码的代码如下:
// New initialize new instance of BigCache
// New用来初始化一个新的BigCache实例。
func New(ctx context.Context, config Config) (*BigCache, error) {
return newBigCache(ctx, config, &systemClock{})
}
我们在使用的时候,主要又涉及到一个 bigcache.DefaultConfig(10*time.Minute))
我们看一下他的方法:
// DefaultConfig initializes config with default values.
// DefaultConfig 初始化Config,给定默认值。
// When load for BigCache can be predicted in advance then it is better to use custom config.
// 当load加载 BigCache 的时候,如果在使用之前就能预估到使用量,然后预设置config,它好于使用默认config。
func DefaultConfig(eviction time.Duration) Config {
return Config{
Shards: 1024,
LifeWindow: eviction,
CleanWindow: 1 * time.Second,
MaxEntriesInWindow: 1000 * 10 * 60,
MaxEntrySize: 500,
StatsEnabled: false,
Verbose: true,
Hasher: newDefaultHasher(),
HardMaxCacheSize: 0,
Logger: DefaultLogger(),
}
}
这里设计一个 Config 结构体
// Config for BigCache
type Config struct {
// Number of cache shards, value must be a power of two
Shards int
// Time after which entry can be evicted
// LifeWindow后,缓存对象被认为不活跃,但并不会删除对象
LifeWindow time.Duration
// Interval between removing expired entries (clean up).
// If set to <= 0 then no action is performed. Setting to < 1 second is counterproductive — bigcache has a one second resolution.
// CleanWindow后,会删除被认为不活跃的对象(超过LifeWindow时间的对象),0代表不操作;
CleanWindow time.Duration
// Max number of entries in life window. Used only to calculate initial size for cache shards.
// When proper value is set then additional memory allocation does not occur.
// 设置最大存储对象数量,仅在初始化时可以设置
MaxEntriesInWindow int
// Max size of entry in bytes. Used only to calculate initial size for cache shards.
// 缓存对象的最大字节数,仅在初始化时可以设置
MaxEntrySize int
// StatsEnabled if true calculate the number of times a cached resource was requested.
StatsEnabled bool
// Verbose mode prints information about new memory allocation
// 是否打印内存分配信息
Verbose bool
// Hasher used to map between string keys and unsigned 64bit integers, by default fnv64 hashing is used.
Hasher Hasher
// HardMaxCacheSize is a limit for BytesQueue size in MB.
// It can protect application from consuming all available memory on machine, therefore from running OOM Killer.
// Default value is 0 which means unlimited size. When the limit is higher than 0 and reached then
// the oldest entries are overridden for the new ones. The max memory consumption will be bigger than
// HardMaxCacheSize due to Shards' s additional memory. Every Shard consumes additional memory for map of keys
// and statistics (map[uint64]uint32) the size of this map is equal to number of entries in
// cache ~ 2×(64+32)×n bits + overhead or map itself.
// 设置缓存最大值(单位为MB),0表示无限制
HardMaxCacheSize int
// OnRemove is a callback fired when the oldest entry is removed because of its expiration time or no space left
// for the new entry, or because delete was called.
// Default value is nil which means no callback and it prevents from unwrapping the oldest entry.
// ignored if OnRemoveWithMetadata is specified.
// 在缓存过期或者被删除时,可设置回调函数,参数是(key、val),默认是nil不设置
OnRemove func(key string, entry []byte)
// OnRemoveWithMetadata is a callback fired when the oldest entry is removed because of its expiration time or no space left
// for the new entry, or because delete was called. A structure representing details about that specific entry.
// Default value is nil which means no callback and it prevents from unwrapping the oldest entry.
OnRemoveWithMetadata func(key string, entry []byte, keyMetadata Metadata)
// OnRemoveWithReason is a callback fired when the oldest entry is removed because of its expiration time or no space left
// for the new entry, or because delete was called. A constant representing the reason will be passed through.
// Default value is nil which means no callback and it prevents from unwrapping the oldest entry.
// Ignored if OnRemove is specified.
// 在缓存过期或者被删除时,可设置回调函数,参数是(key、val,reason)默认是nil不设置
OnRemoveWithReason func(key string, entry []byte, reason RemoveReason)
onRemoveFilter int
// Logger is a logging interface and used in combination with `Verbose`
// Defaults to `DefaultLogger()`
Logger Logger
}
BigCache的实现是 一种索引和数据分离的多阶hash。
主索引(多阶hash数组)的value保存的是在数据段的位置,通过二次定位拿到某个key对应的真实的value。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。