123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- package cache
- import (
- "container/list"
- )
- type lruCache struct {
- cache *cache
- cap int
- ls list.List
- }
- func (l *lruCache) init(c *cache, cap int) {
- l.cache = c
- l.cap = cap
- l.ls.Init()
- }
- func (l *lruCache) write(en *entry) *entry {
-
- if en.accessList != nil {
-
- l.markAccess(en)
- return nil
- }
-
- cen := l.cache.getOrSet(en)
- if cen == nil {
-
- en.accessList = l.ls.PushFront(en)
- } else {
-
- cen.setValue(en.getValue())
- cen.setWriteTime(en.getWriteTime())
- if cen.accessList == nil {
-
- cen.accessList = l.ls.PushFront(cen)
- } else {
- l.markAccess(cen)
- }
- }
- if l.cap > 0 && l.ls.Len() > l.cap {
-
- en = getEntry(l.ls.Back())
- return l.remove(en)
- }
- return nil
- }
- func (l *lruCache) access(en *entry) {
- if en.accessList != nil {
- l.markAccess(en)
- }
- }
- func (l *lruCache) markAccess(en *entry) {
- l.ls.MoveToFront(en.accessList)
- }
- func (l *lruCache) remove(en *entry) *entry {
- if en.accessList == nil {
-
- return nil
- }
- l.cache.delete(en)
- l.ls.Remove(en.accessList)
- en.accessList = nil
- return en
- }
- func (l *lruCache) iterate(fn func(en *entry) bool) {
- iterateListFromBack(&l.ls, fn)
- }
- const (
- admissionWindow uint8 = iota
- probationSegment
- protectedSegment
- )
- const (
- protectedRatio = 0.8
- )
- type slruCache struct {
- cache *cache
- probationCap int
- probationLs list.List
- protectedCap int
- protectedLs list.List
- }
- func (l *slruCache) init(c *cache, cap int) {
- l.cache = c
- l.protectedCap = int(float64(cap) * protectedRatio)
- l.probationCap = cap - l.protectedCap
- l.probationLs.Init()
- l.protectedLs.Init()
- }
- func (l *slruCache) length() int {
- return l.probationLs.Len() + l.protectedLs.Len()
- }
- func (l *slruCache) write(en *entry) *entry {
-
- if en.accessList != nil {
-
- l.markAccess(en)
- return nil
- }
-
- cen := l.cache.getOrSet(en)
- if cen == nil {
-
- en.listID = probationSegment
- en.accessList = l.probationLs.PushFront(en)
- } else {
-
- cen.setValue(en.getValue())
- cen.setWriteTime(en.getWriteTime())
- if cen.accessList == nil {
-
- cen.listID = probationSegment
- cen.accessList = l.probationLs.PushFront(cen)
- } else {
- l.markAccess(cen)
- }
- }
-
-
- if l.probationCap > 0 && l.probationLs.Len() > l.probationCap &&
- l.length() > (l.probationCap+l.protectedCap) {
-
- en = getEntry(l.probationLs.Back())
- return l.remove(en)
- }
- return nil
- }
- func (l *slruCache) access(en *entry) {
- if en.accessList != nil {
- l.markAccess(en)
- }
- }
- func (l *slruCache) markAccess(en *entry) {
- if en.listID == protectedSegment {
-
- l.protectedLs.MoveToFront(en.accessList)
- return
- }
-
- en.listID = protectedSegment
- l.probationLs.Remove(en.accessList)
- en.accessList = l.protectedLs.PushFront(en)
- if l.protectedCap > 0 && l.protectedLs.Len() > l.protectedCap {
-
-
- en = getEntry(l.protectedLs.Back())
- en.listID = probationSegment
- l.protectedLs.Remove(en.accessList)
- en.accessList = l.probationLs.PushFront(en)
- }
- }
- func (l *slruCache) remove(en *entry) *entry {
- if en.accessList == nil {
- return nil
- }
- l.cache.delete(en)
- if en.listID == protectedSegment {
- l.protectedLs.Remove(en.accessList)
- } else {
- l.probationLs.Remove(en.accessList)
- }
- en.accessList = nil
- return en
- }
- func (l *slruCache) victim() *entry {
- if l.probationCap <= 0 || l.length() < (l.probationCap+l.protectedCap) {
- return nil
- }
- el := l.probationLs.Back()
- if el == nil {
- return nil
- }
- return getEntry(el)
- }
- func (l *slruCache) iterate(fn func(en *entry) bool) {
- iterateListFromBack(&l.protectedLs, fn)
- iterateListFromBack(&l.probationLs, fn)
- }
|