1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
|
# Releases
## v1.14.0
### Enhanced `IO::Event::PriorityHeap` with deletion and bulk insertion methods
The {ruby IO::Event::PriorityHeap} now supports efficient element removal and bulk insertion:
- **`delete(element)`**: Remove a specific element from the heap in O(n) time
- **`delete_if(&block)`**: Remove elements matching a condition with O(n) amortized bulk deletion
- **`concat(elements)`**: Add multiple elements efficiently in O(n) time
<!-- end list -->
``` ruby
heap = IO::Event::PriorityHeap.new
# Efficient bulk insertion - O(n) instead of O(n log n)
heap.concat([5, 2, 8, 1, 9, 3])
# Remove specific element
removed = heap.delete(5) # Returns 5, heap maintains order
# Bulk removal with condition
count = heap.delete_if{|x| x.even?} # Removes 2, 8 efficiently
```
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:
- **Bulk insertion**: O(n log n) → O(n) for adding multiple elements
- **Bulk deletion**: O(k×n) → O(n) for removing k elements
Both methods maintain the heap invariant and include comprehensive test coverage with edge case validation.
## v1.11.2
- Fix Windows build.
## v1.11.1
- Fix `read_nonblock` when using the `URing` selector, which was not handling zero-length reads correctly. This allows reading available data without blocking.
## v1.11.0
### Introduce `IO::Event::WorkerPool` for off-loading blocking operations.
The {ruby IO::Event::WorkerPool} provides a mechanism for executing blocking operations on separate OS threads while properly integrating with Ruby's fiber scheduler and GVL (Global VM Lock) management. This enables true parallelism for CPU-intensive or blocking operations that would otherwise block the event loop.
``` ruby
# Fiber scheduler integration via blocking_operation_wait hook
class MyScheduler
def initialize
@worker_pool = IO::Event::WorkerPool.new
end
def blocking_operation_wait(operation)
@worker_pool.call(operation)
end
end
# Usage with automatic offloading
Fiber.set_scheduler(MyScheduler.new)
# Automatically offload `rb_nogvl(..., RB_NOGVL_OFFLOAD_SAFE)` to a background thread:
result = some_blocking_operation()
```
The implementation uses one or more background threads and a list of pending blocking operations. Those operations either execute through to completion or may be cancelled, which executes the "unblock function" provided to `rb_nogvl`.
## v1.10.2
- Improved consistency of handling closed IO when invoking `#select`.
## v1.10.0
- `IO::Event::Profiler` is moved to dedicated gem: [fiber-profiler](https://github.com/socketry/fiber-profiler).
- Perform runtime checks for native selectors to ensure they are supported in the current environment. While compile-time checks determine availability, restrictions like seccomp and SELinux may still prevent them from working.
## v1.9.0
- Improved `IO::Event::Profiler` for detecting stalls.
## v1.8.0
- Detecting fibers that are stalling the event loop.
## v1.7.5
- Fix `process_wait` race condition on EPoll that could cause a hang.
|