rbtree-ruby 0.3.2 → 0.3.3
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 +9 -0
- data/README.ja.md +8 -5
- data/README.md +8 -5
- data/lib/rbtree/version.rb +1 -1
- data/lib/rbtree.rb +14 -9
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2145d91a96cc64b7e65c65460716b678301f74d6decdffa2dbd077a914273c21
|
|
4
|
+
data.tar.gz: 66503c542ce07672a493830afbfcb66ebfea14d8563e67b1b2dd1d5ecd1d9c48
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7befca8277d78b75242a443c2ec155bded73f899222b32330c6416e6ffeaad8ec6bca01e11ce23c6047208871cf71cfb8c6a742732b4ae0b531f54e51a8e424e
|
|
7
|
+
data.tar.gz: eb77127897b535277717575afe27c47cd087ba15685f59b0df67516c55d393a8d7412cf08d667cea5494978746967c098294bb73e8e9771c2aee363762afcca9
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,15 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.3.3] - 2026-01-23
|
|
9
|
+
|
|
10
|
+
### Optimized
|
|
11
|
+
- **find_successor_node**: Optimized performance for scans starting from the beginning (or before `min_key`) when the `safe: true` option is used. Added a fast-path (short-circuit) when the given key is smaller than `min_key`.
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
- **MultiRBTree Aliases**: Fixed `delete`, `get`, and `[]` aliases in `MultiRBTree`. They now correctly point to the overridden methods in the derived class, ensuring correct value handling and size tracking.
|
|
15
|
+
- **enum_for Syntax**: Syntactic corrections for `enum_for` to ensure robust keyword argument handling in enumerators.
|
|
16
|
+
|
|
8
17
|
## [0.3.2] - 2026-01-15
|
|
9
18
|
|
|
10
19
|
### Added
|
data/README.ja.md
CHANGED
|
@@ -6,11 +6,14 @@ Red-Black Tree(赤黒木)データ構造のピュアRuby実装です。挿
|
|
|
6
6
|
|
|
7
7
|
## 特徴
|
|
8
8
|
|
|
9
|
-
- **自己平衡二分探索木**:
|
|
10
|
-
- **順序付き操作**:
|
|
11
|
-
- **複数値サポート**: `MultiRBTree
|
|
12
|
-
- **ピュアRuby**: C
|
|
13
|
-
-
|
|
9
|
+
- **自己平衡二分探索木**: 赤黒木の性質により最適なパフォーマンスを維持。挿入・削除・検索がすべてO(log n)。
|
|
10
|
+
- **順序付き操作**: ソート済みイテレーション、範囲クエリ(lt, gt, between)、最小/最大値取得が高速に実行可能。
|
|
11
|
+
- **複数値サポート**: `MultiRBTree`クラスで同一キーに複数の値を格納。値は挿入順に保持され、最初または最後の値を個別にアクセス可能。
|
|
12
|
+
- **ピュアRuby**: C拡張不要。MRI, JRuby, TruffleRubyなどあらゆるRuby実装で動作。
|
|
13
|
+
- **ハイブリッドインデックス**: 内部ハッシュインデックスにより、キー検索と存在確認がO(1)の超高速アクセスを実現。
|
|
14
|
+
- **メモリ効率**: ノードプールによるオブジェクト再利用と自動縮小機能でGC負荷を大幅に削減。長時間実行アプリにも適応。
|
|
15
|
+
- **最近傍検索**: 数値キーに対して、最も近いキーペアをO(log n)で効率的に探索。
|
|
16
|
+
- **安全なイテレーション**: `safe: true`オプションにより、イテレーション中に他の操作(削除・挿入)を安全に実行可能。
|
|
14
17
|
|
|
15
18
|
## インストール
|
|
16
19
|
|
data/README.md
CHANGED
|
@@ -6,11 +6,14 @@ A pure Ruby implementation of the Red-Black Tree data structure, providing effic
|
|
|
6
6
|
|
|
7
7
|
## Features
|
|
8
8
|
|
|
9
|
-
- **Self-Balancing Binary Search Tree**: Maintains optimal performance through red-black tree properties
|
|
10
|
-
- **Ordered Operations**: Efficient range queries, min/max retrieval
|
|
11
|
-
- **Multi-Value Support**: `MultiRBTree` class
|
|
12
|
-
- **Pure Ruby**: No C extensions required
|
|
13
|
-
- **
|
|
9
|
+
- **Self-Balancing Binary Search Tree**: Maintains optimal performance through red-black tree properties. All insertions, deletions, and lookups run in O(log n).
|
|
10
|
+
- **Ordered Operations**: Efficient sorted iteration, range queries (`lt`, `gt`, `between`), min/max retrieval.
|
|
11
|
+
- **Multi-Value Support**: `MultiRBTree` class stores multiple values per key, with access to first or last value individually.
|
|
12
|
+
- **Pure Ruby**: No C extensions required. Works on MRI, JRuby, TruffleRuby, and all Ruby implementations.
|
|
13
|
+
- **Hybrid Indexing**: Internal hash index enables O(1) key lookup and membership checks — matching standard Hash performance.
|
|
14
|
+
- **Memory Efficiency**: Node recycling with auto-shrinking pool (`AutoShrinkNodePool`) drastically reduces GC pressure in long-running apps.
|
|
15
|
+
- **Nearest Key Search**: Finds the closest numeric key in O(log n) time — ideal for spatial or temporal queries.
|
|
16
|
+
- **Safe Iteration**: Use `safe: true` to safely modify the tree (insert/delete) during iteration.
|
|
14
17
|
|
|
15
18
|
## Installation
|
|
16
19
|
|
data/lib/rbtree/version.rb
CHANGED
data/lib/rbtree.rb
CHANGED
|
@@ -432,7 +432,7 @@ class RBTree
|
|
|
432
432
|
# tree.delete(k) if k.even?
|
|
433
433
|
# end
|
|
434
434
|
def keys(reverse: false, safe: false, &block)
|
|
435
|
-
return enum_for(
|
|
435
|
+
return enum_for(__method__, reverse: reverse, safe: safe) { @key_count } unless block_given?
|
|
436
436
|
each(reverse: reverse, safe: safe) { |key, _| yield key }
|
|
437
437
|
self
|
|
438
438
|
end
|
|
@@ -459,7 +459,7 @@ class RBTree
|
|
|
459
459
|
# tree.delete(k) if k.even?
|
|
460
460
|
# end
|
|
461
461
|
def each(reverse: false, safe: false, &block)
|
|
462
|
-
return enum_for(
|
|
462
|
+
return enum_for(__method__, reverse: reverse, safe: safe) { size } unless block_given?
|
|
463
463
|
if reverse
|
|
464
464
|
traverse_all_desc(@root, safe: safe, &block)
|
|
465
465
|
else
|
|
@@ -488,7 +488,7 @@ class RBTree
|
|
|
488
488
|
# @return [Enumerator, RBTree] an Enumerator if no block is given, self otherwise
|
|
489
489
|
# @see #each
|
|
490
490
|
def reverse_each(safe: false, &block)
|
|
491
|
-
return enum_for(
|
|
491
|
+
return enum_for(__method__, safe: safe) { size } unless block_given?
|
|
492
492
|
each(reverse: true, safe: safe, &block)
|
|
493
493
|
end
|
|
494
494
|
|
|
@@ -505,7 +505,7 @@ class RBTree
|
|
|
505
505
|
# tree.lt(3, reverse: true).first # => [2, "two"]
|
|
506
506
|
# tree.lt(3, safe: true) { |k, _| tree.delete(k) if k.even? } # safe to delete
|
|
507
507
|
def lt(key, reverse: false, safe: false, &block)
|
|
508
|
-
return enum_for(
|
|
508
|
+
return enum_for(__method__, key, reverse: reverse, safe: safe) unless block_given?
|
|
509
509
|
if reverse
|
|
510
510
|
traverse_lt_desc(@root, key, safe: safe, &block)
|
|
511
511
|
else
|
|
@@ -526,7 +526,7 @@ class RBTree
|
|
|
526
526
|
# tree.lte(3).to_a # => [[1, "one"], [2, "two"], [3, "three"]]
|
|
527
527
|
# tree.lte(3, reverse: true).first # => [3, "three"]
|
|
528
528
|
def lte(key, reverse: false, safe: false, &block)
|
|
529
|
-
return enum_for(
|
|
529
|
+
return enum_for(__method__, key, reverse: reverse, safe: safe) unless block_given?
|
|
530
530
|
if reverse
|
|
531
531
|
traverse_lte_desc(@root, key, safe: safe, &block)
|
|
532
532
|
else
|
|
@@ -547,7 +547,7 @@ class RBTree
|
|
|
547
547
|
# tree.gt(2).to_a # => [[3, "three"], [4, "four"]]
|
|
548
548
|
# tree.gt(2, reverse: true).first # => [4, "four"]
|
|
549
549
|
def gt(key, reverse: false, safe: false, &block)
|
|
550
|
-
return enum_for(
|
|
550
|
+
return enum_for(__method__, key, reverse: reverse, safe: safe) unless block_given?
|
|
551
551
|
if reverse
|
|
552
552
|
traverse_gt_desc(@root, key, safe: safe, &block)
|
|
553
553
|
else
|
|
@@ -568,7 +568,7 @@ class RBTree
|
|
|
568
568
|
# tree.gte(2).to_a # => [[2, "two"], [3, "three"], [4, "four"]]
|
|
569
569
|
# tree.gte(2, reverse: true).first # => [4, "four"]
|
|
570
570
|
def gte(key, reverse: false, safe: false, &block)
|
|
571
|
-
return enum_for(
|
|
571
|
+
return enum_for(__method__, key, reverse: reverse, safe: safe) unless block_given?
|
|
572
572
|
if reverse
|
|
573
573
|
traverse_gte_desc(@root, key, safe: safe, &block)
|
|
574
574
|
else
|
|
@@ -592,7 +592,7 @@ class RBTree
|
|
|
592
592
|
# tree.between(2, 4).to_a # => [[2, "two"], [3, "three"], [4, "four"]]
|
|
593
593
|
# tree.between(2, 4, reverse: true).first # => [4, "four"]
|
|
594
594
|
def between(min, max, include_min: true, include_max: true, reverse: false, safe: false, &block)
|
|
595
|
-
return enum_for(
|
|
595
|
+
return enum_for(__method__, min, max, include_min: include_min, include_max: include_max, reverse: reverse, safe: safe) unless block_given?
|
|
596
596
|
if reverse
|
|
597
597
|
traverse_between_desc(@root, min, max, include_min, include_max, safe: safe, &block)
|
|
598
598
|
else
|
|
@@ -1194,6 +1194,8 @@ class RBTree
|
|
|
1194
1194
|
# @param key [Object] the reference key
|
|
1195
1195
|
# @return [Node] the successor node, or @nil_node if none exists
|
|
1196
1196
|
def find_successor_node(key)
|
|
1197
|
+
# If key is smaller than min_key, return min_node
|
|
1198
|
+
return @min_node if min_key && key < min_key
|
|
1197
1199
|
# Check if key exists using O(1) hash lookup
|
|
1198
1200
|
if (node = @hash_index[key])
|
|
1199
1201
|
# Key exists: find successor in subtree or ancestors
|
|
@@ -1496,6 +1498,8 @@ class MultiRBTree < RBTree
|
|
|
1496
1498
|
# tree.get(1) # => "first"
|
|
1497
1499
|
# tree.get(1, last: true) # => "second"
|
|
1498
1500
|
def value(key, last: false) = @hash_index[key]&.value&.send(last ? :last : :first)
|
|
1501
|
+
alias :get :value
|
|
1502
|
+
alias :[] :value
|
|
1499
1503
|
|
|
1500
1504
|
# Retrieves the first value associated with the given key.
|
|
1501
1505
|
#
|
|
@@ -1521,7 +1525,7 @@ class MultiRBTree < RBTree
|
|
|
1521
1525
|
# tree.insert(1, 'second')
|
|
1522
1526
|
# tree.values(1).to_a # => ["first", "second"]
|
|
1523
1527
|
def values(key, reverse: false)
|
|
1524
|
-
return enum_for(
|
|
1528
|
+
return enum_for(__method__, key) { value_count(key) } unless block_given?
|
|
1525
1529
|
@hash_index[key]&.value&.send(reverse ? :reverse_each : :each) { |v| yield v }
|
|
1526
1530
|
end
|
|
1527
1531
|
alias :get_all :values
|
|
@@ -1622,6 +1626,7 @@ class MultiRBTree < RBTree
|
|
|
1622
1626
|
delete_indexed_node(z.key)
|
|
1623
1627
|
value
|
|
1624
1628
|
end
|
|
1629
|
+
alias :delete :delete_key
|
|
1625
1630
|
|
|
1626
1631
|
# Removes and returns the first key-value pair.
|
|
1627
1632
|
#
|