Skip to content

Commit

Permalink
MRU, MFU naming
Browse files Browse the repository at this point in the history
  • Loading branch information
jamiealquiza committed May 17, 2018
1 parent 686122b commit bd2a74b
Show file tree
Hide file tree
Showing 11 changed files with 124 additions and 124 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
THE SOFTWARE.
24 changes: 12 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,14 @@ type KeyInfo struct {
}
```

### FlushMru(), FlushMfu(), FlushAll()
### FlushMRU(), FlushMFU(), FlushAll()
```go
err := c.FlushMru()
err := c.FlushMfu()
err := c.FlushMRU()
err := c.FlushMFU()
err := c.FlushAll()
```

Flush commands flush all keys from the respective cache. `FlushAll` is faster than combining `FlushMru` and `FlushMfu`.
Flush commands flush all keys from the respective cache. `FlushAll` is faster than combining `FlushMRU` and `FlushMFU`.

### Pause(), Resume()
```go
Expand All @@ -91,10 +91,10 @@ Returns a \*bicache.Stats.

```go
type Stats struct {
MfuSize uint // Number of acive MFU keys.
MruSize uint // Number of active MRU keys.
MfuUsedP uint // MFU used in percent.
MruUsedP uint // MRU used in percent.
MFUSize uint // Number of acive MFU keys.
MRUSize uint // Number of active MRU keys.
MFUUsedP uint // MFU used in percent.
MRUUsedP uint // MRU used in percent.
Hits uint64 // Cache hits.
Misses uint64 // Cache misses.
Evictions uint64 // Cache evictions.
Expand All @@ -109,7 +109,7 @@ j, _ := json.Marshal(stats)
fmt.Prinln(string(j))
```
```
{"MfuSize":0,"MruSize":3,"MfuUsedP":0,"MruUsedP":4,"Hits":3,"Misses":0,"Evictions":0,"Overflows":0}
{"MFUSize":0,"MRUSize":3,"MFUUsedP":0,"MRUUsedP":4,"Hits":3,"Misses":0,"Evictions":0,"Overflows":0}
```

# Design
Expand Down Expand Up @@ -180,8 +180,8 @@ import (

func main() {
c, _ := bicache.New(&bicache.Config{
MfuSize: 24, // MFU capacity in keys
MruSize: 64, // MRU capacity in keys
MFUSize: 24, // MFU capacity in keys
MRUSize: 64, // MRU capacity in keys
ShardCount: 16, // Shard count. Defaults to 512 if unset.
AutoEvict: 30000, // Run TTL evictions + MRU->MFU promotions / evictions automatically every 30s.
EvictLog: true, // Emit eviction timing logs.
Expand Down Expand Up @@ -215,5 +215,5 @@ john
5535
[109 121 32 118 97 108 117 101]
{"MfuSize":0,"MruSize":3,"MfuUsedP":0,"MruUsedP":4,"Hits":3,"Misses":0,"Evictions":0,"Overflows":0}
{"MFUSize":0,"MRUSize":3,"MFUUsedP":0,"MRUUsedP":4,"Hits":3,"Misses":0,"Evictions":0,"Overflows":0}
```
54 changes: 27 additions & 27 deletions bicache.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ type counters struct {
// defers the operation until each Set is called
// on the bicache.
type Config struct {
MfuSize uint
MruSize uint
MFUSize uint
MRUSize uint
AutoEvict uint
EvictLog bool
ShardCount int
Expand All @@ -91,10 +91,10 @@ type cacheData struct {
// Stats holds Bicache
// statistics data.
type Stats struct {
MfuSize uint // Number of acive MFU keys.
MruSize uint // Number of active MRU keys.
MfuUsedP uint // MFU used in percent.
MruUsedP uint // MRU used in percent.
MFUSize uint // Number of acive MFU keys.
MRUSize uint // Number of active MRU keys.
MFUUsedP uint // MFU used in percent.
MRUUsedP uint // MRU used in percent.
Hits uint64 // Cache hits.
Misses uint64 // Cache misses.
Evictions uint64 // Cache evictions.
Expand All @@ -109,7 +109,7 @@ func New(c *Config) (*Bicache, error) {
return nil, errors.New("Shard count must be a power of 2")
}

if c.MruSize <= 0 {
if c.MRUSize <= 0 {
return nil, errors.New("MRU size must be > 0")
}

Expand All @@ -121,8 +121,8 @@ func New(c *Config) (*Bicache, error) {
shards := make([]*Shard, c.ShardCount)

// Get cache sizes for each shard.
mfuSize := int(math.Ceil(float64(c.MfuSize) / float64(c.ShardCount)))
mruSize := int(math.Ceil(float64(c.MruSize) / float64(c.ShardCount)))
mfuSize := int(math.Ceil(float64(c.MFUSize) / float64(c.ShardCount)))
mruSize := int(math.Ceil(float64(c.MRUSize) / float64(c.ShardCount)))

// Init shards.
for i := 0; i < c.ShardCount; i++ {
Expand Down Expand Up @@ -258,8 +258,8 @@ func (b *Bicache) Stats() *Stats {

for _, s := range b.shards {
s.RLock()
stats.MfuSize += s.mfuCache.Len()
stats.MruSize += s.mruCache.Len()
stats.MFUSize += s.mfuCache.Len()
stats.MRUSize += s.mruCache.Len()
s.RUnlock()

mfuCap += float64(s.mfuCap)
Expand All @@ -271,12 +271,12 @@ func (b *Bicache) Stats() *Stats {
stats.Overflows += atomic.LoadUint64(&s.counters.overflows)
}

stats.MruUsedP = uint(float64(stats.MruSize) / mruCap * 100)
stats.MRUUsedP = uint(float64(stats.MRUSize) / mruCap * 100)
// Prevent incorrect stats in MRU-only mode.
if mfuCap > 0 {
stats.MfuUsedP = uint(float64(stats.MfuSize) / mfuCap * 100)
stats.MFUUsedP = uint(float64(stats.MFUSize) / mfuCap * 100)
} else {
stats.MfuUsedP = 0
stats.MFUUsedP = 0
}

return stats
Expand Down Expand Up @@ -354,7 +354,7 @@ func (s *Shard) evictTTL() int {
}

// promoteEvict checks if the MRU exceeds the
// Config.MruSize (overflow count) If so, the top <overflow count>
// Config.MRUSize (overflow count) If so, the top <overflow count>
// MRU scores are checked against the MFU. If any of the top MRU scores
// are greater than the lowest MFU scores, they are promoted
// to the MFU (if possible). Any remaining overflow count
Expand All @@ -370,7 +370,7 @@ func (s *Shard) promoteEvict() {
// LRU-only behavior.
if s.mfuCap == 0 {
s.Lock()
s.evictFromMruTail(mruOverflow)
s.evictFromMRUTail(mruOverflow)
s.Unlock()

return
Expand Down Expand Up @@ -462,19 +462,19 @@ promoteByScore:
// 2) We promoted some mruToPromoteEvict and have leftovers (canPromote > 0).

// Get top MRU scores and bottom MFU scores to compare.
bottomMfu := s.mfuCache.LowScores(mruOverflow)
bottomMFU := s.mfuCache.LowScores(mruOverflow)

// If the lowest MFU score is higher than the lowest
// score to promote, none of these are eligible.
if len(bottomMfu) == 0 || bottomMfu[0].Score >= mruToPromoteEvict[remainderPosition].Score {
goto evictFromMruTail
if len(bottomMFU) == 0 || bottomMFU[0].Score >= mruToPromoteEvict[remainderPosition].Score {
goto evictFromMRUTail
}

// Otherwise, scan for a replacement.
s.Lock()
scorePromote:
for _, mruNode := range mruToPromoteEvict[remainderPosition:] {
for i, mfuNode := range bottomMfu {
for i, mfuNode := range bottomMFU {
if mruNode.Score > mfuNode.Score {
// Push the evicted MFU node to the head
// of the MRU and update state.
Expand All @@ -491,11 +491,11 @@ scorePromote:
promotedByScore++

// Remove the replaced MFU node from the
// bottomMfu list so it's not attempted twice.
bottomMfu = append(bottomMfu[:i], bottomMfu[i+1:]...)
// bottomMFU list so it's not attempted twice.
bottomMFU = append(bottomMFU[:i], bottomMFU[i+1:]...)
break
}
if i == len(bottomMfu)-1 {
if i == len(bottomMFU)-1 {
break scorePromote
}
}
Expand All @@ -504,23 +504,23 @@ scorePromote:

s.Unlock()

evictFromMruTail:
evictFromMRUTail:

s.Lock()

// What's the overflow remainder count?
toEvict := mruOverflow - promotedByScore
// Evict this many from the MRU tail.
if toEvict > 0 {
s.evictFromMruTail(toEvict)
s.evictFromMRUTail(toEvict)
}

s.Unlock()
}

// evictFromMruTail evicts n keys from the tail
// evictFromMRUTail evicts n keys from the tail
// of the MRU cache.
func (s *Shard) evictFromMruTail(n int) {
func (s *Shard) evictFromMRUTail(n int) {
ttlStart := len(s.ttlMap)

for i := 0; i < n; i++ {
Expand Down
38 changes: 19 additions & 19 deletions bicache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ func TestNew(t *testing.T) {
// minimum for the number of shards specified.
for _, n := range configExpected {
c, _ := bicache.New(&bicache.Config{
MfuSize: uint(n[0]),
MruSize: uint(n[1]),
MFUSize: uint(n[0]),
MRUSize: uint(n[1]),
ShardCount: n[2],
})

Expand All @@ -34,8 +34,8 @@ func TestNew(t *testing.T) {

func TestStats(t *testing.T) {
c, _ := bicache.New(&bicache.Config{
MfuSize: 10,
MruSize: 30,
MFUSize: 10,
MRUSize: 30,
ShardCount: 2,
AutoEvict: 3000,
})
Expand All @@ -53,20 +53,20 @@ func TestStats(t *testing.T) {

stats := c.Stats()

if stats.MfuSize != 10 {
t.Errorf("Expected MFU size 10, got %d", stats.MfuSize)
if stats.MFUSize != 10 {
t.Errorf("Expected MFU size 10, got %d", stats.MFUSize)
}

if stats.MruSize != 30 {
t.Errorf("Expected MRU size 30, got %d", stats.MruSize)
if stats.MRUSize != 30 {
t.Errorf("Expected MRU size 30, got %d", stats.MRUSize)
}

if stats.MfuUsedP != 100 {
t.Errorf("Expected MFU usedp 100, got %d", stats.MfuUsedP)
if stats.MFUUsedP != 100 {
t.Errorf("Expected MFU usedp 100, got %d", stats.MFUUsedP)
}

if stats.MruUsedP != 100 {
t.Errorf("Expected MRU usedp 100, got %d", stats.MruUsedP)
if stats.MRUUsedP != 100 {
t.Errorf("Expected MRU usedp 100, got %d", stats.MRUUsedP)
}

if stats.Hits != 100 {
Expand All @@ -88,8 +88,8 @@ func TestStats(t *testing.T) {

func TestEvictTtl(t *testing.T) {
c, _ := bicache.New(&bicache.Config{
MfuSize: 10,
MruSize: 30,
MFUSize: 10,
MRUSize: 30,
ShardCount: 2,
AutoEvict: 1000,
})
Expand All @@ -111,16 +111,16 @@ func TestEvictTtl(t *testing.T) {

stats := c.Stats()

if stats.MruSize != 1 || stats.Evictions != 1 {
if stats.MRUSize != 1 || stats.Evictions != 1 {
t.Error("Unexpected stats")
}
}

func TestPromoteEvict(t *testing.T) {
// Also covers MRU tail eviction.
c, _ := bicache.New(&bicache.Config{
MfuSize: 10,
MruSize: 30,
MFUSize: 10,
MRUSize: 30,
ShardCount: 2,
AutoEvict: 5000,
})
Expand Down Expand Up @@ -150,11 +150,11 @@ func TestPromoteEvict(t *testing.T) {

stats := c.Stats()

if stats.MfuSize != 3 {
if stats.MFUSize != 3 {
t.Error("Unexpected MFU count")
}

if stats.MruSize != 30 {
if stats.MRUSize != 30 {
t.Error("Unexpected MRU count")
}

Expand Down
8 changes: 4 additions & 4 deletions examples/bicache-example/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Excerpts:
```go
c, _ := bicache.New(&bicache.Config{
MfuSize: 50000,
MruSize: 25000,
MFUSize: 50000,
MRUSize: 25000,
AutoEvict: 1000,
})

Expand Down Expand Up @@ -50,7 +50,7 @@ Max: 281.841µs
Min: 82ns
Rate/sec.: 5196912.04
{"MfuSize":0,"MruSize":100000,"MfuUsedP":0,"MruUsedP":200,"Hits":100010,"Misses":0,"Evictions":0}
{"MFUSize":0,"MRUSize":100000,"MFUUsedP":0,"MRUUsedP":200,"Hits":100010,"Misses":0,"Evictions":0}
```

Note: timing data via [tachymeter](https://github.com/jamiealquiza/tachymeter)
Note: timing data via [tachymeter](https://github.com/jamiealquiza/tachymeter)
4 changes: 2 additions & 2 deletions examples/bicache-example/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import (

func main() {
c, _ := bicache.New(&bicache.Config{
MfuSize: 50000,
MruSize: 50000,
MFUSize: 50000,
MRUSize: 50000,
AutoEvict: 1000,
ShardCount: 512,
})
Expand Down
4 changes: 2 additions & 2 deletions examples/bicache-loadtest/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ func main() {
flag.Parse()

c, _ := bicache.New(&bicache.Config{
MfuSize: uint(*mfu),
MruSize: uint(*mru),
MFUSize: uint(*mfu),
MRUSize: uint(*mru),
AutoEvict: uint(*evict * 1000),
EvictLog: true,
ShardCount: 1024,
Expand Down
10 changes: 5 additions & 5 deletions methods.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,8 +214,8 @@ func (b *Bicache) List(n int) ListResults {
return lr
}

// FlushMru flushes all MRU entries.
func (b *Bicache) FlushMru() error {
// FlushMRU flushes all MRU entries.
func (b *Bicache) FlushMRU() error {
// Traverse shards.
for _, s := range b.shards {
s.Lock()
Expand All @@ -236,8 +236,8 @@ func (b *Bicache) FlushMru() error {
return nil
}

// FlushMfu flushes all MFU entries.
func (b *Bicache) FlushMfu() error {
// FlushMFU flushes all MFU entries.
func (b *Bicache) FlushMFU() error {
// Traverse shards.
for _, s := range b.shards {
s.Lock()
Expand All @@ -260,7 +260,7 @@ func (b *Bicache) FlushMfu() error {

// FlushAll flushes all cache entries.
// Flush all is much faster than combining both a
// FlushMru and FlushMfu call.
// FlushMRU and FlushMFU call.
func (b *Bicache) FlushAll() error {
// Traverse and reset shard caches.
for _, s := range b.shards {
Expand Down
Loading

0 comments on commit bd2a74b

Please sign in to comment.