use integer counter for promotions instead of time

This commit is contained in:
Karl Seguin 2013-10-21 19:37:35 +08:00
parent 7a8102e166
commit 36e5fae491
5 changed files with 28 additions and 25 deletions

View file

@ -24,7 +24,7 @@ func (b *Bucket) set(key string, value Value) *Item {
existing.Unlock()
return existing
}
item := &Item{key: key, value: value}
item := newItem(key, value)
b.lookup[key] = item
return item
}

View file

@ -56,7 +56,7 @@ func (c *Cache) bucket(key string) *Bucket {
}
func (c *Cache) promote(item *Item) {
if item.shouldPromote(c.promoteDelay) == false { return }
if item.shouldPromote() == false { return }
c.promotables <- item
}
@ -75,7 +75,7 @@ func (c *Cache) worker() {
func (c *Cache) doPromote(item *Item) bool {
item.Lock()
defer item.Unlock()
item.promoted = time.Now()
item.promotions = 0
if item.element != nil { //not a new item
c.list.MoveToFront(item.element)
return false

View file

@ -1,15 +1,10 @@
package ccache
import (
"time"
)
type Configuration struct {
size uint64
buckets int
itemsToPrune int
promoteBuffer int
promoteDelay time.Duration
}
func Configure() *Configuration {
@ -18,7 +13,6 @@ func Configure() *Configuration {
itemsToPrune: 500,
promoteBuffer: 1024,
size: 500 * 1024 * 1024,
promoteDelay: time.Minute * -5,
}
}
@ -41,8 +35,3 @@ func (c *Configuration) PromoteBuffer(size int) *Configuration {
c.promoteBuffer = size
return c
}
func (c *Configuration) PromoteDelay(delay time.Duration) *Configuration {
c.promoteDelay = -delay
return c
}

25
item.go
View file

@ -2,21 +2,32 @@ package ccache
import (
"sync"
"time"
"sync/atomic"
"container/list"
)
const promoteCap = 5
type Item struct {
key string
value Value
sync.RWMutex
promoted time.Time
promotions int32
element *list.Element
}
func (i *Item) shouldPromote(staleness time.Duration) bool {
stale := time.Now().Add(staleness)
i.RLock()
defer i.RUnlock()
return i.promoted.Before(stale)
func newItem(key string, value Value) *Item {
return &Item{
key: key,
value: value,
promotions: -1,
}
}
func (i *Item) shouldPromote() bool {
promotions := atomic.AddInt32(&i.promotions, 1)
if promotions == promoteCap || promotions == 0 {
return true
}
return false
}

View file

@ -1,14 +1,17 @@
package ccache
import (
"time"
"testing"
"github.com/karlseguin/gspec"
)
func TestItemPromotability(t *testing.T) {
spec := gspec.New(t)
item := &Item{promoted: time.Now().Add(time.Second * -5)}
spec.Expect(item.shouldPromote(time.Second * -2)).ToEqual(true)
spec.Expect(item.shouldPromote(time.Second * -6)).ToEqual(false)
item := &Item{promotions: -1}
spec.Expect(item.shouldPromote()).ToEqual(true)
spec.Expect(item.shouldPromote()).ToEqual(false)
item.promotions = 4
spec.Expect(item.shouldPromote()).ToEqual(true)
spec.Expect(item.shouldPromote()).ToEqual(false)
}