Skip to content

Commit

Permalink
Merge pull request #40 from chenyanchen/fix/priotiry_queue_swap
Browse files Browse the repository at this point in the history
  • Loading branch information
Code-Hex authored May 10, 2023
2 parents 0cefe16 + 20c3c20 commit 9f98378
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 17 deletions.
34 changes: 17 additions & 17 deletions policy/lfu/priotiry_queue.go → policy/lfu/priority_queue.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,29 +40,29 @@ func newPriorityQueue[K comparable, V any](cap int) *priorityQueue[K, V] {
// see example of priority queue: https://pkg.go.dev/container/heap
var _ heap.Interface = (*priorityQueue[struct{}, interface{}])(nil)

func (l priorityQueue[K, V]) Len() int { return len(l) }
func (q priorityQueue[K, V]) Len() int { return len(q) }

func (l priorityQueue[K, V]) Less(i, j int) bool {
if l[i].referenceCount == l[j].referenceCount {
return l[i].referencedAt.Before(l[j].referencedAt)
func (q priorityQueue[K, V]) Less(i, j int) bool {
if q[i].referenceCount == q[j].referenceCount {
return q[i].referencedAt.Before(q[j].referencedAt)
}
return l[i].referenceCount < l[j].referenceCount
return q[i].referenceCount < q[j].referenceCount
}

func (l priorityQueue[K, V]) Swap(i, j int) {
l[i], l[j] = l[j], l[i]
l[i].index = i
l[i].index = j
func (q priorityQueue[K, V]) Swap(i, j int) {
q[i], q[j] = q[j], q[i]
q[i].index = i
q[j].index = j
}

func (l *priorityQueue[K, V]) Push(x interface{}) {
func (q *priorityQueue[K, V]) Push(x interface{}) {
entry := x.(*entry[K, V])
entry.index = len(*l)
*l = append(*l, entry)
entry.index = len(*q)
*q = append(*q, entry)
}

func (l *priorityQueue[K, V]) Pop() interface{} {
old := *l
func (q *priorityQueue[K, V]) Pop() interface{} {
old := *q
n := len(old)
entry := old[n-1]
old[n-1] = nil // avoid memory leak
Expand All @@ -71,12 +71,12 @@ func (l *priorityQueue[K, V]) Pop() interface{} {
for i := 0; i < len(new); i++ {
new[i].index = i
}
*l = new
*q = new
return entry
}

func (pq *priorityQueue[K, V]) update(e *entry[K, V], val V) {
func (q *priorityQueue[K, V]) update(e *entry[K, V], val V) {
e.val = val
e.referenced()
heap.Fix(pq, e.index)
heap.Fix(q, e.index)
}
40 changes: 40 additions & 0 deletions policy/lfu/priority_queue_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package lfu

import (
"container/heap"
"reflect"
"testing"
"time"
)
Expand Down Expand Up @@ -73,3 +74,42 @@ func TestPriorityQueue(t *testing.T) {
t.Errorf("want %d, but got %d", want, got)
}
}

func Test_priorityQueue_Swap(t *testing.T) {
type args struct {
i int
j int
}
type testCase[K comparable, V any] struct {
name string
q *priorityQueue[K, V]
args args
want *priorityQueue[K, V]
}
tests := []testCase[string, int]{
{
name: "swap case",
q: func() *priorityQueue[string, int] {
q := newPriorityQueue[string, int](10)
q.Push(&entry[string, int]{index: 0})
q.Push(&entry[string, int]{index: 1})
return q
}(),
args: args{i: 0, j: 1},
want: func() *priorityQueue[string, int] {
q := newPriorityQueue[string, int](10)
q.Push(&entry[string, int]{index: 1})
q.Push(&entry[string, int]{index: 0})
return q
}(),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.q.Swap(tt.args.i, tt.args.j)
if !reflect.DeepEqual(tt.q, tt.want) {
t.Errorf("want %v, got %v", tt.want, tt.q)
}
})
}
}

0 comments on commit 9f98378

Please sign in to comment.