introduction of bst

This commit is contained in:
Giuseppe 2015-11-30 09:06:51 +01:00
parent 28ab885a1a
commit c11107bf02
2 changed files with 32 additions and 10 deletions

View File

@ -1,6 +1,7 @@
package cache package cache
import ( import (
"github.com/petar/GoLLRB/llrb"
"encoding/gob" "encoding/gob"
"fmt" "fmt"
"io" "io"
@ -15,6 +16,11 @@ var emptyTime = time.Time{}
type Item struct { type Item struct {
Object interface{} Object interface{}
Expiration time.Time Expiration time.Time
Key string
}
func (item Item) Less(than llrb.Item) bool {
return item.Expiration.Before(than.(Item).Expiration)
} }
// Returns true if the item has expired. // Returns true if the item has expired.
@ -45,6 +51,7 @@ type cache struct {
mu sync.RWMutex mu sync.RWMutex
onEvicted func(string, interface{}) onEvicted func(string, interface{})
janitor *janitor janitor *janitor
sortedItems *llrb.LLRB
} }
// Add an item to the cache, replacing any existing item. If the duration is 0 // Add an item to the cache, replacing any existing item. If the duration is 0
@ -66,10 +73,18 @@ func (c *cache) set(k string, x interface{}, d time.Duration) {
if d > 0 { if d > 0 {
e = time.Now().Add(d) e = time.Now().Add(d)
} }
c.items[k] = Item{ item := Item{
Object: x, Object: x,
Expiration: e, Expiration: e,
Key : k,
} }
//if an item with the same key exists in the cache, remove it from the bst
old, found := c.items[k]
if found {
c.sortedItems.Delete(old)
c.sortedItems.InsertNoReplace(item)
}
c.items[k] = item
} }
// Add an item to the cache only if an item doesn't already exist for the given // Add an item to the cache only if an item doesn't already exist for the given
@ -1041,6 +1056,11 @@ func newCache(de time.Duration, m map[string]Item) *cache {
func newCacheWithJanitor(de time.Duration, ci time.Duration, m map[string]Item) *Cache { func newCacheWithJanitor(de time.Duration, ci time.Duration, m map[string]Item) *Cache {
c := newCache(de, m) c := newCache(de, m)
c.sortedItems = llrb.New()
//we can probably do bulk insertion here to speed it up
for _, item := range m {
c.sortedItems.InsertNoReplace(item)
}
// This trick ensures that the janitor goroutine (which--granted it // This trick ensures that the janitor goroutine (which--granted it
// was enabled--is running DeleteExpired on c forever) does not keep // was enabled--is running DeleteExpired on c forever) does not keep
// the returned C object from being garbage collected. When it is // the returned C object from being garbage collected. When it is

View File

@ -8,6 +8,7 @@ import (
"os" "os"
"runtime" "runtime"
"time" "time"
"github.com/petar/GoLLRB/llrb"
) )
// This is an experimental and unexported (for now) attempt at making a cache // This is an experimental and unexported (for now) attempt at making a cache
@ -172,6 +173,7 @@ func newShardedCache(n int, de time.Duration) *shardedCache {
c := &cache{ c := &cache{
defaultExpiration: de, defaultExpiration: de,
items: map[string]Item{}, items: map[string]Item{},
sortedItems: llrb.New(),
} }
sc.cs[i] = c sc.cs[i] = c
} }