Documentation
¶
Overview ¶
Package gqueue provides dynamic/static concurrent-safe queue.
Features:
1. FIFO queue(data -> list -> chan);
2. Fast creation and initialization;
3. Support dynamic queue size(unlimited queue size);
4. Blocking when reading data from queue;
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Queue ¶
type Queue[T comparable] struct { C chan T // Underlying channel for data reading. // contains filtered or unexported fields }
Queue is a concurrent-safe queue built on doubly linked list and channel.
func New ¶
func New[T comparable](limit ...int) *Queue[T]
New returns an empty queue object. Optional parameter `limit` is used to limit the size of the queue, which is unlimited in default. When `limit` is given, the queue will be static and high performance which is comparable with stdlib channel.
Example ¶
package main
import (
"context"
"fmt"
"time"
"github.com/wesleywu/gcontainer/gqueue"
"github.com/wesleywu/gcontainer/gtimer"
)
func main() {
n := 10
q := gqueue.New[int](100)
// Producer
for i := 0; i < n; i++ {
q.Push(i)
}
// Close the queue in three seconds.
gtimer.SetTimeout(context.Background(), time.Second*3, func(ctx context.Context) {
q.Close()
})
// The consumer constantly reads the queue data.
// If there is no data in the queue, it will block.
// The queue is read using the queue.C property exposed
// by the queue object and the selectIO multiplexing syntax
// example:
// for {
// select {
// case v := <-queue.C:
// if v != nil {
// fmt.Println(v)
// } else {
// return
// }
// }
// }
for {
v, ok := q.Pop()
if ok {
fmt.Print(v)
} else {
break
}
}
}
Output: 0123456789
func (*Queue[T]) Close ¶
func (q *Queue[T]) Close()
Close closes the queue. Notice: It would notify all goroutines return immediately, which are being blocked reading using Pop method.
Example ¶
package main
import (
"fmt"
"time"
"github.com/wesleywu/gcontainer/gqueue"
)
func main() {
q := gqueue.New[int]()
for i := 0; i < 10; i++ {
q.Push(i)
}
time.Sleep(time.Millisecond)
q.Close()
fmt.Println(q.Len())
fmt.Println(q.Pop())
// May Output:
// 0
// <nil>
}
Output:
func (*Queue[T]) Len ¶
Len returns the length of the queue. Note that the result might not be accurate if using unlimited queue size as there's an asynchronous channel reading the list constantly.
Example ¶
package main
import (
"fmt"
"github.com/wesleywu/gcontainer/gqueue"
)
func main() {
q := gqueue.New[int]()
q.Push(1)
q.Push(2)
fmt.Println(q.Len())
// May Output:
// 2
}
Output:
func (*Queue[T]) MustPop ¶
func (q *Queue[T]) MustPop() T
MustPop pops an item from the queue in FIFO way. Note that it would return empty value of T or nil if T is a pointer, when Pop is called after the queue is closed.
Example ¶
package main
import (
"fmt"
"github.com/wesleywu/gcontainer/gqueue"
)
type exampleQueueItem struct {
index int
}
func main() {
q := gqueue.New[*exampleQueueItem]()
for i := 0; i < 10; i++ {
q.Push(&exampleQueueItem{index: i})
}
fmt.Println(q.MustPop())
fmt.Println(q.MustPop())
fmt.Println(q.MustPop())
q.Close()
fmt.Println(q.MustPop())
}
Output: &{0} &{1} &{2} <nil>
func (*Queue[T]) Pop ¶
Pop pops an item from the queue in FIFO way, and a bool value indicating whether the channel is still open.
Example ¶
package main
import (
"fmt"
"github.com/wesleywu/gcontainer/gqueue"
)
func main() {
q := gqueue.New[int]()
for i := 0; i < 10; i++ {
q.Push(i)
}
v, ok := q.Pop()
fmt.Println(v, ok)
v, ok = q.Pop()
fmt.Println(v, ok)
v, ok = q.Pop()
fmt.Println(v, ok)
q.Close()
v, ok = q.Pop()
fmt.Println(v, ok)
}
Output: 0 true 1 true 2 true 0 false
func (*Queue[T]) Push ¶
func (q *Queue[T]) Push(v T)
Push pushes the data `v` into the queue. Note that it would panic if Push is called after the queue is closed.
Example ¶
package main
import (
"fmt"
"github.com/wesleywu/gcontainer/gqueue"
)
func main() {
q := gqueue.New[int]()
for i := 0; i < 10; i++ {
q.Push(i)
}
fmt.Println(q.MustPop())
fmt.Println(q.MustPop())
fmt.Println(q.MustPop())
}
Output: 0 1 2