Skip to content

Commit

Permalink
[#17] Improve S3-FIFO
Browse files Browse the repository at this point in the history
  • Loading branch information
maypok86 committed Dec 11, 2023
1 parent 55a4bc5 commit a71450d
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 40 deletions.
12 changes: 12 additions & 0 deletions internal/s3fifo/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"github.com/maypok86/otter/internal/node"
)

const maxReinsertions = 20

type main[K comparable, V any] struct {
q *deque.Deque[*node.Node[K, V]]
cost uint32
Expand All @@ -26,6 +28,7 @@ func (m *main[K, V]) insert(n *node.Node[K, V]) {
}

func (m *main[K, V]) evict(deleted []*node.Node[K, V]) []*node.Node[K, V] {
reinsertions := 0
for m.cost > 0 {
n := m.q.PopFront()
if n.Meta.IsDeleted() {
Expand All @@ -41,6 +44,15 @@ func (m *main[K, V]) evict(deleted []*node.Node[K, V]) []*node.Node[K, V] {
return append(deleted, n)
}

// to avoid the worst case O(n), we remove the 20th reinserted consecutive element.
reinsertions++
if reinsertions >= maxReinsertions {
n.Meta = n.Meta.UnmarkMain().MarkDeleted()
m.cost -= n.Cost()
// can remove
return append(deleted, n)
}

m.q.PushBack(n)
n.Meta = n.Meta.DecrementFrequency()
}
Expand Down
26 changes: 10 additions & 16 deletions internal/s3fifo/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,44 +52,38 @@ func (p *Policy[K, V]) read(deleted []*node.Node[K, V], n *node.Node[K, V]) []*n
}

func (p *Policy[K, V]) insert(deleted []*node.Node[K, V], n *node.Node[K, V]) []*node.Node[K, V] {
for p.isFull() {
deleted = p.evict(deleted)
}

if n.Meta.IsDeleted() {
return deleted
}

if p.ghost.isGhost(n) {
if !n.Meta.IsMain() {
p.main.insert(n)
}
return deleted
p.main.insert(n)
} else {
p.small.insert(n)
}

if !n.Meta.IsSmall() {
p.small.insert(n)
for p.isFull() {
deleted = p.evict(deleted)
}

return deleted
}

func (p *Policy[K, V]) update(deleted []*node.Node[K, V], n *node.Node[K, V], costDiff uint32) []*node.Node[K, V] {
for p.isFull() {
deleted = p.evict(deleted)
}

if n.Meta.IsDeleted() {
return deleted
}

if n.Meta.IsSmall() {
p.small.cost += costDiff
}
if n.Meta.IsMain() {
} else if n.Meta.IsMain() {
p.main.cost += costDiff
}

for p.isFull() {
deleted = p.evict(deleted)
}

return deleted
}

Expand Down
46 changes: 22 additions & 24 deletions internal/s3fifo/small.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,34 +34,32 @@ func (s *small[K, V]) insert(n *node.Node[K, V]) {
}

func (s *small[K, V]) evict(deleted []*node.Node[K, V]) []*node.Node[K, V] {
for s.cost > 0 {
n := s.q.PopFront()
s.cost -= n.Cost()
n.Meta = n.Meta.UnmarkSmall()
if n.Meta.IsDeleted() {
return deleted
}
if n.IsExpired() {
n.Meta = n.Meta.MarkDeleted()
// can remove
return append(deleted, n)
}
if s.cost == 0 {
return deleted
}

if n.Meta.GetFrequency() > 1 {
if !n.Meta.IsMain() {
s.main.insert(n)
for s.main.isFull() {
deleted = s.main.evict(deleted)
}
n.Meta = n.Meta.ResetFrequency()
continue
}
}
n := s.q.PopFront()
s.cost -= n.Cost()
n.Meta = n.Meta.UnmarkSmall()
if n.Meta.IsDeleted() {
return deleted
}
if n.IsExpired() {
n.Meta = n.Meta.MarkDeleted()
// can remove
return append(deleted, n)
}

return s.ghost.insert(deleted, n)
if n.Meta.GetFrequency() > 1 {
s.main.insert(n)
for s.main.isFull() {
deleted = s.main.evict(deleted)
}
n.Meta = n.Meta.ResetFrequency()
return deleted
}

return deleted
return s.ghost.insert(deleted, n)
}

func (s *small[K, V]) length() int {
Expand Down

0 comments on commit a71450d

Please sign in to comment.