You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This package (repo) provides an implementation of a thread-safe, blocking, generic, infinite dequeue that can be used as FIFO or LIFO or a hybrid between the 2.
7
+
This package (repo) provides an implementation of a thread-safe, blocking, generic dequeue that can be used as FIFO or LIFO or a hybrid between the 2.
8
8
9
9
## Installation
10
10
@@ -32,11 +32,13 @@ To create a new dequeue use `blocking_dequeue.NewBlockingDequeue` function as fo
The dequeue is implemented using generics, so it can hold any datatype, just pass the data type you want between the square brackets `[ ]`.
60
+
The dequeue is implemented using generics, so it can hold any datatype, just create a buffer with the desired datatype and pass it to the creation function.
57
61
58
62
### Capacity
59
63
60
-
You can set a capacity if you want (the default is unlimited capacity)
61
-
62
-
```go
63
-
dequeue.SetCapacity(100) // Limit the dequeue to only carry 100 elements
64
-
dequeue.SetCapacity(0) // Infinite capacity (the default)
65
-
```
66
-
67
-
Some notes about setting the capacity:
68
-
69
-
- Pushing to the dequeue will block if it has full capacity, the goroutine will be blocked until some values are popped from the dequeue.
70
-
- As in the above example, setting the capacity to 0 means having infinite capacity.
71
-
- If you attempt the set the capacity to be lower than the current size of the dequeue, the method `SetCapacity` will return an error, and the capacity won't be updated. The same thing will also happen if you try to set the capacity with a negative number.
72
-
- You can always set the capacity to 0 regardless of the current size.
64
+
The capacity of the dequeue is the length of the provided buffer.
73
65
74
66
### Usage as Queue
75
67
76
68
```go
77
-
dq:= blocking_dequeue.NewBlockingDequeue[int]()
69
+
buffer:=make([]int, 10)
70
+
dq:= blocking_dequeue.NewBlockingDequeue(buffer)
78
71
79
72
dq.PushBack(1) // Pushed to the end of the dequeue
80
73
dq.PushBack(2) // Pushed to the end of the dequeue
@@ -88,7 +81,8 @@ dq.PopFront() // Pops from the top, returns 3
88
81
### Usage as Stack
89
82
90
83
```go
91
-
dq:= blocking_dequeue.NewBlockingDequeue[int]()
84
+
buffer:=make([]int, 10)
85
+
dq:= blocking_dequeue.NewBlockingDequeue(buffer)
92
86
93
87
dq.PushFront(1) // Pushed to the start of the dequeue
94
88
dq.PushFront(2) // Pushed to the start of the dequeue
@@ -108,22 +102,21 @@ The dequeue itself exposes the following methods:
108
102
-`PushFront`, `PushBack`
109
103
-`PopFront`, `PopBack`
110
104
-`PeekFront`, `PeekBack`
111
-
-`Capacity`, `SetCapacity`, `IsFull`
112
-
-`Size`, `IsEmpty`
105
+
-`Size`, `IsEmpty`, `IsFull`
113
106
114
107
The detailed documentation can be found at the related [go packages page](https://pkg.go.dev/github.com/AmrSaber/go-blocking-dequeue#section-documentation).
115
108
116
109
## Limitations and Drawbacks
117
110
118
-
This dequeue is implemented using build-in `container/list` so all of the operations are done in O(1) time complexity.
111
+
This dequeue is implemented using ring (or circular) buffer so all of the operations are done in O(1) time complexity.
119
112
120
-
However, due to the thread-safe nature, and all the lock/unlock/wait/signal/broadcast logic, it's expected to be a bit slower than the plain `container/list`. If you intend to use this dequeue in a single threaded context (where only a single goroutine will have access to it) it's advised to use the built-in `container/list` instead.
113
+
However, due to the thread-safe nature, and all the lock/unlock/wait/signal logic, it's expected to be a bit slower than plain ring buffer. If you intend to use this dequeue in a single threaded context (where only a single goroutine will have access to it) it's advised to use plain circular buffer or the built-in `container/list` instead.
121
114
122
115
If you intend to use it as a limited capacity queue to communicate between goroutines, it would be better to use built-in channels with buffer, so instead of
123
116
124
117
```go
125
-
dq:=blocking_dequeue.NewBlockingDequeue[int]()
126
-
dq.SetCapacity(10)
118
+
buffer:=make([]int, 10)
119
+
dq:= blocking_dequeue.NewBlockingDequeue(buffer)
127
120
128
121
// Push to queue
129
122
dq.PushBack(1)
@@ -148,7 +141,7 @@ That is unless you need access the other provided methods, such as `Peek` variat
148
141
149
142
## Benchmarking
150
143
151
-
No benchmarking against the built-in `container/list` nor channels yet. But it's in the plan.
144
+
No benchmarking against plain ring buffer or the built-in `container/list` nor channels yet. But it's in the plan.
0 commit comments