Skip to content

Commit dc3686f

Browse files
committed
Fix Push/Pop of LinkedListQueue by using DoublyListItem.(Shift/Unshift/Push/Pop are all different now)
1 parent 4eb92b5 commit dc3686f

File tree

1 file changed

+50
-25
lines changed

1 file changed

+50
-25
lines changed

queue.go

Lines changed: 50 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -241,11 +241,11 @@ func (listItem *DoublyListItem[T]) AddFirst(input *DoublyListItem[T]) *DoublyLis
241241

242242
// LinkedListQueue LinkedListQueue inspired by Collection utils
243243
type LinkedListQueue[T any] struct {
244-
first *LinkedListItem[T]
245-
last *LinkedListItem[T]
244+
first *DoublyListItem[T]
245+
last *DoublyListItem[T]
246246
count int
247247

248-
nodePoolFirst *LinkedListItem[T]
248+
nodePoolFirst *DoublyListItem[T]
249249
nodeCount int
250250
}
251251

@@ -277,14 +277,14 @@ func (q *LinkedListQueue[T]) KeepNodePoolCount(n int) {
277277
n--
278278
last := q.nodePoolFirst
279279
if last == nil {
280-
last = new(LinkedListItem[T])
280+
last = new(DoublyListItem[T])
281281
q.nodePoolFirst = last
282282
}
283283

284284
for n > 0 {
285285
n--
286286
if last.Next == nil {
287-
last.Next = new(LinkedListItem[T])
287+
last.Next = new(DoublyListItem[T])
288288
}
289289
last = last.Next
290290
}
@@ -298,6 +298,7 @@ func (q *LinkedListQueue[T]) Clear() {
298298
node := q.nodePoolFirst
299299
for node != nil {
300300
node.Val = nil
301+
node.Prev = nil
301302
node = node.Next
302303
}
303304

@@ -306,17 +307,17 @@ func (q *LinkedListQueue[T]) Clear() {
306307
q.count = 0
307308
}
308309

309-
// Put Put the T val(no-blocking)
310+
// Put Put the T val to the last position(no-blocking)
310311
func (q *LinkedListQueue[T]) Put(val T) error {
311312
return q.Offer(val)
312313
}
313314

314-
// Take Take the T val(no-blocking)
315+
// Take Take the T val from the first position(no-blocking)
315316
func (q *LinkedListQueue[T]) Take() (T, error) {
316317
return q.Poll()
317318
}
318319

319-
// Offer Offer the T val(non-blocking)
320+
// Offer Offer the T val to the last position(non-blocking)
320321
func (q *LinkedListQueue[T]) Offer(val T) error {
321322
// Try get from pool or new one
322323
node := q.generateNode()
@@ -329,13 +330,14 @@ func (q *LinkedListQueue[T]) Offer(val T) error {
329330
last := q.last
330331
if last != nil {
331332
last.Next = node
333+
node.Prev = last
332334
}
333335
q.last = node
334336

335337
return nil
336338
}
337339

338-
// Poll Poll the T val(non-blocking)
340+
// Poll Poll the T val from the first position(non-blocking)
339341
func (q *LinkedListQueue[T]) Poll() (T, error) {
340342
return q.Shift()
341343
}
@@ -362,15 +364,11 @@ func (q *LinkedListQueue[T]) Shift() (T, error) {
362364
if q.first == nil {
363365
q.last = nil
364366
}
365-
val := *node.Val
367+
val := node.Val
366368

367-
// Recycle
368-
q.nodeCount++
369-
node.Val = nil
370-
node.Next = q.nodePoolFirst
371-
q.nodePoolFirst = node
369+
q.recycleNode(node)
372370

373-
return val, nil
371+
return *val, nil
374372
}
375373

376374
// Unshift Unshift the T val to the first position(non-blocking)
@@ -386,34 +384,61 @@ func (q *LinkedListQueue[T]) Unshift(val T) error {
386384
first := q.first
387385
q.first = node
388386
node.Next = first
387+
if first != nil {
388+
first.Prev = node
389+
}
389390

390391
return nil
391392
}
392393

393-
// Pop Pop the data from the first position(non-blocking)
394+
// Pop Pop the data from the last position(non-blocking)
394395
func (q *LinkedListQueue[T]) Pop() (T, error) {
395-
val, err := q.Take()
396-
if err == ErrQueueIsEmpty {
397-
return val, ErrStackIsEmpty
396+
node := q.last
397+
if node == nil {
398+
return *new(T), ErrStackIsEmpty
399+
}
400+
401+
// Remove the last item
402+
q.count--
403+
q.last = node.Prev
404+
if q.last == nil {
405+
q.first = nil
398406
}
407+
val := node.Val
408+
q.recycleNode(node)
399409

400-
return val, err
410+
return *val, nil
401411
}
402412

403-
// Push Push the data from the first position(non-blocking)
413+
// Push Push the data to the last position(non-blocking)
404414
func (q *LinkedListQueue[T]) Push(val T) error {
405-
return q.Unshift(val)
415+
// return q.Unshift(val)
416+
return q.Offer(val)
406417
}
407418

408-
func (q *LinkedListQueue[T]) generateNode() *LinkedListItem[T] {
419+
func (q *LinkedListQueue[T]) generateNode() *DoublyListItem[T] {
409420
node := q.nodePoolFirst
410421
if node == nil {
411-
node = new(LinkedListItem[T])
422+
node = new(DoublyListItem[T])
412423
} else {
413424
q.nodeCount--
414425
q.nodePoolFirst = node.Next
415426
node.Next = nil
427+
node.Prev = nil
416428
}
417429

418430
return node
419431
}
432+
433+
func (q *LinkedListQueue[T]) recycleNode(node *DoublyListItem[T]) {
434+
if node == nil {
435+
return
436+
}
437+
438+
// Recycle
439+
q.nodeCount++
440+
node.Val = nil
441+
node.Next = q.nodePoolFirst
442+
node.Prev = nil
443+
q.nodePoolFirst = node
444+
}

0 commit comments

Comments
 (0)