2019-06-12 07:46:20 +01:00
|
|
|
// Package memory is a in-memory store store
|
2019-06-11 17:49:34 +01:00
|
|
|
package memory
|
|
|
|
|
|
|
|
import (
|
2020-01-08 22:23:14 +00:00
|
|
|
"strings"
|
2019-06-11 17:49:34 +01:00
|
|
|
"sync"
|
|
|
|
"time"
|
|
|
|
|
2020-01-30 14:39:00 +03:00
|
|
|
"github.com/micro/go-micro/v2/store"
|
2019-06-11 17:49:34 +01:00
|
|
|
)
|
|
|
|
|
2019-06-12 07:46:20 +01:00
|
|
|
type memoryStore struct {
|
2019-12-16 14:38:51 +00:00
|
|
|
options store.Options
|
2019-06-11 17:49:34 +01:00
|
|
|
|
|
|
|
sync.RWMutex
|
|
|
|
values map[string]*memoryRecord
|
|
|
|
}
|
|
|
|
|
|
|
|
type memoryRecord struct {
|
2019-06-12 07:46:20 +01:00
|
|
|
r *store.Record
|
2019-06-11 17:49:34 +01:00
|
|
|
c time.Time
|
|
|
|
}
|
|
|
|
|
2020-01-08 12:11:31 +00:00
|
|
|
func (m *memoryStore) Init(opts ...store.Option) error {
|
|
|
|
for _, o := range opts {
|
|
|
|
o(&m.options)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2019-10-23 22:05:39 +01:00
|
|
|
func (m *memoryStore) List() ([]*store.Record, error) {
|
2019-06-11 17:49:34 +01:00
|
|
|
m.RLock()
|
|
|
|
defer m.RUnlock()
|
|
|
|
|
2019-12-03 22:59:44 +03:00
|
|
|
//nolint:prealloc
|
2019-06-12 07:46:20 +01:00
|
|
|
var values []*store.Record
|
2019-06-11 17:49:34 +01:00
|
|
|
|
|
|
|
for _, v := range m.values {
|
|
|
|
// get expiry
|
|
|
|
d := v.r.Expiry
|
|
|
|
t := time.Since(v.c)
|
|
|
|
|
2019-07-11 12:58:20 +08:00
|
|
|
if d > time.Duration(0) {
|
2019-07-11 14:13:58 +08:00
|
|
|
// expired
|
|
|
|
if t > d {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
// update expiry
|
2019-07-11 12:58:20 +08:00
|
|
|
v.r.Expiry -= t
|
|
|
|
v.c = time.Now()
|
|
|
|
}
|
2019-07-11 12:51:55 +08:00
|
|
|
|
2019-06-11 17:49:34 +01:00
|
|
|
values = append(values, v.r)
|
|
|
|
}
|
|
|
|
|
|
|
|
return values, nil
|
|
|
|
}
|
|
|
|
|
2020-01-08 22:23:14 +00:00
|
|
|
func (m *memoryStore) Read(key string, opts ...store.ReadOption) ([]*store.Record, error) {
|
2019-06-11 17:49:34 +01:00
|
|
|
m.RLock()
|
|
|
|
defer m.RUnlock()
|
|
|
|
|
2020-01-08 22:23:14 +00:00
|
|
|
var options store.ReadOptions
|
|
|
|
|
|
|
|
for _, o := range opts {
|
|
|
|
o(&options)
|
|
|
|
}
|
2019-06-11 17:49:34 +01:00
|
|
|
|
2020-01-08 22:23:14 +00:00
|
|
|
var vals []*memoryRecord
|
|
|
|
|
2020-02-03 08:16:02 +00:00
|
|
|
if options.Prefix {
|
2020-01-08 22:23:14 +00:00
|
|
|
for _, v := range m.values {
|
|
|
|
if !strings.HasPrefix(v.r.Key, key) {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
vals = append(vals, v)
|
|
|
|
}
|
2020-02-03 08:16:02 +00:00
|
|
|
} else if options.Suffix {
|
|
|
|
for _, v := range m.values {
|
|
|
|
if !strings.HasSuffix(v.r.Key, key) {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
vals = append(vals, v)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
v, ok := m.values[key]
|
|
|
|
if !ok {
|
|
|
|
return nil, store.ErrNotFound
|
|
|
|
}
|
|
|
|
vals = []*memoryRecord{v}
|
2020-01-08 22:23:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//nolint:prealloc
|
|
|
|
var records []*store.Record
|
2019-10-11 14:08:50 +01:00
|
|
|
|
2020-01-08 22:23:14 +00:00
|
|
|
for _, v := range vals {
|
2019-10-11 14:08:50 +01:00
|
|
|
// get expiry
|
|
|
|
d := v.r.Expiry
|
|
|
|
t := time.Since(v.c)
|
|
|
|
|
|
|
|
// expired
|
|
|
|
if d > time.Duration(0) {
|
|
|
|
if t > d {
|
|
|
|
return nil, store.ErrNotFound
|
|
|
|
}
|
|
|
|
// update expiry
|
|
|
|
v.r.Expiry -= t
|
|
|
|
v.c = time.Now()
|
|
|
|
}
|
|
|
|
|
|
|
|
records = append(records, v.r)
|
2019-07-11 12:58:20 +08:00
|
|
|
}
|
2019-07-11 12:51:55 +08:00
|
|
|
|
2019-10-11 14:08:50 +01:00
|
|
|
return records, nil
|
2019-06-11 17:49:34 +01:00
|
|
|
}
|
|
|
|
|
2020-01-08 22:23:14 +00:00
|
|
|
func (m *memoryStore) Write(r *store.Record) error {
|
2019-06-11 17:49:34 +01:00
|
|
|
m.Lock()
|
|
|
|
defer m.Unlock()
|
|
|
|
|
2020-01-08 22:23:14 +00:00
|
|
|
// set the record
|
|
|
|
m.values[r.Key] = &memoryRecord{
|
|
|
|
r: r,
|
|
|
|
c: time.Now(),
|
2019-06-11 17:49:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-01-08 22:23:14 +00:00
|
|
|
func (m *memoryStore) Delete(key string) error {
|
2019-06-11 17:49:34 +01:00
|
|
|
m.Lock()
|
|
|
|
defer m.Unlock()
|
|
|
|
|
2020-01-08 22:23:14 +00:00
|
|
|
// delete the value
|
|
|
|
delete(m.values, key)
|
2019-06-11 17:49:34 +01:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-01-10 19:13:55 +00:00
|
|
|
func (m *memoryStore) String() string {
|
|
|
|
return "memory"
|
|
|
|
}
|
|
|
|
|
2019-06-12 07:46:20 +01:00
|
|
|
// NewStore returns a new store.Store
|
2019-12-16 14:38:51 +00:00
|
|
|
func NewStore(opts ...store.Option) store.Store {
|
|
|
|
var options store.Options
|
|
|
|
for _, o := range opts {
|
|
|
|
o(&options)
|
|
|
|
}
|
2019-06-11 17:49:34 +01:00
|
|
|
|
2019-06-12 07:46:20 +01:00
|
|
|
return &memoryStore{
|
2019-12-16 14:38:51 +00:00
|
|
|
options: options,
|
2019-06-11 17:49:34 +01:00
|
|
|
values: make(map[string]*memoryRecord),
|
|
|
|
}
|
|
|
|
}
|