philiprehberger-priority_queue 0.2.1 → 0.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 550864e1c3c7c28c4d978059acd56e73d64fd084e9263f46afd5fbf52a86671e
4
- data.tar.gz: 766b98241695a100ba12122f06c6a7d4cada3c28685643f08fae483b667da0ce
3
+ metadata.gz: 4fca90d36f6f8f63c1b89c458854eb61af26682c7dcf66aaa1da9023f8cba5ab
4
+ data.tar.gz: a91b25347569be4e586c4c0ec1ce8c6d77b77d652df16ba39bce020c4560458c
5
5
  SHA512:
6
- metadata.gz: a76b48855cd5782999ec79ae730efc4ebeaad9a02f78b4b1d981979d3cdf7b9543108d53bf710163d526b09273f655a9dc0bcf716c42c870c6678994d2a4b29d
7
- data.tar.gz: d31237580572959f8cbf0943504b96205df6b97678a4385dcf5963bf069b52f8eac8cbd45d644be6779c7cca1d98ec039e6e507844888f4d83ad9e61e0d00c59
6
+ metadata.gz: b280a1927ced0e7ac6706af14e03a319111c962d8d67cfe7d93ceab3ce05761a187698ec0b8d8d175c3fdb12f52fecf35640de99410242dee37a583e5bdf1322
7
+ data.tar.gz: c52cb6190358eab1880f423df857c8165cadca1b98255c1c062a2c6bdfe54c027d0c29a492f9baf1481d78078f354c1190a7f48dbdf0d570ee5ae38d2fa7f57b
data/CHANGELOG.md CHANGED
@@ -7,6 +7,21 @@ and this gem adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.4.0] - 2026-04-21
11
+
12
+ ### Added
13
+ - `Queue#bulk_push` — insert multiple items from a hash
14
+ - `Queue#priority_of` — lookup priority by item
15
+ - `Queue#find` — priority-ordered search
16
+
17
+ ### Fixed
18
+ - `bug_report.yml` — require Ruby version; add Gem version input per guide
19
+
20
+ ## [0.3.0] - 2026-04-15
21
+
22
+ ### Added
23
+ - `Queue#pop_n(n)` to pop up to `n` items in priority order and return them as an array; returns `[]` for empty queues or `n == 0`; raises `ArgumentError` for negative `n`
24
+
10
25
  ## [0.2.1] - 2026-04-15
11
26
 
12
27
  ### Fixed
data/README.md CHANGED
@@ -103,6 +103,18 @@ queue.push_many([
103
103
  queue.pop # => "alert"
104
104
  ```
105
105
 
106
+ ### Bulk Insertion
107
+
108
+ Insert multiple items from a hash, look up the priority of an item, and search in priority order.
109
+
110
+ ```ruby
111
+ queue = Philiprehberger::PriorityQueue::Queue.new
112
+ queue.bulk_push("email" => 2, "backup" => 5, "alert" => 1)
113
+
114
+ queue.priority_of("backup") # => 5
115
+ queue.find { |_item, priority| priority > 1 } # => ["email", 2]
116
+ ```
117
+
106
118
  ### Peek Priority
107
119
 
108
120
  Return just the top priority value without the item.
@@ -127,6 +139,21 @@ queue.drain # => ["a", "b", "c"]
127
139
  queue.empty? # => true
128
140
  ```
129
141
 
142
+ ### Pop N
143
+
144
+ Pop up to `n` items in priority order. Returns fewer than `n` items when the queue is exhausted.
145
+
146
+ ```ruby
147
+ queue = Philiprehberger::PriorityQueue::Queue.new
148
+ queue.push("a", priority: 1)
149
+ queue.push("b", priority: 2)
150
+ queue.push("c", priority: 3)
151
+
152
+ queue.pop_n(2) # => ["a", "b"]
153
+ queue.pop_n(5) # => ["c"]
154
+ queue.pop_n(0) # => []
155
+ ```
156
+
130
157
  ### Delete
131
158
 
132
159
  Remove a specific item by value.
@@ -202,9 +229,13 @@ merged.size # => 3
202
229
  | `#push_many(items)` | Batch push from array of hashes `[{ item: x, priority: n }, ...]`; returns `self` |
203
230
  | `#peek_priority` | Return just the top priority value; returns `nil` when empty |
204
231
  | `#drain` | Pop all items and return as array in priority order; empties the queue |
232
+ | `#pop_n(n)` | Pop up to `n` items in priority order and return as array; returns `[]` for empty queue or `n == 0`; raises `ArgumentError` for negative `n` |
205
233
  | `#delete(item)` | Remove a specific item by value; returns the item or `nil` |
206
234
  | `#priorities` | Return sorted array of unique priority values in the queue |
207
235
  | `#each` | Yield `[item, priority]` pairs in priority order (Enumerable) |
236
+ | `#bulk_push(items_hash)` | Insert multiple items from a hash `{ item => priority, ... }`; returns `self`; raises `ArgumentError` for non-Hash input |
237
+ | `#priority_of(item)` | Return the priority of the first matching item (O(n) linear scan); returns `nil` if not present |
238
+ | `#find(&block)` | Yield `[item, priority]` pairs in priority order and return the first pair for which the block is truthy; returns `nil` if none match, or an `Enumerator` when no block is given |
208
239
 
209
240
  ## Development
210
241
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Philiprehberger
4
4
  module PriorityQueue
5
- VERSION = '0.2.1'
5
+ VERSION = '0.4.0'
6
6
  end
7
7
  end
@@ -57,6 +57,18 @@ module Philiprehberger
57
57
  @heap[0][2]
58
58
  end
59
59
 
60
+ def pop_n(n)
61
+ raise ArgumentError, "n must be non-negative, got #{n}" if n.negative?
62
+
63
+ result = []
64
+ n.times do
65
+ break if empty?
66
+
67
+ result << pop
68
+ end
69
+ result
70
+ end
71
+
60
72
  def empty?
61
73
  @size.zero?
62
74
  end
@@ -141,6 +153,48 @@ module Philiprehberger
141
153
  @heap.map { |entry| entry[0] }.uniq.sort
142
154
  end
143
155
 
156
+ # Insert multiple items from a hash in one call.
157
+ #
158
+ # @param items_hash [Hash] a mapping of item to priority
159
+ # @return [self] the queue, for chaining
160
+ # @raise [ArgumentError] if +items_hash+ is not a Hash
161
+ def bulk_push(items_hash)
162
+ raise ArgumentError, "Expected a Hash, got #{items_hash.class}" unless items_hash.is_a?(Hash)
163
+
164
+ items_hash.each { |item, priority| push(item, priority: priority) }
165
+ self
166
+ end
167
+
168
+ # Look up the priority of the first matching item.
169
+ #
170
+ # Uses a linear scan (O(n)) over internal storage and returns
171
+ # the priority associated with the first entry whose item is
172
+ # +==+ to the argument.
173
+ #
174
+ # @param item [Object] the item to look up
175
+ # @return [Object, nil] the priority of the first match, or +nil+ when not present
176
+ def priority_of(item)
177
+ entry = @heap.find { |e| e[2] == item }
178
+ entry.nil? ? nil : entry[0]
179
+ end
180
+
181
+ # Find the first [item, priority] pair in priority order for which
182
+ # the block returns a truthy value.
183
+ #
184
+ # @yield [item, priority] pairs in priority order
185
+ # @yieldparam item [Object] the item
186
+ # @yieldparam priority [Object] the priority
187
+ # @return [Array, nil] the first matching +[item, priority]+ pair, or +nil+ when none match
188
+ # @return [Enumerator] if no block is given
189
+ def find(&block)
190
+ return enum_for(:find) unless block
191
+
192
+ each do |item, priority|
193
+ return [item, priority] if block.call(item, priority)
194
+ end
195
+ nil
196
+ end
197
+
144
198
  def merge(other)
145
199
  merged = self.class.new(&@comparator)
146
200
  @heap.each { |entry| merged.push(entry[2], priority: entry[0]) }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: philiprehberger-priority_queue
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.4.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-15 00:00:00.000000000 Z
11
+ date: 2026-04-21 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A binary heap-based priority queue supporting min-heap, max-heap, and
14
14
  custom comparator modes. Features O(log n) push/pop, priority changes, merge operations,