设计思路
- 定义缓存策略接口:为不同的缓存策略(如LRU、LFU)定义统一的接口,每个策略实现该接口。
- 定义存储后端接口:为不同的存储后端(如内存、文件系统、Redis)定义统一的接口,每个后端实现该接口。
- 缓存系统结构体:创建一个缓存系统结构体,该结构体包含缓存策略和存储后端的实例,通过组合方式实现可插拔。
关键代码框架
// 缓存策略接口
type CachePolicy interface {
Add(key, value interface{})
Get(key interface{}) (interface{}, bool)
Remove(key interface{})
}
// LRU缓存策略实现
type LRUCache struct {
capacity int
cache map[interface{}]*list.Element
lruList *list.List
}
type lruEntry struct {
key interface{}
value interface{}
}
func NewLRUCache(capacity int) *LRUCache {
return &LRUCache{
capacity: capacity,
cache: make(map[interface{}]*list.Element),
lruList: list.New(),
}
}
func (lru *LRUCache) Add(key, value interface{}) {
if elem, ok := lru.cache[key]; ok {
lru.lruList.MoveToFront(elem)
elem.Value.(*lruEntry).value = value
return
}
newEntry := &lruEntry{key, value}
elem := lru.lruList.PushFront(newEntry)
lru.cache[key] = elem
if lru.lruList.Len() > lru.capacity {
lru.Remove(lru.lruList.Back().Value.(*lruEntry).key)
}
}
func (lru *LRUCache) Get(key interface{}) (interface{}, bool) {
if elem, ok := lru.cache[key]; ok {
lru.lruList.MoveToFront(elem)
return elem.Value.(*lruEntry).value, true
}
return nil, false
}
func (lru *LRUCache) Remove(key interface{}) {
if elem, ok := lru.cache[key]; ok {
lru.lruList.Remove(elem)
delete(lru.cache, key)
}
}
// LFU缓存策略实现
type LFUCache struct {
capacity int
cache map[interface{}]*lfuEntry
freqMap map[int]*list.List
minFreq int
}
type lfuEntry struct {
key interface{}
value interface{}
freq int
listElem *list.Element
}
func NewLFUCache(capacity int) *LFUCache {
return &LFUCache{
capacity: capacity,
cache: make(map[interface{}]*lfuEntry),
freqMap: make(map[int]*list.List),
minFreq: 0,
}
}
func (lfu *LFUCache) Add(key, value interface{}) {
if entry, ok := lfu.cache[key]; ok {
lfu.freqMap[entry.freq].Remove(entry.listElem)
if lfu.freqMap[entry.freq].Len() == 0 {
delete(lfu.freqMap, entry.freq)
if entry.freq == lfu.minFreq {
lfu.minFreq++
}
}
entry.value = value
entry.freq++
if _, ok := lfu.freqMap[entry.freq];!ok {
lfu.freqMap[entry.freq] = list.New()
}
entry.listElem = lfu.freqMap[entry.freq].PushFront(entry)
lfu.cache[key] = entry
return
}
newEntry := &lfuEntry{key, value, 1, nil}
if _, ok := lfu.freqMap[1];!ok {
lfu.freqMap[1] = list.New()
}
newEntry.listElem = lfu.freqMap[1].PushFront(newEntry)
lfu.cache[key] = newEntry
lfu.minFreq = 1
if len(lfu.cache) > lfu.capacity {
lfu.removeOldest()
}
}
func (lfu *LFUCache) Get(key interface{}) (interface{}, bool) {
if entry, ok := lfu.cache[key]; ok {
lfu.freqMap[entry.freq].Remove(entry.listElem)
if lfu.freqMap[entry.freq].Len() == 0 {
delete(lfu.freqMap, entry.freq)
if entry.freq == lfu.minFreq {
lfu.minFreq++
}
}
entry.freq++
if _, ok := lfu.freqMap[entry.freq];!ok {
lfu.freqMap[entry.freq] = list.New()
}
entry.listElem = lfu.freqMap[entry.freq].PushFront(entry)
lfu.cache[key] = entry
return entry.value, true
}
return nil, false
}
func (lfu *LFUCache) Remove(key interface{}) {
if entry, ok := lfu.cache[key]; ok {
lfu.freqMap[entry.freq].Remove(entry.listElem)
if lfu.freqMap[entry.freq].Len() == 0 {
delete(lfu.freqMap, entry.freq)
if entry.freq == lfu.minFreq {
lfu.minFreq++
}
}
delete(lfu.cache, key)
}
}
func (lfu *LFUCache) removeOldest() {
l := lfu.freqMap[lfu.minFreq]
entry := l.Back().Value.(*lfuEntry)
l.Remove(l.Back())
if l.Len() == 0 {
delete(lfu.freqMap, lfu.minFreq)
}
delete(lfu.cache, entry.key)
}
// 存储后端接口
type StorageBackend interface {
Get(key interface{}) (interface{}, bool)
Set(key, value interface{})
Delete(key interface{})
}
// 内存存储后端实现
type InMemoryStorage struct {
data map[interface{}]interface{}
}
func NewInMemoryStorage() *InMemoryStorage {
return &InMemoryStorage{
data: make(map[interface{}]interface{}),
}
}
func (im *InMemoryStorage) Get(key interface{}) (interface{}, bool) {
value, ok := im.data[key]
return value, ok
}
func (im *InMemoryStorage) Set(key, value interface{}) {
im.data[key] = value
}
func (im *InMemoryStorage) Delete(key interface{}) {
delete(im.data, key)
}
// 分布式缓存系统
type DistributedCache struct {
policy CachePolicy
backend StorageBackend
}
func NewDistributedCache(policy CachePolicy, backend StorageBackend) *DistributedCache {
return &DistributedCache{
policy: policy,
backend: backend,
}
}
func (dc *DistributedCache) Get(key interface{}) (interface{}, bool) {
if value, ok := dc.policy.Get(key); ok {
return value, ok
}
if value, ok := dc.backend.Get(key); ok {
dc.policy.Add(key, value)
return value, ok
}
return nil, false
}
func (dc *DistributedCache) Set(key, value interface{}) {
dc.policy.Add(key, value)
dc.backend.Set(key, value)
}
func (dc *DistributedCache) Delete(key interface{}) {
dc.policy.Remove(key)
dc.backend.Delete(key)
}