mirror of https://github.com/tidwall/buntdb.git
added TTL function
This commit is contained in:
parent
332ce3d9ca
commit
d3df98bcf9
34
buntdb.go
34
buntdb.go
|
@ -683,6 +683,15 @@ func (db *DB) Update(fn func(tx *Tx) error) error {
|
|||
return db.managed(true, fn)
|
||||
}
|
||||
|
||||
// get return an item or nil if not found.
|
||||
func (db *DB) get(key string) *dbItem {
|
||||
item := db.keys.Get(&dbItem{key: key})
|
||||
if item != nil {
|
||||
return item.(*dbItem)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Tx represents a transaction on the database. This transaction can either be
|
||||
// read-only or read/write. Read-only transactions can be used for retrieving
|
||||
// values for keys and iterating through keys and values. Read/write
|
||||
|
@ -975,11 +984,10 @@ func (tx *Tx) Get(key string) (val string, err error) {
|
|||
if tx.db == nil {
|
||||
return "", ErrTxClosed
|
||||
}
|
||||
prev := tx.db.keys.Get(&dbItem{key: key})
|
||||
if prev == nil {
|
||||
item := tx.db.get(key)
|
||||
if item == nil {
|
||||
return "", ErrNotFound
|
||||
}
|
||||
item := prev.(*dbItem)
|
||||
if item.expired() {
|
||||
// The item exists in the tree, but has expired. Let's assume that
|
||||
// the caller is only interested in items that have not expired.
|
||||
|
@ -1016,6 +1024,26 @@ func (tx *Tx) Delete(key string) (val string, err error) {
|
|||
return item.val, nil
|
||||
}
|
||||
|
||||
// TTL returns the remaining time-to-live for an item.
|
||||
// A negative duration will be returned for items that do not have an
|
||||
// expiration.
|
||||
func (tx *Tx) TTL(key string) (time.Duration, error) {
|
||||
if tx.db == nil {
|
||||
return 0, ErrTxClosed
|
||||
}
|
||||
item := tx.db.get(key)
|
||||
if item == nil {
|
||||
return 0, ErrNotFound
|
||||
} else if item.opts == nil || !item.opts.ex {
|
||||
return -1, nil
|
||||
}
|
||||
dur := item.opts.exat.Sub(time.Now())
|
||||
if dur < 0 {
|
||||
return 0, ErrNotFound
|
||||
}
|
||||
return dur, nil
|
||||
}
|
||||
|
||||
// scan iterates through a specified index and calls user-defined iterator
|
||||
// function for each item encountered.
|
||||
// The desc param indicates that the iterator should descend.
|
||||
|
|
|
@ -789,3 +789,35 @@ func TestRectStrings(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTTL(t *testing.T) {
|
||||
os.RemoveAll("data.db")
|
||||
db, err := Open("data.db")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll("data.db")
|
||||
defer db.Close()
|
||||
db.Update(func(tx *Tx) error {
|
||||
tx.Set("key1", "val1", &SetOptions{Expires: true, TTL: time.Second})
|
||||
tx.Set("key2", "val2", nil)
|
||||
return nil
|
||||
})
|
||||
db.View(func(tx *Tx) error {
|
||||
dur1, err := tx.TTL("key1")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if dur1 > time.Second || dur1 <= 0 {
|
||||
t.Fatalf("expecting between zero and one second, got '%v'", dur1)
|
||||
}
|
||||
dur1, err = tx.TTL("key2")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if dur1 >= 0 {
|
||||
t.Fatalf("expecting a negative value, got '%v'", dur1)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue