github.com/benz9527/toy-box/algo@v0.0.0-20240221120937-66c0c6bd5abd/queue/priority_queue_test.go (about) 1 package queue 2 3 import ( 4 "fmt" 5 "github.com/stretchr/testify/assert" 6 "testing" 7 "unsafe" 8 ) 9 10 type person struct { 11 name string 12 age int 13 salary int64 14 } 15 16 func TestPriorityQueueItemAlignmentAndSize(t *testing.T) { 17 item := NewPQItem[*person](&person{age: 10, name: "p0"}, 1) 18 t.Logf("item alignment size: %d\n", unsafe.Alignof(item)) 19 prototype := item.(*pqItem[*person]) 20 t.Logf("item prototype alignment size: %d\n", unsafe.Alignof(prototype)) 21 t.Logf("item prototype value alignment size: %d\n", unsafe.Alignof(prototype.value)) 22 t.Logf("item prototype priority alignment size: %d\n", unsafe.Alignof(prototype.priority)) 23 t.Logf("item prototype index alignment size: %d\n", unsafe.Alignof(prototype.index)) 24 t.Logf("item prototype comparator alignment size: %d\n", unsafe.Alignof(prototype.comparator)) 25 t.Logf("item prototype size: %d\n", unsafe.Sizeof(prototype)) 26 t.Logf("item prototype value size: %d\n", unsafe.Sizeof(prototype.value)) 27 t.Logf("item prototype priority size: %d\n", unsafe.Sizeof(prototype.priority)) 28 t.Logf("item prototype index size: %d\n", unsafe.Sizeof(prototype.index)) 29 t.Logf("item prototype comparator size: %d\n", unsafe.Sizeof(prototype.comparator)) 30 } 31 32 func TestPriorityQueue_MinValueAsHighPriority(t *testing.T) { 33 pq := NewArrayPriorityQueue[*person](32, 34 func(i, j PQItem[*person]) bool { 35 return i.GetPriority() < j.GetPriority() 36 }, 37 ) 38 pq.Push(NewPQItem[*person](&person{age: 10, name: "p0"}, 1)) 39 pq.Push(NewPQItem[*person](&person{age: 101, name: "p1"}, 101)) 40 pq.Push(NewPQItem[*person](&person{age: 10, name: "p2"}, 10)) 41 pq.Push(NewPQItem[*person](&person{age: 200, name: "p3"}, 200)) 42 pq.Push(NewPQItem[*person](&person{age: 3, name: "p4"}, 3)) 43 pq.Push(NewPQItem[*person](&person{age: 1, name: "p5"}, 1)) 44 pq.Push(NewPQItem[*person](&person{age: 5, name: "p6"}, 5)) 45 46 expectedPriorities := []int64{1, 1, 3, 5, 10, 101, 200} 47 for i, priority := range expectedPriorities { 48 item := pq.Pop() 49 t.Logf("%v, priority: %d", item.GetValue(), item.GetPriority()) 50 assert.Equal(t, priority, item.GetPriority(), "priority", i) 51 } 52 } 53 54 func TestPriorityQueue_MaxValueAsHighPriority(t *testing.T) { 55 pq := NewArrayPriorityQueue[*person](32, 56 func(i, j PQItem[*person]) bool { 57 return i.GetPriority() > j.GetPriority() 58 }, 59 ) 60 pq.Push(NewPQItem[*person](&person{age: 10, name: "p0"}, 1)) 61 pq.Push(NewPQItem[*person](&person{age: 101, name: "p1"}, 101)) 62 pq.Push(NewPQItem[*person](&person{age: 10, name: "p2"}, 10)) 63 pq.Push(NewPQItem[*person](&person{age: 200, name: "p3"}, 200)) 64 pq.Push(NewPQItem[*person](&person{age: 3, name: "p4"}, 3)) 65 pq.Push(NewPQItem[*person](&person{age: 1, name: "p5"}, 1)) 66 pq.Push(NewPQItem[*person](&person{age: 5, name: "p6"}, 5)) 67 pq.Push(NewPQItem[*person](&person{age: 200, name: "p7"}, 201)) 68 69 expectedPriorities := []int64{201, 200, 101, 10, 5, 3, 1, 1} 70 for i, priority := range expectedPriorities { 71 item := pq.Pop() 72 t.Logf("%v, priority: %d", item.GetValue(), item.GetPriority()) 73 assert.Equal(t, priority, item.GetPriority(), "priority", i) 74 } 75 } 76 77 func TestPriorityQueue_MaxValueAsHighPriority_Peek(t *testing.T) { 78 pq := NewArrayPriorityQueue[*person](32, 79 func(i, j PQItem[*person]) bool { 80 return i.GetPriority() > j.GetPriority() 81 }, 82 ) 83 pq.Push(NewPQItem[*person](&person{age: 10, name: "p0"}, 1)) 84 pq.Push(NewPQItem[*person](&person{age: 101, name: "p1"}, 101)) 85 pq.Push(NewPQItem[*person](&person{age: 10, name: "p2"}, 10)) 86 pq.Push(NewPQItem[*person](&person{age: 200, name: "p3"}, 200)) 87 pq.Push(NewPQItem[*person](&person{age: 3, name: "p4"}, 3)) 88 pq.Push(NewPQItem[*person](&person{age: 1, name: "p5"}, 1)) 89 pq.Push(NewPQItem[*person](&person{age: 5, name: "p6"}, 5)) 90 pq.Push(NewPQItem[*person](&person{age: 200, name: "p7"}, 201)) 91 92 expectedPriorities := []int64{201, 200, 101, 10, 5, 3, 1, 1} 93 for i, priority := range expectedPriorities { 94 peekItem := pq.Peek() 95 t.Logf("peek item: %v, priority: %d", peekItem.GetValue(), peekItem.GetPriority()) 96 item := pq.Pop() 97 t.Logf("%v, priority: %d", item.GetValue(), item.GetPriority()) 98 assert.Equal(t, priority, item.GetPriority(), "priority", i) 99 } 100 } 101 102 // goos: linux 103 // goarch: amd64 104 // pkg: github.com/benz9527/toy-box/algo/queue 105 // cpu: Intel(R) Core(TM) i5-4590 CPU @ 3.30GHz 106 // BenchmarkPriorityQueue_Push 107 // BenchmarkPriorityQueue_Push-4 4362896 229.8 ns/op 96 B/op 0 allocs/op 108 func BenchmarkPriorityQueue_Push(b *testing.B) { 109 var list = make([]PQItem[*person], 0, b.N) 110 for i := 0; i < b.N; i++ { 111 e := NewPQItem[*person](&person{age: i, name: fmt.Sprintf("p%d", i)}, int64(i)) 112 list = append(list, e) 113 } 114 b.ResetTimer() 115 pq := NewArrayPriorityQueue[*person](32, 116 func(i, j PQItem[*person]) bool { 117 return i.GetPriority() < j.GetPriority() 118 }, 119 ) 120 for i := 0; i < b.N; i++ { 121 pq.Push(list[i]) 122 } 123 b.ReportAllocs() 124 } 125 126 // goos: linux 127 // goarch: amd64 128 // pkg: github.com/benz9527/toy-box/algo/queue 129 // cpu: Intel(R) Core(TM) i5-4590 CPU @ 3.30GHz 130 // BenchmarkPriorityQueue_Pop 131 // BenchmarkPriorityQueue_Pop-4 818748 2113 ns/op 0 B/op 0 allocs/op 132 func BenchmarkPriorityQueue_Pop(b *testing.B) { 133 var list = make([]PQItem[*person], 0, b.N) 134 for i := 0; i < b.N; i++ { 135 e := NewPQItem[*person](&person{age: i, name: fmt.Sprintf("p%d", i)}, int64(i)) 136 list = append(list, e) 137 } 138 pq := NewArrayPriorityQueue[*person](32) 139 for i := 0; i < b.N; i++ { 140 pq.Push(list[i]) 141 } 142 b.ResetTimer() 143 for i := 0; i < b.N; i++ { 144 _ = pq.Pop() 145 } 146 b.ReportAllocs() 147 }