mirror of
https://github.com/gofiber/storage.git
synced 2025-10-07 01:23:02 +08:00
👷 Improve memory storage
This commit is contained in:
@@ -15,7 +15,7 @@ var ConfigDefault = Config{
|
||||
GCInterval: 10 * time.Second,
|
||||
}
|
||||
|
||||
// Helper function to set default values
|
||||
// configDefault is a helper function to set default values
|
||||
func configDefault(config ...Config) Config {
|
||||
// Return default config if nothing provided
|
||||
if len(config) < 1 {
|
||||
|
@@ -43,7 +43,7 @@ func (s *Storage) Get(key string) ([]byte, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if v.expiry <= time.Now().Unix() && v.expiry != 0 {
|
||||
if v.expiry != 0 && v.expiry <= time.Now().Unix() {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -80,15 +80,11 @@ func (s *Storage) Clear() error {
|
||||
}
|
||||
|
||||
func (s *Storage) gc() {
|
||||
tick := time.NewTicker(s.gcInterval)
|
||||
for {
|
||||
<-tick.C
|
||||
|
||||
for t := range time.NewTicker(s.gcInterval).C {
|
||||
now := t.Unix()
|
||||
s.mux.Lock()
|
||||
|
||||
now := time.Now().Unix()
|
||||
for id, v := range s.db {
|
||||
if v.expiry < now && v.expiry != 0 {
|
||||
if v.expiry != 0 && v.expiry < now {
|
||||
delete(s.db, id)
|
||||
}
|
||||
}
|
||||
|
@@ -7,20 +7,31 @@ import (
|
||||
"github.com/gofiber/utils"
|
||||
)
|
||||
|
||||
func Test_Memory_Config(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
store := New(Config{})
|
||||
|
||||
utils.AssertEqual(t, ConfigDefault.GCInterval, store.gcInterval)
|
||||
}
|
||||
|
||||
func Test_Memory_Set(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
store := New()
|
||||
|
||||
id := "hello"
|
||||
value := []byte("Hi there!")
|
||||
|
||||
store.Set(id, value, 0)
|
||||
err := store.Set(id, value, 0)
|
||||
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, entry{value, 0}, store.db[id])
|
||||
|
||||
}
|
||||
|
||||
func Test_Memory_SetExpiry(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
store := New()
|
||||
|
||||
@@ -28,7 +39,9 @@ func Test_Memory_SetExpiry(t *testing.T) {
|
||||
value := []byte("Hi there!")
|
||||
expiry := time.Second * 10
|
||||
|
||||
store.Set(id, value, expiry)
|
||||
err := store.Set(id, value, expiry)
|
||||
|
||||
utils.AssertEqual(t, nil, err)
|
||||
|
||||
now := time.Now().Unix()
|
||||
fromStore, found := store.db[id]
|
||||
@@ -44,45 +57,66 @@ func Test_Memory_SetExpiry(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
// func Test_Memory_GC(t *testing.T) {
|
||||
func Test_Memory_GC(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// // New() isn't being used here so the gcInterval can be set low
|
||||
// store := &Storage{
|
||||
// DB: make(map[string]entry),
|
||||
// gcInterval: time.Second * 1,
|
||||
// }
|
||||
// go store.gc()
|
||||
|
||||
// id := "hello"
|
||||
// value := []byte("Hi there!")
|
||||
|
||||
// expireAt := time.Now().Add(time.Second * 2).Unix()
|
||||
|
||||
// store.db[id] = entry{value, expireAt}
|
||||
|
||||
// time.Sleep(time.Second * 4) // The purpose of the long delay is to ensure the GC has time to run and delete the value
|
||||
|
||||
// _, found := store.db[id]
|
||||
// utils.AssertEqual(t, false, found)
|
||||
|
||||
// }
|
||||
|
||||
func Test_Memory_Get(t *testing.T) {
|
||||
|
||||
store := New()
|
||||
store := &Storage{
|
||||
db: make(map[string]entry),
|
||||
gcInterval: time.Millisecond * 10,
|
||||
}
|
||||
|
||||
id := "hello"
|
||||
value := []byte("Hi there!")
|
||||
|
||||
store.db[id] = entry{value, 0}
|
||||
expireAt := time.Now().Add(-time.Second).Unix()
|
||||
|
||||
returnedValue, err := store.Get(id)
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, value, returnedValue)
|
||||
store.db[id] = entry{value, expireAt}
|
||||
|
||||
go store.gc()
|
||||
|
||||
// The purpose of the long delay is to ensure the GC has time to run and delete the value
|
||||
time.Sleep(time.Millisecond * 15)
|
||||
|
||||
store.mux.RLock()
|
||||
_, found := store.db[id]
|
||||
utils.AssertEqual(t, false, found)
|
||||
store.mux.RUnlock()
|
||||
}
|
||||
|
||||
func Test_Memory_Get(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
store := New()
|
||||
|
||||
t.Run("exist", func(t *testing.T) {
|
||||
id := "hello"
|
||||
value := []byte("Hi there!")
|
||||
|
||||
store.db[id] = entry{value, 0}
|
||||
|
||||
returnedValue, err := store.Get(id)
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, value, returnedValue)
|
||||
})
|
||||
|
||||
t.Run("expired", func(t *testing.T) {
|
||||
expired := "expired"
|
||||
store.db[expired] = entry{[]byte{}, time.Now().Add(-time.Second).Unix()}
|
||||
|
||||
returnedValue, err := store.Get(expired)
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, true, returnedValue == nil)
|
||||
})
|
||||
|
||||
t.Run("non-exist", func(t *testing.T) {
|
||||
returnedValue, err := store.Get("non-exist")
|
||||
utils.AssertEqual(t, nil, err)
|
||||
utils.AssertEqual(t, true, returnedValue == nil)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Memory_Delete(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
store := New()
|
||||
|
||||
@@ -100,6 +134,7 @@ func Test_Memory_Delete(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_Memory_Clear(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
store := New()
|
||||
|
||||
@@ -122,12 +157,14 @@ func Benchmark_Memory_Set(b *testing.B) {
|
||||
value := []byte("Hi there!")
|
||||
expiry := time.Duration(0)
|
||||
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
|
||||
for n := 0; n < b.N; n++ {
|
||||
store.Set(id, value, expiry)
|
||||
}
|
||||
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
_ = store.Set(id, value, expiry)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func Benchmark_Memory_Get(b *testing.B) {
|
||||
@@ -139,9 +176,12 @@ func Benchmark_Memory_Get(b *testing.B) {
|
||||
|
||||
store.db[id] = entry{value, 0}
|
||||
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
|
||||
for n := 0; n < b.N; n++ {
|
||||
store.Get(id)
|
||||
}
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
_, _ = store.Get(id)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
Reference in New Issue
Block a user