cache

package module
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Mar 16, 2020 License: Apache-2.0 Imports: 3 Imported by: 7

README

📝 cachego

License

cachego 是一个轻量级内存型并支持链式编程的缓存组件,拥有懒清理和哨兵清理两种机制,可以应用于所有的 GoLang 应用程序中。

Read me in English.

🥇 功能特性
  • 以键值对形式缓存数据,并发访问安全,支持自动清理过期数据
  • 基础特性和高级特性分离设计模式,减少新用户学习上手难度
  • 链式编程友好的 API 设计,在一定程度上提供了很高的代码可读性
  • 支持懒清理机制,每一次访问的时候判断是否过期
  • 支持哨兵清理机制,每隔一定的时间间隔进行清理过期数据
  • 支持内存大小限制,防止无上限的使用内存(开发中)
  • 支持缓存个数限制,防止数据量太多导致哈希性能下降(开发中)
  • 支持用户自定义达到内存限制时的处理策略(开发中)
  • 支持用户自定义达到个数限制时的处理策略(开发中)
  • 使用更细粒度的分段锁机制保证更高的缓存性能(开发中)

历史版本的特性请查看 HISTORY.md。未来版本的新特性和计划请查看 FUTURE.md

🚀 安装方式

唯一需要的依赖就是 Golang 运行环境.

Go modules

$ go get -u github.com/FishGoddess/cachego

您也可以直接编辑 go.mod 文件,然后执行 go build

module your_project_name

go 1.14

require (
    github.com/FishGoddess/cachego v0.0.1
)

Go path

$ go get -u github.com/FishGoddess/cachego

cachego 没有任何其他额外的依赖,纯使用 Golang 标准库 完成。

package main

import (
    "fmt"
    "time"

    cache "github.com/FishGoddess/cachego"
)

func main() {

    // Create a cache with default gc duration (10 minutes).
    newCache := cache.NewCache()

    // Put a new entry in cache.
    // This entry will be dead after 5 seconds.
    // However, it will be deleted after 10 minutes if you never access.
    newCache.Put("key", 666, 5 * time.Second)

    // Of returns the value of this key.
    // As you know, this is chain-programming api.
    // If you need int type, just call Int().
    v := newCache.Of("key").Int()
    fmt.Println(v) // Output: 666

    // If you want change the value of key, try this:
    newCache.Change("key", "value")

    // Then you can call String() behind Of().
    s := newCache.Of("key").String()
    fmt.Println(s) // Output: value

    // After 5 seconds, this entry will dead, then an invalidCacheValue will be returned.
    time.Sleep(5 * time.Second)
    ok := newCache.Of("key").Ok()
    fmt.Println(ok) // Output: false

    // Maybe you want a default value for some situations, such as the code above.
    // Use Or() to help you to do that:
    s = newCache.Of("key").Or("default value").String()
    fmt.Println(s) // Output: default value
}
📖 参考案例
  • 开发中...

更多使用案例请查看 _examples 目录。

🔥 性能测试
$ go test -v ./_examples/benchmarks_test.go -bench=. -benchtime=12s

测试文件:_examples/benchmarks_test.go

写入缓存和读取缓存并发进行,将缓存 GC 时间设置为 5 秒/次,总缓存数据为 100 万条

测试 单位时间内运行次数 (越大越好) 每个操作消耗时间 (越小越好) 功能性 扩展性
cachego 127152241 104 ns/op 强大
freeCache 132629332 107 ns/op 正常 正常
go-cache 276515510   44 ns/op 正常 正常

测试环境:I7-6700HQ CPU @ 2.6 GHZ,16 GB RAM

注意:

  1. freeCache 的过期时间远大于 cachego 和 go-cache,也就意味着单次 GC 的量要少得多, 所以这个结果应该是偏好的,实际生产环境可能要更差(个人想法)。
👥 贡献者

如果您觉得 cachego 缺少您需要的功能,请不要犹豫,马上参与进来,发起一个 issue

📦 使用 cachego 的项目
项目 作者 描述

Documentation

Overview

Package cache provides an easy way to use foundation for your caching operations.

1. the basic usage:

// Create a cache with default gc duration (10 minutes).
newCache := cache.NewCache()

// Put a new entry in cache.
// This entry will be dead after 5 seconds.
// However, it will be deleted after 10 minutes if you never access.
newCache.Put("key", 666, 5*time.Second)

// Of returns the value of this key.
// As you know, this is chain-programming api.
// If you need int type, just call Int().
v := newCache.Of("key").Int()
fmt.Println(v) // Output: 666

// If you want change the value of key, try this:
newCache.Change("key", "value")

// Then you can call String() behind Of().
s := newCache.Of("key").String()
fmt.Println(s) // Output: value

// After 5 seconds, this entry will dead, then an invalidCacheValue will be returned.
time.Sleep(5 * time.Second)
ok := newCache.Of("key").Ok()
fmt.Println(ok) // Output: false

// Maybe you want a default value for some situations, such as the code above.
// Use Or() to help you to do that:
s = newCache.Of("key").Or("default value").String()
fmt.Println(s) // Output: default value

2. cache value usage:

// Create a cache with default gc duration (10 minutes).
newCache := cache.NewCache()

// Put a new entry in cache.
// This entry will be dead after 5 seconds.
// However, it will be deleted after 10 minutes if you never access.
newCache.Put("key", 666, 5*time.Second)

// Of returns the value of this key.
// As you know, this is chain-programming api.
// If you need int type, just call Int().
v := newCache.Of("key").Int()
fmt.Println(v) // Output: 666

// If you need another type like string, just call String().
// But you should know, this is not gonna work because the value is int
// type in fact, so it will return "".
nilStr := newCache.Of("key").String()
fmt.Printf("%q\n", nilStr) // Output: ""

// Sometimes you don't know the real type of value, and you try to
// convert to some type, try this:
// TryXxx returns two results (value, ok or not). If ok, this value will be valid.
nilFloat32, ok := newCache.Of("key").TryFloat32()
fmt.Println(nilFloat32, ok) // Output: 0 false

// Of cause, there are more functions for other type:
newCache.Of("key").Int8()
newCache.Of("key").Int16()
newCache.Of("key").Int32()
newCache.Of("key").Int64()
newCache.Of("key").Float32()
newCache.Of("key").Float64()
newCache.Of("key").String()
newCache.Of("key").TryInt8()
newCache.Of("key").TryInt16()
newCache.Of("key").TryInt32()
newCache.Of("key").TryInt64()
newCache.Of("key").TryFloat32()
newCache.Of("key").TryFloat64()
newCache.Of("key").TryString()

// Of cause, we have the most original method Value() for you to get the value.
value, ok := newCache.Of("key").Value()
fmt.Println(value, ok) // Output: 666 true

// There are some functions for you to get info of value:
ok = newCache.Of("key").Ok()      // Return true if this value is valid.
dead := newCache.Of("key").Dead() // Return true if this value is dead.
life := newCache.Of("key").Life() // Return the remained life of this value.
fmt.Println(ok, dead, life)       // Output: true false 4.9990022s

Index

Constants

View Source
const (
	// NeverDie means this value will not be dead (cleaned up by gc).
	NeverDie = time.Duration(0)
)
View Source
const Version = "v0.0.1"

Version is the version string representation of cachego.

Variables

This section is empty.

Functions

func InvalidCacheValue

func InvalidCacheValue() *cacheValue

InvalidCacheValue returns an invalid cache value.

func NewCacheValue

func NewCacheValue(value interface{}, life time.Duration) *cacheValue

NewCacheValue returns a new cache value including real cached value and its life.

Types

type AdvancedCache

type AdvancedCache interface {

	// Cache means an AdvancedCache implement also has the features of basic cache.
	Cache

	// Size returns the size of current cache.
	Size() int

	// Dump is for endurance, however, it is still a question that
	// this feature is beWorth?
	Dump(w io.Writer)
}

AdvancedCache is a Cache interface with advanced features. Maybe you are confused for why cachego has two interfaces representation of cache, but you should know that some features is for some people, not for everyone. So splitting a complex interface into two lightweight interfaces is better. For example, some people just need a basic cache for speeding up their data-access process, so they use Cache interface is enough. However, some people need more advanced features like endurance, so they need a more advanced cache interface to do that. This is an isolation measure for basic users and advanced users.

type Cache

type Cache interface {

	// Of returns the value of this key.
	Of(key string) *cacheValue

	// Put stores an entry (key, value) to cache, and sets the life of this entry.
	Put(key string, value interface{}, life time.Duration)

	// Change changes the value of key to newValue.
	// If this key is not existed, nothing will happen.
	Change(key string, newValue interface{})

	// Remove removes the value of key.
	// If this key is not existed, nothing will happen.
	Remove(key string)

	// RemoveAll is for removing all data in cache.
	RemoveAll()

	// Gc is for cleaning up dead data.
	// Notice that this method will take lots of time to remove all dead data
	// if there are many entries in cache. So it is not recommended to call Gc()
	// manually. Let cachego do this automatically will be better.
	Gc()

	// Extend returns a cache instance with advanced features.
	// Notice that this method is for extension, so implement it is not required.
	// You can just return a nil in method body.
	Extend() AdvancedCache
}

Cache is an interface representation of one kind cache. In cachego, StandardCache is the only implement of this interface right now. However, this interface is not just for cachego. It is for everyone. Maybe you are using cachego and StandardCache, but someday your project may have more cached data and need higher performance even distributed cache. We don't want you to be bother with cachego, so one recommended way to use cachego is to use cache interface in code. You just need an implement of another cache.

func NewCache

func NewCache() Cache

NewCache Returns a cache implemented AdvancedCache interface. Notice that default gc duration is ten minutes. The gc duration will affect the performance of cache, so do not set it too small.

func NewCacheWithGcDuration

func NewCacheWithGcDuration(gcDuration time.Duration) Cache

NewCacheWithGcDuration Returns a cache implemented AdvancedCache interface. The gc duration will affect the performance of cache, so do not set it too small.

type StandardCache

type StandardCache struct {
	// contains filtered or unexported fields
}

StandardCache is a standard cache implements AdvancedCache interface. It is a k-v entry cache that stores in memory. Actually, this cache is a concurrency-safe map essentially. That means it can be visited with many goroutines at the same time. More than a map does, It keeps a background task that removes all dead key and value, also, you can call Gc() manually to invoke this clean up process.

func (*StandardCache) Change

func (sc *StandardCache) Change(key string, newValue interface{})

Change changes the value of key to newValue. If this key is not existed, nothing will happen.

func (*StandardCache) Dump

func (sc *StandardCache) Dump(w io.Writer)

Dump is for endurance. It will write all alive data by w, which means one gc task will be invoked before writing. It will be implemented in future versions...

func (*StandardCache) Extend

func (sc *StandardCache) Extend() AdvancedCache

Extend returns a cache instance with advanced features. Notice that this method is for extension, so implement it is not required. You can just return a nil in method body.

func (*StandardCache) Gc

func (sc *StandardCache) Gc()

Gc is for cleaning up dead data. Notice that this method will take lots of time to remove all dead data if there are many entries in cache. So it is not recommended to call Gc() manually. Let cachego do this automatically will be better.

func (*StandardCache) Of

func (sc *StandardCache) Of(key string) *cacheValue

Of returns the value of this key. Return invalidCacheValue if this key is absent in cache.

func (*StandardCache) Put

func (sc *StandardCache) Put(key string, value interface{}, life time.Duration)

Put stores an entry (key, value) to cache, and sets the life of this entry.

func (*StandardCache) Remove

func (sc *StandardCache) Remove(key string)

Remove removes the value of key. If this key is not existed, nothing will happen.

func (*StandardCache) RemoveAll

func (sc *StandardCache) RemoveAll()

RemoveAll is for removing all data in cache.

func (*StandardCache) Size

func (sc *StandardCache) Size() int

Size returns the count of entries in cache.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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