philiprehberger-priority_queue 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 81ecb740f0ef3871c9662a0bf53f627784e039ad638c3e772fae8cbf9664ec52
4
- data.tar.gz: 8233105bc0db893faa7a53696c2283165d4bc6b5f10f86c02771a1101ddb1a76
3
+ metadata.gz: 5f4b5e7596b5e647e5e21d266d6532e93e045e36eb4373fb4588150220798f7b
4
+ data.tar.gz: 18dfd8320614129f2fef3980afdaa69e65052f081471252b35d6b1b70ee70f3a
5
5
  SHA512:
6
- metadata.gz: 47adacec5e5bd08c5cd6dd2a45500f5e5901372df0171b1aaceb6aefe0e162fc4504e67b345a067ee818685333ca158eb3440a7fe9173c4716e2ed18f1586537
7
- data.tar.gz: 53380b7734ed65fcbf26b80644caef0268b2c187182a8168792aba4fa855433a4dcca840060a9f673972cb4250fc3e1cc996e75474bfcb8a07ac35168d03da59
6
+ metadata.gz: 8f1818babf9c4a3b4f052c8a5fe7b7168f93dd8072933049209e6ecf87485e0769c7fe5dbea5fb166fb45543653a8acf77a53ef3699dd063e5cbf185c4a32629
7
+ data.tar.gz: 30d6bda5afc831cb70e0f8d5beb4ae4b5b37cb4e7512e4b236ad396b00811aec6c8233040e512910855338d0a088a7a538a64650c6f460faeb8f1d293a2ab9dd
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.5.0] - 2026-04-26
11
+
12
+ ### Added
13
+ - `Queue#peek_n(n)` — return the top `n` items in priority order without removing them; symmetric to `#pop_n`
14
+
15
+ ## [0.4.0] - 2026-04-21
16
+
17
+ ### Added
18
+ - `Queue#bulk_push` — insert multiple items from a hash
19
+ - `Queue#priority_of` — lookup priority by item
20
+ - `Queue#find` — priority-ordered search
21
+
22
+ ### Fixed
23
+ - `bug_report.yml` — require Ruby version; add Gem version input per guide
24
+
10
25
  ## [0.3.0] - 2026-04-15
11
26
 
12
27
  ### Added
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.
@@ -142,6 +154,21 @@ queue.pop_n(5) # => ["c"]
142
154
  queue.pop_n(0) # => []
143
155
  ```
144
156
 
157
+ ### Peek N
158
+
159
+ Return the top `n` items in priority order without removing them. The queue is unchanged.
160
+
161
+ ```ruby
162
+ queue = Philiprehberger::PriorityQueue::Queue.new
163
+ queue.push("a", priority: 1)
164
+ queue.push("b", priority: 2)
165
+ queue.push("c", priority: 3)
166
+
167
+ queue.peek_n(2) # => ["a", "b"]
168
+ queue.peek_n(5) # => ["a", "b", "c"]
169
+ queue.size # => 3
170
+ ```
171
+
145
172
  ### Delete
146
173
 
147
174
  Remove a specific item by value.
@@ -218,9 +245,13 @@ merged.size # => 3
218
245
  | `#peek_priority` | Return just the top priority value; returns `nil` when empty |
219
246
  | `#drain` | Pop all items and return as array in priority order; empties the queue |
220
247
  | `#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` |
248
+ | `#peek_n(n)` | Return up to `n` items in priority order without removing them; returns `[]` for empty queue or `n == 0`; raises `ArgumentError` for negative `n` |
221
249
  | `#delete(item)` | Remove a specific item by value; returns the item or `nil` |
222
250
  | `#priorities` | Return sorted array of unique priority values in the queue |
223
251
  | `#each` | Yield `[item, priority]` pairs in priority order (Enumerable) |
252
+ | `#bulk_push(items_hash)` | Insert multiple items from a hash `{ item => priority, ... }`; returns `self`; raises `ArgumentError` for non-Hash input |
253
+ | `#priority_of(item)` | Return the priority of the first matching item (O(n) linear scan); returns `nil` if not present |
254
+ | `#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 |
224
255
 
225
256
  ## Development
226
257
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Philiprehberger
4
4
  module PriorityQueue
5
- VERSION = '0.3.0'
5
+ VERSION = '0.5.0'
6
6
  end
7
7
  end
@@ -69,6 +69,21 @@ module Philiprehberger
69
69
  result
70
70
  end
71
71
 
72
+ # Return the top +n+ items in priority order without removing them.
73
+ #
74
+ # When the queue is empty or +n+ is zero, returns +[]+. When +n+ is
75
+ # greater than or equal to the size, returns all items in priority order.
76
+ # The queue is not modified.
77
+ #
78
+ # @param n [Integer] the maximum number of items to return; must be non-negative
79
+ # @return [Array] the top +n+ items in priority order, or fewer when the queue is smaller
80
+ # @raise [ArgumentError] if +n+ is negative
81
+ def peek_n(n)
82
+ raise ArgumentError, "n must be non-negative, got #{n}" if n.negative?
83
+
84
+ to_a.first(n)
85
+ end
86
+
72
87
  def empty?
73
88
  @size.zero?
74
89
  end
@@ -153,6 +168,48 @@ module Philiprehberger
153
168
  @heap.map { |entry| entry[0] }.uniq.sort
154
169
  end
155
170
 
171
+ # Insert multiple items from a hash in one call.
172
+ #
173
+ # @param items_hash [Hash] a mapping of item to priority
174
+ # @return [self] the queue, for chaining
175
+ # @raise [ArgumentError] if +items_hash+ is not a Hash
176
+ def bulk_push(items_hash)
177
+ raise ArgumentError, "Expected a Hash, got #{items_hash.class}" unless items_hash.is_a?(Hash)
178
+
179
+ items_hash.each { |item, priority| push(item, priority: priority) }
180
+ self
181
+ end
182
+
183
+ # Look up the priority of the first matching item.
184
+ #
185
+ # Uses a linear scan (O(n)) over internal storage and returns
186
+ # the priority associated with the first entry whose item is
187
+ # +==+ to the argument.
188
+ #
189
+ # @param item [Object] the item to look up
190
+ # @return [Object, nil] the priority of the first match, or +nil+ when not present
191
+ def priority_of(item)
192
+ entry = @heap.find { |e| e[2] == item }
193
+ entry.nil? ? nil : entry[0]
194
+ end
195
+
196
+ # Find the first [item, priority] pair in priority order for which
197
+ # the block returns a truthy value.
198
+ #
199
+ # @yield [item, priority] pairs in priority order
200
+ # @yieldparam item [Object] the item
201
+ # @yieldparam priority [Object] the priority
202
+ # @return [Array, nil] the first matching +[item, priority]+ pair, or +nil+ when none match
203
+ # @return [Enumerator] if no block is given
204
+ def find(&block)
205
+ return enum_for(:find) unless block
206
+
207
+ each do |item, priority|
208
+ return [item, priority] if block.call(item, priority)
209
+ end
210
+ nil
211
+ end
212
+
156
213
  def merge(other)
157
214
  merged = self.class.new(&@comparator)
158
215
  @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.3.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-15 00:00:00.000000000 Z
11
+ date: 2026-04-27 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,