7
7
)
8
8
9
9
func TestPriorityQueue (t * testing.T ) {
10
- t .Run ("operations" , func (t * testing.T ) {
10
+ t .Run ("basic operations" , func (t * testing.T ) {
11
11
tests := []struct {
12
12
name string
13
13
input []int
@@ -33,16 +33,14 @@ func TestPriorityQueue(t *testing.T) {
33
33
input : []int {3 , 1 , 2 },
34
34
wantPops : []int {1 , 2 , 3 },
35
35
},
36
- {
37
- name : "duplicate elements" ,
38
- input : []int {2 , 1 , 2 , 1 },
39
- wantPops : []int {1 , 1 , 2 , 2 },
40
- },
41
36
}
42
37
43
38
for _ , tt := range tests {
44
39
t .Run (tt .name , func (t * testing.T ) {
45
- pq := NewPriorityQueue [int ](func (a , b int ) bool { return a < b })
40
+ pq := NewPriorityQueue [int , int ](
41
+ func (a , b int ) bool { return a < b },
42
+ func (v int ) int { return v },
43
+ )
46
44
require .Equal (t , 0 , pq .Len ())
47
45
48
46
// Push all elements
@@ -69,15 +67,73 @@ func TestPriorityQueue(t *testing.T) {
69
67
}
70
68
})
71
69
70
+ t .Run ("key operations" , func (t * testing.T ) {
71
+ type Job struct {
72
+ ID string
73
+ Priority int
74
+ }
75
+
76
+ pq := NewPriorityQueue [string , Job ](
77
+ func (a , b Job ) bool { return a .Priority < b .Priority },
78
+ func (j Job ) string { return j .ID },
79
+ )
80
+
81
+ // Test Push with duplicate key
82
+ job1 := Job {ID : "job1" , Priority : 1 }
83
+ job1Updated := Job {ID : "job1" , Priority : 3 }
84
+ job2 := Job {ID : "job2" , Priority : 2 }
85
+
86
+ pq .Push (job1 )
87
+ require .Equal (t , 1 , pq .Len ())
88
+
89
+ // Push with same key should update
90
+ pq .Push (job1Updated )
91
+ require .Equal (t , 1 , pq .Len ())
92
+
93
+ // Verify updated priority
94
+ v , ok := pq .Lookup ("job1" )
95
+ require .True (t , ok )
96
+ require .Equal (t , job1Updated , v )
97
+
98
+ // Test Remove
99
+ pq .Push (job2 )
100
+ v , ok = pq .Remove ("job1" )
101
+ require .True (t , ok )
102
+ require .Equal (t , job1Updated , v )
103
+ require .Equal (t , 1 , pq .Len ())
104
+
105
+ // Test UpdatePriority
106
+ newJob2 := Job {ID : "job2" , Priority : 4 }
107
+ ok = pq .UpdatePriority ("job2" , newJob2 )
108
+ require .True (t , ok )
109
+
110
+ v , ok = pq .Lookup ("job2" )
111
+ require .True (t , ok )
112
+ require .Equal (t , newJob2 , v )
113
+
114
+ // Test non-existent key operations
115
+ v , ok = pq .Lookup ("nonexistent" )
116
+ require .False (t , ok )
117
+ require .Zero (t , v )
118
+
119
+ v , ok = pq .Remove ("nonexistent" )
120
+ require .False (t , ok )
121
+ require .Zero (t , v )
122
+
123
+ ok = pq .UpdatePriority ("nonexistent" , Job {})
124
+ require .False (t , ok )
125
+ })
126
+
72
127
t .Run ("custom type" , func (t * testing.T ) {
73
128
type Job struct {
74
129
ID string
75
130
Priority int
76
131
}
77
132
78
- pq := NewPriorityQueue [Job ](func (a , b Job ) bool {
79
- return a .Priority < b .Priority
80
- })
133
+ pq := NewPriorityQueue [string , Job ](
134
+ func (a , b Job ) bool { return a .Priority < b .Priority },
135
+ func (j Job ) string { return j .ID },
136
+ )
81
137
82
138
jobs := []Job {
83
139
{ID : "high" , Priority : 3 },
@@ -102,25 +158,28 @@ func TestPriorityQueue(t *testing.T) {
102
158
})
103
159
104
160
t .Run ("mixed operations" , func (t * testing.T ) {
105
- pq := NewPriorityQueue [int ](func (a , b int ) bool { return a < b })
161
+ pq := NewPriorityQueue [int , int ](
162
+ func (a , b int ) bool { return a < b },
163
+ func (v int ) int { return v },
164
+ )
106
165
107
166
// Push some elements
108
167
pq .Push (3 )
109
168
pq .Push (1 )
110
- require . Equal ( t , 2 , pq .Len () )
169
+ pq .Push ( 4 )
111
170
112
- // Pop lowest
171
+ // Pop an element
113
172
v , ok := pq .Pop ()
114
173
require .True (t , ok )
115
174
require .Equal (t , 1 , v )
116
175
117
176
// Push more elements
118
177
pq .Push (2 )
119
- pq .Push (4 )
178
+ pq .Push (5 )
120
179
121
- // Verify remaining elements come out in order
122
- want := []int {2 , 3 , 4 }
123
- got := make ([]int , 0 , 3 )
180
+ // Pop remaining elements and verify order
181
+ want := []int {2 , 3 , 4 , 5 }
182
+ got := make ([]int , 0 , len ( want ) )
124
183
for range want {
125
184
v , ok := pq .Pop ()
126
185
require .True (t , ok )
@@ -191,3 +250,54 @@ func TestCircularBuffer(t *testing.T) {
191
250
})
192
251
}
193
252
}
253
+
254
+ func TestCircularBufferLookup (t * testing.T ) {
255
+ t .Run ("empty buffer" , func (t * testing.T ) {
256
+ cb := NewCircularBuffer [int ](5 )
257
+ _ , ok := cb .Lookup (func (i int ) bool { return i == 1 })
258
+ require .False (t , ok )
259
+ })
260
+
261
+ t .Run ("single element" , func (t * testing.T ) {
262
+ cb := NewCircularBuffer [int ](5 )
263
+ cb .Push (1 )
264
+ v , ok := cb .Lookup (func (i int ) bool { return i == 1 })
265
+ require .True (t , ok )
266
+ require .Equal (t , 1 , v )
267
+ })
268
+
269
+ t .Run ("multiple elements" , func (t * testing.T ) {
270
+ cb := NewCircularBuffer [int ](5 )
271
+ for i := 1 ; i <= 3 ; i ++ {
272
+ cb .Push (i )
273
+ }
274
+ v , ok := cb .Lookup (func (i int ) bool { return i == 2 })
275
+ require .True (t , ok )
276
+ require .Equal (t , 2 , v )
277
+ })
278
+
279
+ t .Run ("wrapped buffer" , func (t * testing.T ) {
280
+ cb := NewCircularBuffer [int ](3 )
281
+ // Push 5 elements into a buffer of size 3, causing wrap-around
282
+ for i := 1 ; i <= 5 ; i ++ {
283
+ cb .Push (i )
284
+ }
285
+ // Buffer should now contain [4,5,3] with head at index 2
286
+ v , ok := cb .Lookup (func (i int ) bool { return i == 4 })
287
+ require .True (t , ok )
288
+ require .Equal (t , 4 , v )
289
+
290
+ // Element that was evicted should not be found
291
+ _ , ok = cb .Lookup (func (i int ) bool { return i == 1 })
292
+ require .False (t , ok )
293
+ })
294
+
295
+ t .Run ("no match" , func (t * testing.T ) {
296
+ cb := NewCircularBuffer [int ](5 )
297
+ for i := 1 ; i <= 3 ; i ++ {
298
+ cb .Push (i )
299
+ }
300
+ _ , ok := cb .Lookup (func (i int ) bool { return i == 99 })
301
+ require .False (t , ok )
302
+ })
303
+ }
0 commit comments