Skip to content

Commit 0262637

Browse files
Simplify interface
Inline bounds checks are not always necessary and I'd rather not force a clunkier interface on users. Just write your own functions: func Pop(q *FlatQueue) (int, bool) { if q.Len() == 0 { return 0, false } return q.Pop(), true } func Peek(q *FlatQueue) (int, bool) { if q.Len() == 0 { return 0, false } return q.Peek(), true } func PeekValue(q *FlatQueue) (float64, bool) { if q.Len() == 0 { return 0, false } return q.PeekValue(), true }
1 parent a567c8b commit 0262637

File tree

3 files changed

+57
-88
lines changed

3 files changed

+57
-88
lines changed

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
A Go port of the [flatqueue](https://github.com/mourner/flatqueue) priority queue library. Push items by identifier (`int`) and value (`float64`).
44

5+
`Peek`, `PeekValue`, and `Pop` will panic if called on an empty queue. You must check `Len` accordingly.
6+
57
```go
68
q := flatqueue.New()
79

@@ -12,12 +14,11 @@ for i, item := range items {
1214
var (
1315
id int
1416
value float64
15-
ok bool
1617
)
1718

18-
id, ok = q.Peek() // top item index, ok if not empty
19-
value, ok = q.PeekValue() // top item value, ok if not empty
20-
id, ok = q.Pop() // remove and return the top item index, ok if not empty
19+
id = q.Peek() // top item index
20+
value = q.PeekValue() // top item value
21+
id = q.Pop() // remove and return the top item index
2122

2223
// loop while queue is not empty
2324
for q.Len() > 0 {

flatqueue.go

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,7 @@ func (q *FlatQueue) Push(id int, value float64) {
4646
q.values[pos] = value
4747
}
4848

49-
func (q *FlatQueue) Pop() (int, bool) {
50-
if q.length == 0 {
51-
return 0, false
52-
}
53-
49+
func (q *FlatQueue) Pop() int {
5450
top := q.ids[0]
5551
q.length--
5652

@@ -91,19 +87,13 @@ func (q *FlatQueue) Pop() (int, bool) {
9187
q.values[pos] = value
9288
}
9389

94-
return top, true
90+
return top
9591
}
9692

97-
func (q *FlatQueue) Peek() (int, bool) {
98-
if q.length == 0 {
99-
return 0, false
100-
}
101-
return q.ids[0], true
93+
func (q *FlatQueue) Peek() int {
94+
return q.ids[0]
10295
}
10396

104-
func (q *FlatQueue) PeekValue() (float64, bool) {
105-
if q.length == 0 {
106-
return 0, false
107-
}
108-
return q.values[0], true
97+
func (q *FlatQueue) PeekValue() float64 {
98+
return q.values[0]
10999
}

flatqueue_test.go

Lines changed: 46 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -29,25 +29,18 @@ func testMaintainsPriorityQueue(t *testing.T, n int, q *FlatQueue) {
2929
q.Push(i, v)
3030
}
3131

32-
v, ok := q.PeekValue()
33-
if v != sorted[0] || !ok {
32+
if q.PeekValue() != sorted[0] {
3433
t.Fatal()
3534
}
3635

37-
id, ok := q.Peek()
38-
if data[id] != sorted[0] || !ok {
36+
if data[q.Peek()] != sorted[0] {
3937
t.Fatal()
4038
}
4139

4240
result := make([]float64, n)
4341
i := 0
4442
for q.Len() > 0 {
45-
id, ok := q.Pop()
46-
if !ok {
47-
t.Fatal()
48-
}
49-
50-
result[i] = data[id]
43+
result[i] = data[q.Pop()]
5144
i++
5245
}
5346

@@ -81,10 +74,6 @@ func testLen(t *testing.T, q *FlatQueue) {
8174
if q.Pop(); q.Len() != 0 {
8275
t.Fatal()
8376
}
84-
85-
if q.Pop(); q.Len() != 0 {
86-
t.Fatal()
87-
}
8877
}
8978

9079
func TestPop(t *testing.T) {
@@ -93,28 +82,14 @@ func TestPop(t *testing.T) {
9382
}
9483

9584
func testPop(t *testing.T, q *FlatQueue) {
96-
// empty
97-
_, ok := q.Pop()
98-
if ok {
99-
t.Fatal()
100-
}
101-
10285
q.Push(1, 10)
10386
q.Push(2, 11)
10487

105-
id, ok := q.Pop()
106-
if id != 1 || !ok {
107-
t.Fatal()
108-
}
109-
110-
id, ok = q.Pop()
111-
if id != 2 || !ok {
88+
if q.Pop() != 1 {
11289
t.Fatal()
11390
}
11491

115-
// empty
116-
_, ok = q.Pop()
117-
if ok {
92+
if q.Pop() != 2 {
11893
t.Fatal()
11994
}
12095
}
@@ -127,40 +102,30 @@ func TestPeek(t *testing.T) {
127102
func testPeek(t *testing.T, q *FlatQueue) {
128103
q.Push(1, 10)
129104

130-
id, ok := q.Peek()
131-
if id != 1 || !ok {
105+
if q.Peek() != 1 {
132106
t.Fatal()
133107
}
134108

135109
q.Push(2, 11)
136110

137-
id, ok = q.Peek()
138-
if id != 1 || !ok {
111+
if q.Peek() != 1 {
139112
t.Fatal()
140113
}
141114

142115
q.Push(3, 9)
143116

144-
id, ok = q.Peek()
145-
if id != 3 || !ok {
117+
if q.Peek() != 3 {
146118
t.Fatal()
147119
}
148120

149121
q.Pop()
150122

151-
id, ok = q.Peek()
152-
if id != 1 || !ok {
123+
if q.Peek() != 1 {
153124
t.Fatal()
154125
}
155126

156127
q.Pop()
157128
q.Pop()
158-
159-
// empty
160-
_, ok = q.Peek()
161-
if ok {
162-
t.Fatal()
163-
}
164129
}
165130

166131
func TestPeekValue(t *testing.T) {
@@ -169,48 +134,32 @@ func TestPeekValue(t *testing.T) {
169134
}
170135

171136
func testPeekValue(t *testing.T, q *FlatQueue) {
172-
// empty
173-
_, ok := q.PeekValue()
174-
if ok {
175-
t.Fatal()
176-
}
177-
178137
q.Push(1, 10)
179138

180-
value, ok := q.PeekValue()
181-
if value != float64(10) || !ok {
139+
if q.PeekValue() != float64(10) {
182140
t.Fatal()
183141
}
184142

185143
q.Push(2, 11)
186144

187-
value, ok = q.PeekValue()
188-
if value != float64(10) || !ok {
145+
if q.PeekValue() != float64(10) {
189146
t.Fatal()
190147
}
191148

192149
q.Push(3, 9)
193150

194-
value, ok = q.PeekValue()
195-
if value != float64(9) || !ok {
151+
if q.PeekValue() != float64(9) {
196152
t.Fatal()
197153
}
198154

199155
q.Pop()
200156

201-
value, ok = q.PeekValue()
202-
if value != float64(10) || !ok {
157+
if q.PeekValue() != float64(10) {
203158
t.Fatal()
204159
}
205160

206161
q.Pop()
207162
q.Pop()
208-
209-
// empty
210-
_, ok = q.PeekValue()
211-
if ok {
212-
t.Fatal()
213-
}
214163
}
215164

216165
func TestEdgeCasesWithFewElements(t *testing.T) {
@@ -226,17 +175,42 @@ func testEdgeCasesWithFewElements(t *testing.T, q *FlatQueue) {
226175
q.Push(2, 2)
227176
q.Push(3, 1)
228177

229-
id, ok := q.Pop()
230-
if id != 3 || !ok {
178+
if q.Pop() != 3 {
231179
t.Fatal()
232180
}
233181

234-
id, ok = q.Pop()
235-
if id != 2 || !ok {
182+
if q.Pop() != 2 {
236183
t.Fatal()
237184
}
238185
}
239186

187+
func TestPeekEmpty(t *testing.T) {
188+
defer func() {
189+
if recover() == nil {
190+
t.Fatal()
191+
}
192+
}()
193+
New().Peek()
194+
}
195+
196+
func TestPeekValueEmpty(t *testing.T) {
197+
defer func() {
198+
if recover() == nil {
199+
t.Fatal()
200+
}
201+
}()
202+
New().PeekValue()
203+
}
204+
205+
func TestPopEmpty(t *testing.T) {
206+
defer func() {
207+
if recover() == nil {
208+
t.Fatal()
209+
}
210+
}()
211+
New().Pop()
212+
}
213+
240214
func BenchmarkPush(b *testing.B) {
241215
q := New()
242216

@@ -245,6 +219,7 @@ func BenchmarkPush(b *testing.B) {
245219
values[i] = randFloat64(-1000, 1000)
246220
}
247221

222+
b.ReportAllocs()
248223
b.ResetTimer()
249224

250225
for i := 0; i < b.N; i++ {
@@ -260,6 +235,7 @@ func BenchmarkPushWithCapacity(b *testing.B) {
260235
values[i] = randFloat64(-1000, 1000)
261236
}
262237

238+
b.ReportAllocs()
263239
b.ResetTimer()
264240

265241
for i := 0; i < b.N; i++ {
@@ -274,6 +250,7 @@ func BenchmarkPop(b *testing.B) {
274250
q.Push(i, randFloat64(-1000, 1000))
275251
}
276252

253+
b.ReportAllocs()
277254
b.ResetTimer()
278255

279256
for i := 0; i < b.N; i++ {
@@ -288,6 +265,7 @@ func BenchmarkPopWithCapacity(b *testing.B) {
288265
q.Push(i, randFloat64(-1000, 1000))
289266
}
290267

268+
b.ReportAllocs()
291269
b.ResetTimer()
292270

293271
for i := 0; i < b.N; i++ {

0 commit comments

Comments
 (0)