forked from urdt/ussd
Implement timed data row db
This commit is contained in:
parent
2a93ea7a0c
commit
fbcde2f322
@ -10,6 +10,10 @@ const (
|
||||
DATATYPE_USERSUB = 64
|
||||
)
|
||||
|
||||
const (
|
||||
SUBPREFIX_TIME = uint16(1)
|
||||
)
|
||||
|
||||
type SubPrefixDb struct {
|
||||
store db.Db
|
||||
pfx []byte
|
||||
|
@ -12,6 +12,7 @@ var (
|
||||
dbC map[string]chan db.Db
|
||||
)
|
||||
|
||||
|
||||
type ThreadGdbmDb struct {
|
||||
db db.Db
|
||||
connStr string
|
||||
|
75
internal/storage/timed.go
Normal file
75
internal/storage/timed.go
Normal file
@ -0,0 +1,75 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
"encoding/binary"
|
||||
|
||||
"git.defalsify.org/vise.git/db"
|
||||
)
|
||||
|
||||
type TimedDb struct {
|
||||
db.Db
|
||||
tdb *SubPrefixDb
|
||||
ttl time.Duration
|
||||
parentPfx uint8
|
||||
}
|
||||
|
||||
|
||||
func NewTimedDb(db db.Db, ttl time.Duration) *TimedDb {
|
||||
var b [2]byte
|
||||
binary.BigEndian.PutUint16(b[:], SUBPREFIX_TIME)
|
||||
sdb := NewSubPrefixDb(db, b[:])
|
||||
return &TimedDb{
|
||||
Db: db,
|
||||
tdb: sdb,
|
||||
ttl: ttl,
|
||||
}
|
||||
}
|
||||
|
||||
func(tib *TimedDb) SetPrefix(pfx uint8) {
|
||||
tib.Db.SetPrefix(pfx)
|
||||
tib.parentPfx = pfx
|
||||
}
|
||||
|
||||
func(tib *TimedDb) Put(ctx context.Context, key []byte, val []byte) error {
|
||||
t := time.Now()
|
||||
b, err := t.MarshalBinary()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = tib.Db.Put(ctx, key, val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
k := append([]byte{tib.parentPfx}, key...)
|
||||
defer func() {
|
||||
tib.parentPfx = 0
|
||||
}()
|
||||
err = tib.tdb.Put(ctx, k, b)
|
||||
if err != nil {
|
||||
logg.ErrorCtxf(ctx, "failed to update timestamp of record", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func(tib *TimedDb) Get(ctx context.Context, key []byte) ([]byte, error) {
|
||||
v, err := tib.Db.Get(ctx, key)
|
||||
return v, err
|
||||
}
|
||||
|
||||
func(tib *TimedDb) Stale(ctx context.Context, pfx uint8, key []byte) bool {
|
||||
b := append([]byte{pfx}, key...)
|
||||
v, err := tib.tdb.Get(ctx, b)
|
||||
if err != nil {
|
||||
logg.ErrorCtxf(ctx, "no time entry", "key", key)
|
||||
return false
|
||||
}
|
||||
t_now := time.Now()
|
||||
t_then := time.Time{}
|
||||
err = t_then.UnmarshalBinary(v)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return t_now.After(t_then.Add(tib.ttl))
|
||||
}
|
35
internal/storage/timed_test.go
Normal file
35
internal/storage/timed_test.go
Normal file
@ -0,0 +1,35 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"git.defalsify.org/vise.git/db"
|
||||
memdb "git.defalsify.org/vise.git/db/mem"
|
||||
)
|
||||
|
||||
func TestStaleDb(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
mdb := memdb.NewMemDb()
|
||||
err := mdb.Connect(ctx, "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
tdb := NewTimedDb(mdb, time.Duration(time.Millisecond))
|
||||
tdb.SetPrefix(db.DATATYPE_USERDATA)
|
||||
k := []byte("foo")
|
||||
err = tdb.Put(ctx, k, []byte("bar"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if tdb.Stale(ctx, db.DATATYPE_USERDATA, k) {
|
||||
t.Fatal("expected not stale")
|
||||
}
|
||||
time.Sleep(time.Millisecond)
|
||||
if !tdb.Stale(ctx, db.DATATYPE_USERDATA, k) {
|
||||
t.Fatal("expected stale")
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user