io-event 1.13.0 → 1.14.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
- checksums.yaml.gz.sig +0 -0
- data/lib/io/event/priority_heap.rb +94 -1
- data/lib/io/event/version.rb +1 -1
- data/readme.md +4 -0
- data/releases.md +32 -0
- data.tar.gz.sig +0 -0
- metadata +2 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 53a9942daf957580fe332adea530a3bba659c0ec5405560078233ead0b893d11
|
4
|
+
data.tar.gz: d6eea90381836e4f1bf62430ae95ea0f7f2b1693683d2a114b5193f0c7a1d3f8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9bfd04d670380038ec6a57a212f0f927b3fd748f93ac95c26e04adb1ed829a999fc02ebca56a27812c84be402b9fef576ba5d53be0df7b8f5e06bb516c70f2b6
|
7
|
+
data.tar.gz: ca71eac94412be0bbb953d32eb60ef1654fe24535012bc3f6f9a1a5375377175a71641c28e5ab92a5f3d44418ab50c3ef177a552cc0abe57f633e718cb2b4bc4
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
@@ -79,19 +79,112 @@ class IO
|
|
79
79
|
return self
|
80
80
|
end
|
81
81
|
|
82
|
+
# Add multiple elements to the heap efficiently in O(n) time.
|
83
|
+
# This is more efficient than calling push multiple times (O(n log n)).
|
84
|
+
#
|
85
|
+
# @parameter elements [Array] The elements to add to the heap.
|
86
|
+
# @returns [self] Returns self for method chaining.
|
87
|
+
def concat(elements)
|
88
|
+
return self if elements.empty?
|
89
|
+
|
90
|
+
# Add all elements to the array without maintaining heap property - O(n)
|
91
|
+
@contents.concat(elements)
|
92
|
+
|
93
|
+
# Rebuild the heap property for the entire array - O(n)
|
94
|
+
heapify!
|
95
|
+
|
96
|
+
return self
|
97
|
+
end
|
98
|
+
|
82
99
|
# Empties out the heap, discarding all elements
|
83
100
|
def clear!
|
84
101
|
@contents = []
|
85
102
|
end
|
86
103
|
|
104
|
+
# Remove a specific element from the heap.
|
105
|
+
#
|
106
|
+
# O(n) where n is the number of elements in the heap.
|
107
|
+
#
|
108
|
+
# @parameter element [Object] The element to remove.
|
109
|
+
# @returns [Object | Nil] The removed element, or nil if not found.
|
110
|
+
def delete(element)
|
111
|
+
# Find the index of the element - O(n) linear search
|
112
|
+
index = @contents.index(element)
|
113
|
+
return nil unless index
|
114
|
+
|
115
|
+
# If it's the last element, just remove it
|
116
|
+
if index == @contents.size - 1
|
117
|
+
return @contents.pop
|
118
|
+
end
|
119
|
+
|
120
|
+
# Store the value we're removing
|
121
|
+
removed_value = @contents[index]
|
122
|
+
|
123
|
+
# Replace with the last element
|
124
|
+
last = @contents.pop
|
125
|
+
@contents[index] = last
|
126
|
+
|
127
|
+
# Restore heap property - might need to bubble up or down
|
128
|
+
if index > 0 && @contents[index] < @contents[(index - 1) / 2]
|
129
|
+
# New element is smaller than parent, bubble up
|
130
|
+
bubble_up(index)
|
131
|
+
else
|
132
|
+
# New element might be larger than children, bubble down
|
133
|
+
bubble_down(index)
|
134
|
+
end
|
135
|
+
|
136
|
+
# validate!
|
137
|
+
|
138
|
+
return removed_value
|
139
|
+
end
|
140
|
+
|
141
|
+
# Remove elements matching the given block condition by rebuilding the heap.
|
142
|
+
#
|
143
|
+
# This is more efficient than multiple delete operations when removing many elements.
|
144
|
+
#
|
145
|
+
# O(n) where n is the number of elements in the heap.
|
146
|
+
#
|
147
|
+
# @yields [Object] Each element in the heap for testing
|
148
|
+
# @returns [Integer] The number of elements removed
|
149
|
+
def delete_if
|
150
|
+
return enum_for(:delete_if) unless block_given?
|
151
|
+
|
152
|
+
original_size = @contents.size
|
153
|
+
|
154
|
+
# Filter out elements that match the condition - O(n)
|
155
|
+
@contents.reject! {|element| yield(element)}
|
156
|
+
|
157
|
+
# If we removed elements, rebuild the heap - O(n)
|
158
|
+
if @contents.size < original_size
|
159
|
+
heapify!
|
160
|
+
end
|
161
|
+
|
162
|
+
# Return number of elements removed
|
163
|
+
original_size - @contents.size
|
164
|
+
end
|
165
|
+
|
87
166
|
# Validate the heap invariant. Every element except the root must not be smaller than its parent element. Note that it MAY be equal.
|
88
167
|
def valid?
|
89
|
-
# Notice we skip index 0 on purpose, because it has no parent
|
168
|
+
# Notice we skip index 0 on purpose, because it has no parent:
|
90
169
|
(1..(@contents.size - 1)).all? {|index| @contents[index] >= @contents[(index - 1) / 2]}
|
91
170
|
end
|
92
171
|
|
93
172
|
private
|
94
173
|
|
174
|
+
# Rebuild the heap property from an arbitrary array in O(n) time.
|
175
|
+
# Uses bottom-up heapify algorithm starting from the last non-leaf node.
|
176
|
+
def heapify!
|
177
|
+
return if @contents.size <= 1
|
178
|
+
|
179
|
+
# Start from the last non-leaf node and work backwards to root:
|
180
|
+
last_non_leaf_index = (@contents.size / 2) - 1
|
181
|
+
last_non_leaf_index.downto(0) do |index|
|
182
|
+
bubble_down(index)
|
183
|
+
end
|
184
|
+
|
185
|
+
# validate!
|
186
|
+
end
|
187
|
+
|
95
188
|
# Left here for reference, but unused.
|
96
189
|
# def swap(i, j)
|
97
190
|
# @contents[i], @contents[j] = @contents[j], @contents[i]
|
data/lib/io/event/version.rb
CHANGED
data/readme.md
CHANGED
@@ -18,6 +18,10 @@ Please see the [project documentation](https://socketry.github.io/io-event/) for
|
|
18
18
|
|
19
19
|
Please see the [project releases](https://socketry.github.io/io-event/releases/index) for all releases.
|
20
20
|
|
21
|
+
### v1.14.0
|
22
|
+
|
23
|
+
- [Enhanced `IO::Event::PriorityHeap` with deletion and bulk insertion methods](https://socketry.github.io/io-event/releases/index#enhanced-io::event::priorityheap-with-deletion-and-bulk-insertion-methods)
|
24
|
+
|
21
25
|
### v1.11.2
|
22
26
|
|
23
27
|
- Fix Windows build.
|
data/releases.md
CHANGED
@@ -1,5 +1,37 @@
|
|
1
1
|
# Releases
|
2
2
|
|
3
|
+
## v1.14.0
|
4
|
+
|
5
|
+
### Enhanced `IO::Event::PriorityHeap` with deletion and bulk insertion methods
|
6
|
+
|
7
|
+
The {ruby IO::Event::PriorityHeap} now supports efficient element removal and bulk insertion:
|
8
|
+
|
9
|
+
- **`delete(element)`**: Remove a specific element from the heap in O(n) time
|
10
|
+
- **`delete_if(&block)`**: Remove elements matching a condition with O(n) amortized bulk deletion
|
11
|
+
- **`concat(elements)`**: Add multiple elements efficiently in O(n) time
|
12
|
+
|
13
|
+
<!-- end list -->
|
14
|
+
|
15
|
+
``` ruby
|
16
|
+
heap = IO::Event::PriorityHeap.new
|
17
|
+
|
18
|
+
# Efficient bulk insertion - O(n) instead of O(n log n)
|
19
|
+
heap.concat([5, 2, 8, 1, 9, 3])
|
20
|
+
|
21
|
+
# Remove specific element
|
22
|
+
removed = heap.delete(5) # Returns 5, heap maintains order
|
23
|
+
|
24
|
+
# Bulk removal with condition
|
25
|
+
count = heap.delete_if { |x| x.even? } # Removes 2, 8 efficiently
|
26
|
+
```
|
27
|
+
|
28
|
+
The `delete_if` and `concat` methods are particularly efficient for bulk operations, using bottom-up heapification to maintain the heap property in O(n) time. This provides significant performance improvements:
|
29
|
+
|
30
|
+
- **Bulk insertion**: O(n log n) → O(n) for adding multiple elements
|
31
|
+
- **Bulk deletion**: O(k×n) → O(n) for removing k elements
|
32
|
+
|
33
|
+
Both methods maintain the heap invariant and include comprehensive test coverage with edge case validation.
|
34
|
+
|
3
35
|
## v1.11.2
|
4
36
|
|
5
37
|
- Fix Windows build.
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: io-event
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.14.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
@@ -116,7 +116,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
116
116
|
- !ruby/object:Gem::Version
|
117
117
|
version: '0'
|
118
118
|
requirements: []
|
119
|
-
rubygems_version: 3.
|
119
|
+
rubygems_version: 3.7.0.dev
|
120
120
|
specification_version: 4
|
121
121
|
summary: An event loop.
|
122
122
|
test_files: []
|
metadata.gz.sig
CHANGED
Binary file
|