Skip to content

Commit 064f3ea

Browse files
Merge pull request #102 from ichinaski/master
Add support for duplicated items in PriorityQueue
2 parents be34045 + 11a2866 commit 064f3ea

File tree

2 files changed

+37
-23
lines changed

2 files changed

+37
-23
lines changed

queue/priority_queue.go

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,13 @@ func (items *priorityItems) push(item Item) {
105105
// items that implement the Item interface and adds them
106106
// to the queue in priority order.
107107
type PriorityQueue struct {
108-
waiters waiters
109-
items priorityItems
110-
itemMap map[Item]struct{}
111-
lock sync.Mutex
112-
disposeLock sync.Mutex
113-
disposed bool
108+
waiters waiters
109+
items priorityItems
110+
itemMap map[Item]struct{}
111+
lock sync.Mutex
112+
disposeLock sync.Mutex
113+
disposed bool
114+
allowDuplicates bool
114115
}
115116

116117
// Put adds items to the queue.
@@ -127,7 +128,9 @@ func (pq *PriorityQueue) Put(items ...Item) error {
127128
}
128129

129130
for _, item := range items {
130-
if _, ok := pq.itemMap[item]; !ok {
131+
if pq.allowDuplicates {
132+
pq.items.push(item)
133+
} else if _, ok := pq.itemMap[item]; !ok {
131134
pq.itemMap[item] = struct{}{}
132135
pq.items.push(item)
133136
}
@@ -186,7 +189,9 @@ func (pq *PriorityQueue) Get(number int) ([]Item, error) {
186189
}
187190

188191
items = pq.items.get(number)
189-
deleteItems(items)
192+
if !pq.allowDuplicates {
193+
deleteItems(items)
194+
}
190195
sema.response.Done()
191196
return items, nil
192197
}
@@ -252,9 +257,10 @@ func (pq *PriorityQueue) Dispose() {
252257
}
253258

254259
// NewPriorityQueue is the constructor for a priority queue.
255-
func NewPriorityQueue(hint int) *PriorityQueue {
260+
func NewPriorityQueue(hint int, allowDuplicates bool) *PriorityQueue {
256261
return &PriorityQueue{
257-
items: make(priorityItems, 0, hint),
258-
itemMap: make(map[Item]struct{}, hint),
262+
items: make(priorityItems, 0, hint),
263+
itemMap: make(map[Item]struct{}, hint),
264+
allowDuplicates: allowDuplicates,
259265
}
260266
}

queue/priority_queue_test.go

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import (
2424
)
2525

2626
func TestPriorityPut(t *testing.T) {
27-
q := NewPriorityQueue(1)
27+
q := NewPriorityQueue(1, false)
2828

2929
q.Put(mockItem(2))
3030

@@ -41,7 +41,7 @@ func TestPriorityPut(t *testing.T) {
4141
}
4242

4343
func TestPriorityGet(t *testing.T) {
44-
q := NewPriorityQueue(1)
44+
q := NewPriorityQueue(1, false)
4545

4646
q.Put(mockItem(2))
4747
result, err := q.Get(2)
@@ -84,15 +84,15 @@ func TestPriorityGet(t *testing.T) {
8484
}
8585

8686
func TestAddEmptyPriorityPut(t *testing.T) {
87-
q := NewPriorityQueue(1)
87+
q := NewPriorityQueue(1, false)
8888

8989
q.Put()
9090

9191
assert.Len(t, q.items, 0)
9292
}
9393

9494
func TestPriorityGetNonPositiveNumber(t *testing.T) {
95-
q := NewPriorityQueue(1)
95+
q := NewPriorityQueue(1, false)
9696

9797
q.Put(mockItem(1))
9898

@@ -112,7 +112,7 @@ func TestPriorityGetNonPositiveNumber(t *testing.T) {
112112
}
113113

114114
func TestPriorityEmpty(t *testing.T) {
115-
q := NewPriorityQueue(1)
115+
q := NewPriorityQueue(1, false)
116116
assert.True(t, q.Empty())
117117

118118
q.Put(mockItem(1))
@@ -121,7 +121,7 @@ func TestPriorityEmpty(t *testing.T) {
121121
}
122122

123123
func TestPriorityGetEmpty(t *testing.T) {
124-
q := NewPriorityQueue(1)
124+
q := NewPriorityQueue(1, false)
125125

126126
go func() {
127127
q.Put(mockItem(1))
@@ -139,7 +139,7 @@ func TestPriorityGetEmpty(t *testing.T) {
139139
}
140140

141141
func TestMultiplePriorityGetEmpty(t *testing.T) {
142-
q := NewPriorityQueue(1)
142+
q := NewPriorityQueue(1, false)
143143
var wg sync.WaitGroup
144144
wg.Add(2)
145145
results := make([][]Item, 2)
@@ -175,7 +175,7 @@ func TestMultiplePriorityGetEmpty(t *testing.T) {
175175
}
176176

177177
func TestEmptyPriorityGetWithDispose(t *testing.T) {
178-
q := NewPriorityQueue(1)
178+
q := NewPriorityQueue(1, false)
179179
var wg sync.WaitGroup
180180
wg.Add(1)
181181

@@ -197,7 +197,7 @@ func TestEmptyPriorityGetWithDispose(t *testing.T) {
197197
}
198198

199199
func TestPriorityGetPutDisposed(t *testing.T) {
200-
q := NewPriorityQueue(1)
200+
q := NewPriorityQueue(1, false)
201201
q.Dispose()
202202

203203
_, err := q.Get(1)
@@ -208,7 +208,7 @@ func TestPriorityGetPutDisposed(t *testing.T) {
208208
}
209209

210210
func BenchmarkPriorityQueue(b *testing.B) {
211-
q := NewPriorityQueue(b.N)
211+
q := NewPriorityQueue(b.N, false)
212212
var wg sync.WaitGroup
213213
wg.Add(1)
214214
i := 0
@@ -232,16 +232,24 @@ func BenchmarkPriorityQueue(b *testing.B) {
232232
}
233233

234234
func TestPriorityPeek(t *testing.T) {
235-
q := NewPriorityQueue(1)
235+
q := NewPriorityQueue(1, false)
236236
q.Put(mockItem(1))
237237

238238
assert.Equal(t, mockItem(1), q.Peek())
239239
}
240240

241241
func TestInsertDuplicate(t *testing.T) {
242-
q := NewPriorityQueue(1)
242+
q := NewPriorityQueue(1, false)
243243
q.Put(mockItem(1))
244244
q.Put(mockItem(1))
245245

246246
assert.Equal(t, 1, q.Len())
247247
}
248+
249+
func TestAllowDuplicates(t *testing.T) {
250+
q := NewPriorityQueue(2, true)
251+
q.Put(mockItem(1))
252+
q.Put(mockItem(1))
253+
254+
assert.Equal(t, 2, q.Len())
255+
}

0 commit comments

Comments
 (0)