Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v0.6.0-alpha #11

Merged
merged 6 commits into from
Jan 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
- name: Setup
uses: actions/setup-go@v4
with:
go-version: "1.17"
go-version: "1.20"
- run: go version

- name: Checkout
Expand Down
6 changes: 5 additions & 1 deletion FUTURE.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
## ✒ 未来版本的新特性 (Features in future versions)

### v0.6.x

* [ ] 梳理代码,优化代码风格,精简部分代码和注释
* [ ] 完善监控上报器,提供更多缓存信息查询的方法

### v0.5.x

* [ ] ~~提供一个清空并设置全量值的方法,方便定时数据的全量替换~~
目前还找不到一个合适的设计去加入这个功能,并且也不是非常刚需,通过业务手段可以处理,所以先不加
* [ ] 完善监控上报器,提供更多缓存信息查询的方法

### v0.4.x

Expand Down
7 changes: 7 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
## ✒ 历史版本的特性介绍 (Features in old versions)

### v0.6.0-alpha

> 此版本发布于 2024-01-13

* 受小徒弟的灵感激发,进行 loader 代码的调整
* 把 cache 结构去掉,精简这部分设计

### v0.5.0

> 此版本发布于 2023-11-30
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
all: test bench

test:
go test -cover ./...
go test -cover -count=1 -test.cpu=1 ./...

bench:
go test -v -bench=. -benchtime=1s ./_examples/performance_test.go
go test -v ./_examples/performance_test.go -bench=. -benchtime=1s

fmt:
go fmt ./...
2 changes: 1 addition & 1 deletion README.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[![Go Doc](_icons/godoc.svg)](https://pkg.go.dev/github.com/FishGoddess/cachego)
[![License](_icons/license.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)
[![License](_icons/coverage.svg)](_icons/coverage.svg)
[![Coverage](_icons/coverage.svg)](_icons/coverage.svg)
![Test](https://github.com/FishGoddess/cachego/actions/workflows/test.yml/badge.svg)

**cachego** is an api friendly memory-based cache for [GoLang](https://golang.org) applications.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[![Go Doc](_icons/godoc.svg)](https://pkg.go.dev/github.com/FishGoddess/cachego)
[![License](_icons/license.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)
[![License](_icons/coverage.svg)](_icons/coverage.svg)
[![Coverage](_icons/coverage.svg)](_icons/coverage.svg)
![Test](https://github.com/FishGoddess/cachego/actions/workflows/test.yml/badge.svg)

**cachego** 是一个拥有分片机制的轻量级内存缓存库,API 友好,支持多种数据淘汰机制,可以应用于所有的 [GoLang](https://golang.org) 应用程序中。
Expand Down
7 changes: 1 addition & 6 deletions _examples/task.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,5 @@ func main() {
// Duration is the duration between two loop of fn, optional.
// Run will start a new goroutine and run the task loop.
// The task will stop if context is done.
task.New(printContextValue).
Before(beforePrint).
After(afterPrint).
Context(ctx).
Duration(time.Second).
Run()
task.New(printContextValue).Before(beforePrint).After(afterPrint).Context(ctx).Duration(time.Second).Run()
}
4 changes: 2 additions & 2 deletions _icons/coverage.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed _icons/jetbrains.png
Binary file not shown.
91 changes: 21 additions & 70 deletions cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ package cachego

import (
"context"
"sync"
"time"

"github.com/FishGoddess/cachego/pkg/task"
Expand All @@ -27,20 +26,6 @@ const (
NoTTL = 0
)

const (
// standard cache is a simple cache with locked map.
// It evicts entries randomly if cache size reaches to max entries.
standard CacheType = "standard"

// lru cache is a cache using lru to evict entries.
// More details see https://en.wikipedia.org/wiki/Cache_replacement_policies#Least_recently_used_(LRU).
lru CacheType = "lru"

// lfu cache is a cache using lfu to evict entries.
// More details see https://en.wikipedia.org/wiki/Cache_replacement_policies#Least-frequently_used_(LFU).
lfu CacheType = "lfu"
)

var (
newCaches = map[CacheType]func(conf *config) Cache{
standard: newStandardCache,
Expand All @@ -49,29 +34,6 @@ var (
}
)

// CacheType is the type of cache.
type CacheType string

// String returns the cache type in string form.
func (ct CacheType) String() string {
return string(ct)
}

// IsStandard returns if cache type is standard.
func (ct CacheType) IsStandard() bool {
return ct == standard
}

// IsLRU returns if cache type is lru.
func (ct CacheType) IsLRU() bool {
return ct == lru
}

// IsLFU returns if cache type is lfu.
func (ct CacheType) IsLFU() bool {
return ct == lfu
}

// Cache is the core interface of cachego.
// We provide some implements including standard cache and sharding cache.
type Cache interface {
Expand Down Expand Up @@ -101,38 +63,10 @@ type Cache interface {
// Reset resets cache to initial status which is like a new cache.
Reset()

// Loader loads a value to cache.
// See Loader interface.
Loader
}

type cache struct {
*config
Loader

lock sync.RWMutex
}

func (c *cache) setup(conf *config, cache Cache) {
c.config = conf
c.Loader = NewLoader(cache, conf.singleflight)
}

// RunGCTask runs a gc task in a new goroutine and returns a cancel function to cancel the task.
// However, you don't need to call it manually for most time, instead, use options is a better choice.
// Making it a public function is for more customizations in some situations.
// For example, using options to run gc task is un-cancelable, so you can use it to run gc task by your own
// and get a cancel function to cancel the gc task.
func RunGCTask(cache Cache, duration time.Duration) (cancel func()) {
fn := func(ctx context.Context) {
cache.GC()
}

ctx := context.Background()
ctx, cancel = context.WithCancel(ctx)

go task.New(fn).Context(ctx).Duration(duration).Run()
return cancel
// Load loads a key with ttl to cache and returns an error if failed.
// We recommend you use this method to load missed keys to cache,
// because it may use singleflight to reduce the times calling load function.
Load(key string, ttl time.Duration, load func() (value interface{}, err error)) (value interface{}, err error)
}

func newCache(withReport bool, opts ...Option) (cache Cache, reporter *Reporter) {
Expand Down Expand Up @@ -180,3 +114,20 @@ func NewCache(opts ...Option) (cache Cache) {
func NewCacheWithReport(opts ...Option) (cache Cache, reporter *Reporter) {
return newCache(true, opts...)
}

// RunGCTask runs a gc task in a new goroutine and returns a cancel function to cancel the task.
// However, you don't need to call it manually for most time, instead, use options is a better choice.
// Making it a public function is for more customizations in some situations.
// For example, using options to run gc task is un-cancelable, so you can use it to run gc task by your own
// and get a cancel function to cancel the gc task.
func RunGCTask(cache Cache, duration time.Duration) (cancel func()) {
fn := func(ctx context.Context) {
cache.GC()
}

ctx := context.Background()
ctx, cancel = context.WithCancel(ctx)

go task.New(fn).Context(ctx).Duration(duration).Run()
return cancel
}
41 changes: 10 additions & 31 deletions cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,35 +25,10 @@ const (
maxTestEntries = 10
)

// go test -v -cover -run=^TestCacheType$
func TestCacheType(t *testing.T) {
if standard.String() != string(standard) {
t.Fatalf("standard.String() %s is wrong", standard.String())
}

if lru.String() != string(lru) {
t.Fatalf("lru.String() %s is wrong", lru.String())
}

if lfu.String() != string(lfu) {
t.Fatalf("lfu.String() %s is wrong", lfu.String())
}

if !standard.IsStandard() {
t.Fatal("!standard.IsStandard()")
}

if !lru.IsLRU() {
t.Fatal("!standard.IsLRU()")
}

if !lfu.IsLFU() {
t.Fatal("!standard.IsLFU()")
}
}

type testCache struct {
cache
*config
loader *loader

count int32
}

Expand Down Expand Up @@ -84,6 +59,10 @@ func (tc *testCache) GC() (cleans int) {

func (tc *testCache) Reset() {}

func (tc *testCache) Load(key string, ttl time.Duration, load func() (value interface{}, err error)) (value interface{}, err error) {
return nil, nil
}

func testCacheGet(t *testing.T, cache Cache) {
value, found := cache.Get("key")
if found {
Expand Down Expand Up @@ -273,7 +252,7 @@ func testCacheImplement(t *testing.T, cache Cache) {
}
}

// go test -v -cover=^TestNewCache$
// go test -v -cover -count=1 -test.cpu=1=^TestNewCache$
func TestNewCache(t *testing.T) {
cache := NewCache()

Expand Down Expand Up @@ -317,7 +296,7 @@ func TestNewCache(t *testing.T) {
cache = NewCache(WithLRU(0))
}

// go test -v -cover=^TestNewCacheWithReport$
// go test -v -cover -count=1 -test.cpu=1=^TestNewCacheWithReport$
func TestNewCacheWithReport(t *testing.T) {
cache, reporter := NewCacheWithReport()

Expand All @@ -335,7 +314,7 @@ func TestNewCacheWithReport(t *testing.T) {
}
}

// go test -v -cover=^TestRunGCTask$
// go test -v -cover -count=1 -test.cpu=1=^TestRunGCTask$
func TestRunGCTask(t *testing.T) {
cache := new(testCache)

Expand Down
52 changes: 52 additions & 0 deletions cache_type.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright 2024 FishGoddess. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cachego

const (
// standard cache is a simple cache with locked map.
// It evicts entries randomly if cache size reaches to max entries.
standard CacheType = "standard"

// lru cache is a cache using lru to evict entries.
// More details see https://en.wikipedia.org/wiki/Cache_replacement_policies#Least_recently_used_(LRU).
lru CacheType = "lru"

// lfu cache is a cache using lfu to evict entries.
// More details see https://en.wikipedia.org/wiki/Cache_replacement_policies#Least-frequently_used_(LFU).
lfu CacheType = "lfu"
)

// CacheType is the type of cache.
type CacheType string

// String returns the cache type in string form.
func (ct CacheType) String() string {
return string(ct)
}

// IsStandard returns if cache type is standard.
func (ct CacheType) IsStandard() bool {
return ct == standard
}

// IsLRU returns if cache type is lru.
func (ct CacheType) IsLRU() bool {
return ct == lru
}

// IsLFU returns if cache type is lfu.
func (ct CacheType) IsLFU() bool {
return ct == lfu
}
44 changes: 44 additions & 0 deletions cache_type_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright 2024 FishGoddess. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cachego

import "testing"

// go test -v -cover -count=1 -test.cpu=1 -run=^TestCacheType$
func TestCacheType(t *testing.T) {
if standard.String() != string(standard) {
t.Fatalf("standard.String() %s is wrong", standard.String())
}

if lru.String() != string(lru) {
t.Fatalf("lru.String() %s is wrong", lru.String())
}

if lfu.String() != string(lfu) {
t.Fatalf("lfu.String() %s is wrong", lfu.String())
}

if !standard.IsStandard() {
t.Fatal("!standard.IsStandard()")
}

if !lru.IsLRU() {
t.Fatal("!standard.IsLRU()")
}

if !lfu.IsLFU() {
t.Fatal("!standard.IsLFU()")
}
}
2 changes: 1 addition & 1 deletion config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func isConfigEquals(conf1 *config, conf2 *config) bool {
return true
}

// go test -v -cover -run=^TestApplyOptions$
// go test -v -cover -count=1 -test.cpu=1 -run=^TestApplyOptions$
func TestApplyOptions(t *testing.T) {
got := &config{
shardings: 0,
Expand Down
Loading
Loading