package
1.0.6
Repository: https://github.com/zeb-d/go-util.git
Documentation: pkg.go.dev

# README

Cache

Golang缓存库,基于lru做特性增强,支持设定过期缓存,LFU, LRU, ARC, Simple等缓存算法实现。 同时也参考了GCache部分源码

特性

  • 支持设定缓存失效时间:LFU, LRU and ARC;

  • 支持协程安全;

  • 支持监听缓存事件:evict, purge, added;(可选特性)

  • 支持全局Loader自动加载不存在的键值;(可选特性)

  • 支持外部化指定Loader加载不存在的键值;(通过GetOrLoad

安装

$ go get github.com/Zeb-D/go-util

示例

手动设定Key-Value键值对

package main

import (
  "github.com/Zeb-D/go-util/cache"
  "fmt"
)

func main() {
  gc := cache.New(20).
    LRU().
    Build()
  gc.Set("key", "ok")
  value, err := gc.Get("key")
  if err != nil {
    panic(err)
  }
  fmt.Println("Get:", value)
}
Get: ok

手动设定Key-Value键值对,指定缓存失效时间

package main

import (
  "github.com/Zeb-D/go-util/cache"
  "fmt"
  "time"
)

func main() {
  gc := cache.New(20).
    LRU().
    Build()
  gc.SetWithExpire("key", "ok", time.Second*10)
  value, _ := gc.Get("key")
  fmt.Println("Get:", value)

  // Wait for value to expire
  time.Sleep(time.Second*10)

  value, err = gc.Get("key")
  if err != nil {
    panic(err)
  }
  fmt.Println("Get:", value)
}
Get: ok
// 10 seconds later, new attempt:
panic: ErrKeyNotFound

全局Loader加载不存在的键值

package main

import (
  "github.com/Zeb-D/go-util/cache"
  "fmt"
)

func main() {
  gc := cache.New(20).
    LRU().
    LoaderFunc(func(key interface{}) (interface{}, error) {
      return "ok", nil
    }).
    Build()
  value, err := gc.Get("key")
  if err != nil {
    panic(err)
  }
  fmt.Println("Get:", value)
}
Get: ok

外部化指定Loader加载不存在的键值

package main

import (
  "github.com/Zeb-D/go-util/cache"
  "fmt"
  "time"
)

func main() {
  gc := cache.New(20).
    LRU().
    Build()
  value, err := gc.GetOrLoad("key",func(key interface{}) (cache.Expirable, error) {
    return cache.NewDefault("my-new-value"), nil
  })
  if err != nil {
    panic(err)
  }
  fmt.Println("Get:", value)
}
Get: by-loader

全局Loader加载不存在的键值,并指定缓存失效时间

package main

import (
  "fmt"
  "time"

  "github.com/Zeb-D/go-util/cache"
)

func main() {
  var evictCounter, loaderCounter, purgeCounter int
  gc := cache.New(20).
    LRU().
    LoaderExpireFunc(func(key interface{}) (cache.Expirable, error) {
      loaderCounter++
      return cache.NewExpirable("ok", time.Second*5), nil
    }).
    EvictedFunc(func(key, value interface{}) {
      evictCounter++
      fmt.Println("evicted key:", key)
    }).
    PurgeVisitorFunc(func(key, value interface{}) {
      purgeCounter++
      fmt.Println("purged key:", key)
    }).
    Build()
  value, err := gc.Get("key")
  if err != nil {
    panic(err)
  }
  fmt.Println("Get:", value)
  time.Sleep(1 * time.Second)
  value, err = gc.Get("key")
  if err != nil {
    panic(err)
  }
  fmt.Println("Get:", value)
  gc.Purge()
  if loaderCounter != evictCounter+purgeCounter {
    panic("bad")
  }
}
Get: ok
evicted key: key
Get: ok
purged key: key

缓存算法

  • Least-Frequently Used (LFU)

Discards the least frequently used items first.

func main() {
  // size: 10
  gc := cache.New(10).
    LFU().
    Build()
  gc.Set("key", "value")
}
  • Least Recently Used (LRU)

Discards the least recently used items first.

func main() {
  // size: 10
  gc := cache.New(10).
    LRU().
    Build()
  gc.Set("key", "value")
}
  • Adaptive Replacement Cache (ARC)

Constantly balances between LRU and LFU, to improve the combined result.

detail: http://en.wikipedia.org/wiki/Adaptive_replacement_cache

func main() {
  // size: 10
  gc := cache.New(10).
    ARC().
    Build()
  gc.Set("key", "value")
}
  • SimpleCache (Default)

SimpleCache has no clear priority for evict cache. It depends on key-value map order.

func main() {
  // size: 10
  gc := cache.New(10).Build()
  gc.Set("key", "value")
  v, err := gc.Get("key")
  if err != nil {
    panic(err)
  }
}

Loading Cache

If specified LoaderFunc, values are automatically loaded by the cache, and are stored in the cache until either evicted or manually invalidated.

func main() {
  gc := cache.New(10).
    LRU().
    LoaderFunc(func(key interface{}) (interface{}, error) {
      return "value", nil
    }).
    Build()
  v, _ := gc.Get("key")
  // output: "value"
  fmt.Println(v)
}

GCache coordinates cache fills such that only one load in one process of an entire replicated set of processes populates the cache, then multiplexes the loaded value to all callers.

Expirable cache

func main() {
  // LRU cache, size: 10, expiration: after a hour
  gc := cache.New(10).
    LRU().
    Expiration(time.Hour).
    Build()
}

事件处理

Evicted handler

Event handler for evict the entry.

func main() {
  gc := cache.New(2).
    EvictedFunc(func(key, value interface{}) {
      fmt.Println("evicted key:", key)
    }).
    Build()
  for i := 0; i < 3; i++ {
    gc.Set(i, i*i)
  }
}
evicted key: 0

Added handler

Event handler for add the entry.

func main() {
  gc := cache.New(2).
    AddedFunc(func(key, value interface{}) {
      fmt.Println("added key:", key)
    }).
    Build()
  for i := 0; i < 3; i++ {
    gc.Set(i, i*i)
  }
}
added key: 0
added key: 1
added key: 2

Authors

Yd 2022 - 2023

Jun Kimura @2019

# Packages

No description provided by the author
No description provided by the author

# Functions

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author

# Constants

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author

# Variables

No description provided by the author
No description provided by the author

# Structs

ARC Constantly balances between LRU and LFU, to improve the combined result.
No description provided by the author
No description provided by the author
No description provided by the author
Group represents a class of work and forms a namespace in which units of work can be executed with duplicate suppression.
LFUCache Discards the least frequently used items first.
LRUCache Discards the least recently used items first.
No description provided by the author
SimpleCache has no clear priority for evict cache.

# Interfaces

No description provided by the author
No description provided by the author
No description provided by the author

# Type aliases

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author