philiprehberger-queue_stack 0.3.0 → 0.5.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 +11 -0
- data/README.md +29 -3
- data/lib/philiprehberger/queue_stack/queue.rb +30 -0
- data/lib/philiprehberger/queue_stack/stack.rb +18 -0
- data/lib/philiprehberger/queue_stack/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dba395bc3ee76baae4cdbbbb100fc91103049635c386e02fe5ac3ae118e9997a
|
|
4
|
+
data.tar.gz: 921a8e4241383d570d951e154b19e7abcce5cdb682d93b42888d36c9804871a2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 30320f35b2ae5d2e01221091e203c31cc799ec5d6a1ff279a0201a04dd9c038f254ad8319d1e4f8cf3a50e1e292e2522a813e8330383f2f49ce99b86d5704b1c
|
|
7
|
+
data.tar.gz: 2ddd79499fa0b97b99fcb45c5c941984c1f8b3ddeee25cc4edeed317b9317509d9ade981940ca685266770db6dc3d472b11e3fdb8610b45731abd44f7f3a284e
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.5.0] - 2026-04-16
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- `Queue#dequeue_if { |item| ... }` conditionally removes and returns the front item only when the block returns truthy; returns `nil` when empty or the block returns false (non-blocking)
|
|
14
|
+
- `Stack#pop_if { |item| ... }` conditionally removes and returns the top item only when the block returns truthy; returns `nil` when empty or the block returns false (non-blocking)
|
|
15
|
+
|
|
16
|
+
## [0.4.0] - 2026-04-15
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
- `Queue#peek_at(index)` returns the item at the given position without removing it, supporting negative indices like `Array#[]` and returning `nil` when out of range
|
|
20
|
+
|
|
10
21
|
## [0.3.0] - 2026-04-09
|
|
11
22
|
|
|
12
23
|
### Added
|
data/README.md
CHANGED
|
@@ -40,9 +40,13 @@ item = q.dequeue # => 'task'
|
|
|
40
40
|
q = Philiprehberger::QueueStack::Queue.new(capacity: 10)
|
|
41
41
|
q.enqueue('first')
|
|
42
42
|
q.enqueue('second')
|
|
43
|
-
q.
|
|
44
|
-
q.peek
|
|
45
|
-
q.
|
|
43
|
+
q.enqueue('third')
|
|
44
|
+
q.peek # => 'first'
|
|
45
|
+
q.peek_at(1) # => 'second'
|
|
46
|
+
q.peek_at(-1) # => 'third'
|
|
47
|
+
q.peek_at(99) # => nil (out of range)
|
|
48
|
+
q.dequeue # => 'first'
|
|
49
|
+
q.size # => 2
|
|
46
50
|
```
|
|
47
51
|
|
|
48
52
|
### Stack (LIFO)
|
|
@@ -66,6 +70,25 @@ s = Philiprehberger::QueueStack::Stack.new
|
|
|
66
70
|
item = s.try_pop(timeout: 5) # waits up to 5 seconds
|
|
67
71
|
```
|
|
68
72
|
|
|
73
|
+
### Conditional Removal
|
|
74
|
+
|
|
75
|
+
Remove the front/top item only when a predicate holds. Non-blocking; returns `nil` if the collection is empty or the block returns false (the item stays put).
|
|
76
|
+
|
|
77
|
+
```ruby
|
|
78
|
+
q = Philiprehberger::QueueStack::Queue.new
|
|
79
|
+
q.enqueue({ priority: 10 })
|
|
80
|
+
q.enqueue({ priority: 2 })
|
|
81
|
+
|
|
82
|
+
# Only take high-priority work
|
|
83
|
+
q.dequeue_if { |job| job[:priority] >= 5 } # => { priority: 10 }
|
|
84
|
+
q.dequeue_if { |job| job[:priority] >= 5 } # => nil (head priority 2 left intact)
|
|
85
|
+
|
|
86
|
+
s = Philiprehberger::QueueStack::Stack.new
|
|
87
|
+
s.push(:ready)
|
|
88
|
+
s.pop_if { |item| item == :ready } # => :ready
|
|
89
|
+
s.pop_if { |item| item == :ready } # => nil (empty)
|
|
90
|
+
```
|
|
91
|
+
|
|
69
92
|
### Drain
|
|
70
93
|
|
|
71
94
|
```ruby
|
|
@@ -146,9 +169,11 @@ q.full? # => true
|
|
|
146
169
|
| `#enqueue(item)` | Add item to back (blocks if full) |
|
|
147
170
|
| `#try_enqueue(item, timeout: nil)` | Non-blocking enqueue, returns true/false (waits up to timeout if given) |
|
|
148
171
|
| `#dequeue` | Remove and return front item (blocks if empty) |
|
|
172
|
+
| `#dequeue_if { \|item\| ... }` | Remove and return the front item only if the block is truthy (non-blocking) |
|
|
149
173
|
| `#try_dequeue(timeout:)` | Dequeue with timeout, returns nil on timeout |
|
|
150
174
|
| `#clear` | Remove all items without returning them |
|
|
151
175
|
| `#peek` | View front item without removing |
|
|
176
|
+
| `#peek_at(index)` | View item at the given position (supports negative indices, returns nil if out of range) |
|
|
152
177
|
| `#drain` | Remove and return all items as array (FIFO order) |
|
|
153
178
|
| `#each` | Iterate items without removing (returns Enumerator if no block) |
|
|
154
179
|
| `#to_a` | Snapshot as array (FIFO order) |
|
|
@@ -166,6 +191,7 @@ q.full? # => true
|
|
|
166
191
|
| `#push(item)` | Push item on top (blocks if full) |
|
|
167
192
|
| `#try_push(item, timeout: nil)` | Non-blocking push, returns true/false (waits up to timeout if given) |
|
|
168
193
|
| `#pop` | Remove and return top item (blocks if empty) |
|
|
194
|
+
| `#pop_if { \|item\| ... }` | Remove and return the top item only if the block is truthy (non-blocking) |
|
|
169
195
|
| `#try_pop(timeout:)` | Pop with timeout, returns nil on timeout |
|
|
170
196
|
| `#clear` | Remove all items without returning them |
|
|
171
197
|
| `#peek` | View top item without removing |
|
|
@@ -96,6 +96,24 @@ module Philiprehberger
|
|
|
96
96
|
end
|
|
97
97
|
end
|
|
98
98
|
|
|
99
|
+
# Conditionally dequeue the front item. The block is called with the item
|
|
100
|
+
# that would be dequeued next. If the block returns truthy, the item is
|
|
101
|
+
# removed and returned. Otherwise the item is left in place and +nil+ is
|
|
102
|
+
# returned. Returns +nil+ immediately if the queue is empty (non-blocking).
|
|
103
|
+
#
|
|
104
|
+
# @yield [item] the front item
|
|
105
|
+
# @return [Object, nil] the removed item, or nil if empty or block returned false
|
|
106
|
+
def dequeue_if
|
|
107
|
+
@mutex.synchronize do
|
|
108
|
+
return nil if @items.empty?
|
|
109
|
+
return nil unless yield(@items.first)
|
|
110
|
+
|
|
111
|
+
item = @items.shift
|
|
112
|
+
@not_full.signal
|
|
113
|
+
item
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
99
117
|
# Try to dequeue an item with a timeout.
|
|
100
118
|
#
|
|
101
119
|
# @param timeout [Numeric] seconds to wait
|
|
@@ -175,6 +193,18 @@ module Philiprehberger
|
|
|
175
193
|
@mutex.synchronize { @items.first }
|
|
176
194
|
end
|
|
177
195
|
|
|
196
|
+
# Peek at the item at the given position without removing it.
|
|
197
|
+
#
|
|
198
|
+
# Indexing follows +Array#[]+ semantics: +0+ is the front of the queue,
|
|
199
|
+
# +size - 1+ is the back, and negative indices count from the back
|
|
200
|
+
# (+-1+ is the last item). Returns +nil+ when the index is out of range.
|
|
201
|
+
#
|
|
202
|
+
# @param index [Integer] position in the queue (supports negative indices)
|
|
203
|
+
# @return [Object, nil] the item at the position or nil if out of range
|
|
204
|
+
def peek_at(index)
|
|
205
|
+
@mutex.synchronize { @items[index] }
|
|
206
|
+
end
|
|
207
|
+
|
|
178
208
|
# Return the number of items in the queue.
|
|
179
209
|
#
|
|
180
210
|
# @return [Integer]
|
|
@@ -96,6 +96,24 @@ module Philiprehberger
|
|
|
96
96
|
end
|
|
97
97
|
end
|
|
98
98
|
|
|
99
|
+
# Conditionally pop the top item. The block is called with the item that
|
|
100
|
+
# would be popped next. If the block returns truthy, the item is removed
|
|
101
|
+
# and returned. Otherwise the item is left in place and +nil+ is returned.
|
|
102
|
+
# Returns +nil+ immediately if the stack is empty (non-blocking).
|
|
103
|
+
#
|
|
104
|
+
# @yield [item] the top item
|
|
105
|
+
# @return [Object, nil] the removed item, or nil if empty or block returned false
|
|
106
|
+
def pop_if
|
|
107
|
+
@mutex.synchronize do
|
|
108
|
+
return nil if @items.empty?
|
|
109
|
+
return nil unless yield(@items.last)
|
|
110
|
+
|
|
111
|
+
item = @items.pop
|
|
112
|
+
@not_full.signal
|
|
113
|
+
item
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
99
117
|
# Try to pop an item with a timeout.
|
|
100
118
|
#
|
|
101
119
|
# @param timeout [Numeric] seconds to wait
|
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.5.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-04-
|
|
11
|
+
date: 2026-04-16 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
|