philiprehberger-queue_stack 0.1.4 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +19 -0
- data/README.md +74 -0
- data/lib/philiprehberger/queue_stack/queue.rb +108 -3
- data/lib/philiprehberger/queue_stack/stack.rb +108 -3
- data/lib/philiprehberger/queue_stack/version.rb +1 -1
- data/lib/philiprehberger/queue_stack.rb +1 -0
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 61b9b755594ffadcc05a80b942c0424a29043da9e01c81bc41045c5d440156e1
|
|
4
|
+
data.tar.gz: 823d4982ec931ecf197a42e37ceb7439939a4e6e06070d22ceb437eb1985f2e4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0c2f235cd8a6f31bafd5d94af63806e3caabc0fff8743b82815ff90df255f74dbf6d924edccb57e5d73f0fef65958b1c7231e60e96bc9dde9aee3e94718ce0fd
|
|
7
|
+
data.tar.gz: 35d25847836f39bbd80fd7aa8ff07005c126cec030be1d1e9908a4d428d8f96cf2b662167cce8428314aefd7a1ce2384179dd8489e132f1635333e2ffd1dec48
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.3.0] - 2026-04-09
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- `Queue#try_enqueue(item, timeout: nil)` and `Stack#try_push(item, timeout: nil)` non-blocking insertion variants
|
|
14
|
+
- `Queue#clear` and `Stack#clear` to discard all items and wake blocked producers
|
|
15
|
+
|
|
16
|
+
## [0.2.0] - 2026-04-03
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
- `drain` method to remove and return all items at once
|
|
20
|
+
- `each` and `to_a` for non-destructive iteration
|
|
21
|
+
- `close` / `closed?` for graceful shutdown semantics
|
|
22
|
+
- `ClosedError` raised when adding to a closed container
|
|
23
|
+
|
|
24
|
+
## [0.1.5] - 2026-03-31
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
- Add GitHub issue templates, dependabot config, and PR template
|
|
28
|
+
|
|
10
29
|
## [0.1.4] - 2026-03-31
|
|
11
30
|
|
|
12
31
|
### Changed
|
data/README.md
CHANGED
|
@@ -66,6 +66,66 @@ s = Philiprehberger::QueueStack::Stack.new
|
|
|
66
66
|
item = s.try_pop(timeout: 5) # waits up to 5 seconds
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
+
### Drain
|
|
70
|
+
|
|
71
|
+
```ruby
|
|
72
|
+
q = Philiprehberger::QueueStack::Queue.new
|
|
73
|
+
q.enqueue('a')
|
|
74
|
+
q.enqueue('b')
|
|
75
|
+
q.enqueue('c')
|
|
76
|
+
q.drain # => ['a', 'b', 'c'] (queue is now empty)
|
|
77
|
+
|
|
78
|
+
s = Philiprehberger::QueueStack::Stack.new
|
|
79
|
+
s.push('a')
|
|
80
|
+
s.push('b')
|
|
81
|
+
s.push('c')
|
|
82
|
+
s.drain # => ['c', 'b', 'a'] (stack is now empty)
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Iteration
|
|
86
|
+
|
|
87
|
+
```ruby
|
|
88
|
+
q = Philiprehberger::QueueStack::Queue.new
|
|
89
|
+
q.enqueue('a')
|
|
90
|
+
q.enqueue('b')
|
|
91
|
+
q.each { |item| puts item } # prints 'a', 'b'
|
|
92
|
+
q.to_a # => ['a', 'b'] (queue unchanged)
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Non-Blocking Insertion
|
|
96
|
+
|
|
97
|
+
```ruby
|
|
98
|
+
q = Philiprehberger::QueueStack::Queue.new(capacity: 1)
|
|
99
|
+
q.enqueue('a')
|
|
100
|
+
q.try_enqueue('b') # => false (full, no wait)
|
|
101
|
+
q.try_enqueue('b', timeout: 0.5) # => false after waiting up to 0.5s
|
|
102
|
+
|
|
103
|
+
s = Philiprehberger::QueueStack::Stack.new(capacity: 1)
|
|
104
|
+
s.push('a')
|
|
105
|
+
s.try_push('b') # => false (full, no wait)
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Clear
|
|
109
|
+
|
|
110
|
+
```ruby
|
|
111
|
+
q = Philiprehberger::QueueStack::Queue.new
|
|
112
|
+
q.enqueue('a'); q.enqueue('b')
|
|
113
|
+
q.clear
|
|
114
|
+
q.empty? # => true
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Close / Shutdown
|
|
118
|
+
|
|
119
|
+
```ruby
|
|
120
|
+
q = Philiprehberger::QueueStack::Queue.new
|
|
121
|
+
q.enqueue('a')
|
|
122
|
+
q.close
|
|
123
|
+
q.closed? # => true
|
|
124
|
+
q.dequeue # => 'a'
|
|
125
|
+
q.dequeue # => nil (closed and empty)
|
|
126
|
+
q.enqueue('b') # raises Philiprehberger::QueueStack::ClosedError
|
|
127
|
+
```
|
|
128
|
+
|
|
69
129
|
### Capacity Limits
|
|
70
130
|
|
|
71
131
|
```ruby
|
|
@@ -84,9 +144,16 @@ q.full? # => true
|
|
|
84
144
|
|--------|-------------|
|
|
85
145
|
| `.new(capacity:)` | Create a queue with optional capacity limit |
|
|
86
146
|
| `#enqueue(item)` | Add item to back (blocks if full) |
|
|
147
|
+
| `#try_enqueue(item, timeout: nil)` | Non-blocking enqueue, returns true/false (waits up to timeout if given) |
|
|
87
148
|
| `#dequeue` | Remove and return front item (blocks if empty) |
|
|
88
149
|
| `#try_dequeue(timeout:)` | Dequeue with timeout, returns nil on timeout |
|
|
150
|
+
| `#clear` | Remove all items without returning them |
|
|
89
151
|
| `#peek` | View front item without removing |
|
|
152
|
+
| `#drain` | Remove and return all items as array (FIFO order) |
|
|
153
|
+
| `#each` | Iterate items without removing (returns Enumerator if no block) |
|
|
154
|
+
| `#to_a` | Snapshot as array (FIFO order) |
|
|
155
|
+
| `#close` | Mark as closed (new enqueues raise `ClosedError`) |
|
|
156
|
+
| `#closed?` | Whether the queue has been closed |
|
|
90
157
|
| `#size` | Number of items |
|
|
91
158
|
| `#empty?` | Whether the queue is empty |
|
|
92
159
|
| `#full?` | Whether the queue is at capacity |
|
|
@@ -97,9 +164,16 @@ q.full? # => true
|
|
|
97
164
|
|--------|-------------|
|
|
98
165
|
| `.new(capacity:)` | Create a stack with optional capacity limit |
|
|
99
166
|
| `#push(item)` | Push item on top (blocks if full) |
|
|
167
|
+
| `#try_push(item, timeout: nil)` | Non-blocking push, returns true/false (waits up to timeout if given) |
|
|
100
168
|
| `#pop` | Remove and return top item (blocks if empty) |
|
|
101
169
|
| `#try_pop(timeout:)` | Pop with timeout, returns nil on timeout |
|
|
170
|
+
| `#clear` | Remove all items without returning them |
|
|
102
171
|
| `#peek` | View top item without removing |
|
|
172
|
+
| `#drain` | Remove and return all items as array (LIFO order) |
|
|
173
|
+
| `#each` | Iterate items without removing (returns Enumerator if no block) |
|
|
174
|
+
| `#to_a` | Snapshot as array (LIFO order) |
|
|
175
|
+
| `#close` | Mark as closed (new pushes raise `ClosedError`) |
|
|
176
|
+
| `#closed?` | Whether the stack has been closed |
|
|
103
177
|
| `#size` | Number of items |
|
|
104
178
|
| `#empty?` | Whether the stack is empty |
|
|
105
179
|
| `#full?` | Whether the stack is at capacity |
|
|
@@ -9,12 +9,15 @@ module Philiprehberger
|
|
|
9
9
|
# q.enqueue('item')
|
|
10
10
|
# q.dequeue # => 'item'
|
|
11
11
|
class Queue
|
|
12
|
+
include Enumerable
|
|
13
|
+
|
|
12
14
|
# Create a new queue.
|
|
13
15
|
#
|
|
14
16
|
# @param capacity [Integer, nil] maximum number of items (nil for unlimited)
|
|
15
17
|
def initialize(capacity: nil)
|
|
16
18
|
@items = []
|
|
17
19
|
@capacity = capacity
|
|
20
|
+
@closed = false
|
|
18
21
|
@mutex = Mutex.new
|
|
19
22
|
@not_empty = ConditionVariable.new
|
|
20
23
|
@not_full = ConditionVariable.new
|
|
@@ -24,26 +27,75 @@ module Philiprehberger
|
|
|
24
27
|
#
|
|
25
28
|
# @param item [Object] the item to enqueue
|
|
26
29
|
# @return [void]
|
|
30
|
+
# @raise [ClosedError] if the queue has been closed
|
|
27
31
|
def enqueue(item)
|
|
28
32
|
@mutex.synchronize do
|
|
33
|
+
raise ClosedError, 'cannot enqueue on a closed queue' if @closed
|
|
34
|
+
|
|
29
35
|
@not_full.wait(@mutex) while @capacity && @items.length >= @capacity
|
|
30
36
|
@items.push(item)
|
|
31
37
|
@not_empty.signal
|
|
32
38
|
end
|
|
33
39
|
end
|
|
34
40
|
|
|
35
|
-
# Remove and return the front item. Blocks if empty.
|
|
41
|
+
# Remove and return the front item. Blocks if empty (returns nil if closed and empty).
|
|
36
42
|
#
|
|
37
|
-
# @return [Object] the dequeued item
|
|
43
|
+
# @return [Object, nil] the dequeued item or nil if closed and empty
|
|
38
44
|
def dequeue
|
|
39
45
|
@mutex.synchronize do
|
|
40
|
-
|
|
46
|
+
while @items.empty?
|
|
47
|
+
return nil if @closed
|
|
48
|
+
|
|
49
|
+
@not_empty.wait(@mutex)
|
|
50
|
+
end
|
|
41
51
|
item = @items.shift
|
|
42
52
|
@not_full.signal
|
|
43
53
|
item
|
|
44
54
|
end
|
|
45
55
|
end
|
|
46
56
|
|
|
57
|
+
# Try to enqueue an item without blocking indefinitely.
|
|
58
|
+
#
|
|
59
|
+
# With timeout: nil, returns immediately. With a numeric timeout, waits up to
|
|
60
|
+
# that many seconds for space to become available.
|
|
61
|
+
#
|
|
62
|
+
# @param item [Object] the item to enqueue
|
|
63
|
+
# @param timeout [Numeric, nil] seconds to wait, or nil for non-blocking
|
|
64
|
+
# @return [Boolean] true if enqueued, false if full (or timed out)
|
|
65
|
+
# @raise [ClosedError] if the queue has been closed
|
|
66
|
+
def try_enqueue(item, timeout: nil)
|
|
67
|
+
@mutex.synchronize do
|
|
68
|
+
raise ClosedError, 'cannot enqueue on a closed queue' if @closed
|
|
69
|
+
|
|
70
|
+
if @capacity && @items.length >= @capacity
|
|
71
|
+
return false if timeout.nil? || timeout <= 0
|
|
72
|
+
|
|
73
|
+
deadline = Time.now + timeout
|
|
74
|
+
while @items.length >= @capacity
|
|
75
|
+
remaining = deadline - Time.now
|
|
76
|
+
return false if remaining <= 0
|
|
77
|
+
|
|
78
|
+
@not_full.wait(@mutex, remaining)
|
|
79
|
+
raise ClosedError, 'cannot enqueue on a closed queue' if @closed
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
@items.push(item)
|
|
84
|
+
@not_empty.signal
|
|
85
|
+
true
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Remove all items without returning them. Signals any blocked producers.
|
|
90
|
+
#
|
|
91
|
+
# @return [void]
|
|
92
|
+
def clear
|
|
93
|
+
@mutex.synchronize do
|
|
94
|
+
@items.clear
|
|
95
|
+
@not_full.broadcast
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
47
99
|
# Try to dequeue an item with a timeout.
|
|
48
100
|
#
|
|
49
101
|
# @param timeout [Numeric] seconds to wait
|
|
@@ -52,6 +104,8 @@ module Philiprehberger
|
|
|
52
104
|
deadline = Time.now + timeout
|
|
53
105
|
@mutex.synchronize do
|
|
54
106
|
while @items.empty?
|
|
107
|
+
return nil if @closed
|
|
108
|
+
|
|
55
109
|
remaining = deadline - Time.now
|
|
56
110
|
return nil if remaining <= 0
|
|
57
111
|
|
|
@@ -63,6 +117,57 @@ module Philiprehberger
|
|
|
63
117
|
end
|
|
64
118
|
end
|
|
65
119
|
|
|
120
|
+
# Remove and return all items as an array (FIFO order). Non-blocking.
|
|
121
|
+
#
|
|
122
|
+
# @return [Array] all items in FIFO order
|
|
123
|
+
def drain
|
|
124
|
+
@mutex.synchronize do
|
|
125
|
+
result = @items.dup
|
|
126
|
+
@items.clear
|
|
127
|
+
@not_full.broadcast
|
|
128
|
+
result
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# Iterate items without removing them (snapshot of current state, FIFO order).
|
|
133
|
+
# Returns an Enumerator if no block is given.
|
|
134
|
+
#
|
|
135
|
+
# @yield [item] each item in FIFO order
|
|
136
|
+
# @return [Enumerator, self]
|
|
137
|
+
def each(&block)
|
|
138
|
+
snapshot = @mutex.synchronize { @items.dup }
|
|
139
|
+
return snapshot.each unless block
|
|
140
|
+
|
|
141
|
+
snapshot.each(&block)
|
|
142
|
+
self
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Return a snapshot of items as an array (FIFO order).
|
|
146
|
+
#
|
|
147
|
+
# @return [Array]
|
|
148
|
+
def to_a
|
|
149
|
+
@mutex.synchronize { @items.dup }
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# Mark the queue as closed. New enqueue calls will raise ClosedError.
|
|
153
|
+
# Existing items can still be dequeued. Wakes all waiting threads.
|
|
154
|
+
#
|
|
155
|
+
# @return [void]
|
|
156
|
+
def close
|
|
157
|
+
@mutex.synchronize do
|
|
158
|
+
@closed = true
|
|
159
|
+
@not_empty.broadcast
|
|
160
|
+
@not_full.broadcast
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# Whether the queue has been closed.
|
|
165
|
+
#
|
|
166
|
+
# @return [Boolean]
|
|
167
|
+
def closed?
|
|
168
|
+
@mutex.synchronize { @closed }
|
|
169
|
+
end
|
|
170
|
+
|
|
66
171
|
# Peek at the front item without removing it.
|
|
67
172
|
#
|
|
68
173
|
# @return [Object, nil] the front item or nil if empty
|
|
@@ -9,12 +9,15 @@ module Philiprehberger
|
|
|
9
9
|
# s.push('item')
|
|
10
10
|
# s.pop # => 'item'
|
|
11
11
|
class Stack
|
|
12
|
+
include Enumerable
|
|
13
|
+
|
|
12
14
|
# Create a new stack.
|
|
13
15
|
#
|
|
14
16
|
# @param capacity [Integer, nil] maximum number of items (nil for unlimited)
|
|
15
17
|
def initialize(capacity: nil)
|
|
16
18
|
@items = []
|
|
17
19
|
@capacity = capacity
|
|
20
|
+
@closed = false
|
|
18
21
|
@mutex = Mutex.new
|
|
19
22
|
@not_empty = ConditionVariable.new
|
|
20
23
|
@not_full = ConditionVariable.new
|
|
@@ -24,26 +27,75 @@ module Philiprehberger
|
|
|
24
27
|
#
|
|
25
28
|
# @param item [Object] the item to push
|
|
26
29
|
# @return [void]
|
|
30
|
+
# @raise [ClosedError] if the stack has been closed
|
|
27
31
|
def push(item)
|
|
28
32
|
@mutex.synchronize do
|
|
33
|
+
raise ClosedError, 'cannot push on a closed stack' if @closed
|
|
34
|
+
|
|
29
35
|
@not_full.wait(@mutex) while @capacity && @items.length >= @capacity
|
|
30
36
|
@items.push(item)
|
|
31
37
|
@not_empty.signal
|
|
32
38
|
end
|
|
33
39
|
end
|
|
34
40
|
|
|
35
|
-
# Pop and return the top item. Blocks if empty.
|
|
41
|
+
# Pop and return the top item. Blocks if empty (returns nil if closed and empty).
|
|
36
42
|
#
|
|
37
|
-
# @return [Object] the popped item
|
|
43
|
+
# @return [Object, nil] the popped item or nil if closed and empty
|
|
38
44
|
def pop
|
|
39
45
|
@mutex.synchronize do
|
|
40
|
-
|
|
46
|
+
while @items.empty?
|
|
47
|
+
return nil if @closed
|
|
48
|
+
|
|
49
|
+
@not_empty.wait(@mutex)
|
|
50
|
+
end
|
|
41
51
|
item = @items.pop
|
|
42
52
|
@not_full.signal
|
|
43
53
|
item
|
|
44
54
|
end
|
|
45
55
|
end
|
|
46
56
|
|
|
57
|
+
# Try to push an item without blocking indefinitely.
|
|
58
|
+
#
|
|
59
|
+
# With timeout: nil, returns immediately. With a numeric timeout, waits up to
|
|
60
|
+
# that many seconds for space to become available.
|
|
61
|
+
#
|
|
62
|
+
# @param item [Object] the item to push
|
|
63
|
+
# @param timeout [Numeric, nil] seconds to wait, or nil for non-blocking
|
|
64
|
+
# @return [Boolean] true if pushed, false if full (or timed out)
|
|
65
|
+
# @raise [ClosedError] if the stack has been closed
|
|
66
|
+
def try_push(item, timeout: nil)
|
|
67
|
+
@mutex.synchronize do
|
|
68
|
+
raise ClosedError, 'cannot push on a closed stack' if @closed
|
|
69
|
+
|
|
70
|
+
if @capacity && @items.length >= @capacity
|
|
71
|
+
return false if timeout.nil? || timeout <= 0
|
|
72
|
+
|
|
73
|
+
deadline = Time.now + timeout
|
|
74
|
+
while @items.length >= @capacity
|
|
75
|
+
remaining = deadline - Time.now
|
|
76
|
+
return false if remaining <= 0
|
|
77
|
+
|
|
78
|
+
@not_full.wait(@mutex, remaining)
|
|
79
|
+
raise ClosedError, 'cannot push on a closed stack' if @closed
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
@items.push(item)
|
|
84
|
+
@not_empty.signal
|
|
85
|
+
true
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Remove all items without returning them. Signals any blocked producers.
|
|
90
|
+
#
|
|
91
|
+
# @return [void]
|
|
92
|
+
def clear
|
|
93
|
+
@mutex.synchronize do
|
|
94
|
+
@items.clear
|
|
95
|
+
@not_full.broadcast
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
47
99
|
# Try to pop an item with a timeout.
|
|
48
100
|
#
|
|
49
101
|
# @param timeout [Numeric] seconds to wait
|
|
@@ -52,6 +104,8 @@ module Philiprehberger
|
|
|
52
104
|
deadline = Time.now + timeout
|
|
53
105
|
@mutex.synchronize do
|
|
54
106
|
while @items.empty?
|
|
107
|
+
return nil if @closed
|
|
108
|
+
|
|
55
109
|
remaining = deadline - Time.now
|
|
56
110
|
return nil if remaining <= 0
|
|
57
111
|
|
|
@@ -63,6 +117,57 @@ module Philiprehberger
|
|
|
63
117
|
end
|
|
64
118
|
end
|
|
65
119
|
|
|
120
|
+
# Remove and return all items as an array (LIFO order, top first). Non-blocking.
|
|
121
|
+
#
|
|
122
|
+
# @return [Array] all items in LIFO order (top first)
|
|
123
|
+
def drain
|
|
124
|
+
@mutex.synchronize do
|
|
125
|
+
result = @items.reverse
|
|
126
|
+
@items.clear
|
|
127
|
+
@not_full.broadcast
|
|
128
|
+
result
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# Iterate items without removing them (snapshot of current state, LIFO order).
|
|
133
|
+
# Returns an Enumerator if no block is given.
|
|
134
|
+
#
|
|
135
|
+
# @yield [item] each item in LIFO order (top first)
|
|
136
|
+
# @return [Enumerator, self]
|
|
137
|
+
def each(&block)
|
|
138
|
+
snapshot = @mutex.synchronize { @items.reverse }
|
|
139
|
+
return snapshot.each unless block
|
|
140
|
+
|
|
141
|
+
snapshot.each(&block)
|
|
142
|
+
self
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Return a snapshot of items as an array (LIFO order, top first).
|
|
146
|
+
#
|
|
147
|
+
# @return [Array]
|
|
148
|
+
def to_a
|
|
149
|
+
@mutex.synchronize { @items.reverse }
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# Mark the stack as closed. New push calls will raise ClosedError.
|
|
153
|
+
# Existing items can still be popped. Wakes all waiting threads.
|
|
154
|
+
#
|
|
155
|
+
# @return [void]
|
|
156
|
+
def close
|
|
157
|
+
@mutex.synchronize do
|
|
158
|
+
@closed = true
|
|
159
|
+
@not_empty.broadcast
|
|
160
|
+
@not_full.broadcast
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# Whether the stack has been closed.
|
|
165
|
+
#
|
|
166
|
+
# @return [Boolean]
|
|
167
|
+
def closed?
|
|
168
|
+
@mutex.synchronize { @closed }
|
|
169
|
+
end
|
|
170
|
+
|
|
66
171
|
# Peek at the top item without removing it.
|
|
67
172
|
#
|
|
68
173
|
# @return [Object, nil] the top item or nil if empty
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: philiprehberger-queue_stack
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Philip Rehberger
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-04-09 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: Thread-safe queue and stack data structures with configurable capacity
|
|
14
14
|
limits, blocking enqueue/dequeue with timeouts, and peek operations. Uses Mutex
|
|
@@ -26,11 +26,11 @@ files:
|
|
|
26
26
|
- lib/philiprehberger/queue_stack/queue.rb
|
|
27
27
|
- lib/philiprehberger/queue_stack/stack.rb
|
|
28
28
|
- lib/philiprehberger/queue_stack/version.rb
|
|
29
|
-
homepage: https://
|
|
29
|
+
homepage: https://philiprehberger.com/open-source-packages/ruby/philiprehberger-queue_stack
|
|
30
30
|
licenses:
|
|
31
31
|
- MIT
|
|
32
32
|
metadata:
|
|
33
|
-
homepage_uri: https://
|
|
33
|
+
homepage_uri: https://philiprehberger.com/open-source-packages/ruby/philiprehberger-queue_stack
|
|
34
34
|
source_code_uri: https://github.com/philiprehberger/rb-queue-stack
|
|
35
35
|
changelog_uri: https://github.com/philiprehberger/rb-queue-stack/blob/main/CHANGELOG.md
|
|
36
36
|
bug_tracker_uri: https://github.com/philiprehberger/rb-queue-stack/issues
|