introduction of bst
This commit is contained in:
parent
28ab885a1a
commit
c11107bf02
40
cache.go
40
cache.go
|
@ -1,6 +1,7 @@
|
||||||
package cache
|
package cache
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/petar/GoLLRB/llrb"
|
||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
@ -13,8 +14,13 @@ import (
|
||||||
var emptyTime = time.Time{}
|
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.
|
||||||
|
@ -40,11 +46,12 @@ type Cache struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type cache struct {
|
type cache struct {
|
||||||
defaultExpiration time.Duration
|
defaultExpiration time.Duration
|
||||||
items map[string]Item
|
items map[string]Item
|
||||||
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
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue