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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 327862d13e55ed6406023e1d10676e4b5e94541c59400d9205380af08822e4bf
4
- data.tar.gz: 465e1a514390286bf0165db4dfa9f25ada4cd3d1410b0115b11eba15b03dcf33
3
+ metadata.gz: 2145d91a96cc64b7e65c65460716b678301f74d6decdffa2dbd077a914273c21
4
+ data.tar.gz: 66503c542ce07672a493830afbfcb66ebfea14d8563e67b1b2dd1d5ecd1d9c48
5
5
  SHA512:
6
- metadata.gz: 1f354523b8fb78b746cf256949887b89184ce1dcd190403a7024949cded391de24ce6f932720a58ae24592b4b453f3901b1896c9904f546aa03fe4b1524698c2
7
- data.tar.gz: e1219a20ea771f3fe1ca2fc160d737c787a1a0e81cb5389b63f320dcd1d2ac9d2cc71d9df2b9698d73afc98069f76d39285ca8106691f0025f1d5a5fa8b6bf91
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拡張不要、あらゆるRuby実装で動作
13
- - **充実したドキュメント**: 使用例付きの包括的なRDocドキュメント
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, and sorted iteration
11
- - **Multi-Value Support**: `MultiRBTree` class for storing multiple values per key
12
- - **Pure Ruby**: No C extensions required, works on any Ruby implementation
13
- - **Well-Documented**: Comprehensive RDoc documentation with examples
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
 
@@ -2,5 +2,5 @@
2
2
 
3
3
  class RBTree
4
4
  # The version of the rbtree-ruby gem
5
- VERSION = "0.3.2"
5
+ VERSION = "0.3.3"
6
6
  end
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(:keys, reverse: reverse, safe: safe) { @key_count } unless block_given?
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(:each, reverse: reverse, safe: safe) { size } unless block_given?
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(:reverse_each, safe: safe) { size } unless block_given?
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(:lt, key, reverse: reverse, safe: safe) unless block_given?
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(:lte, key, reverse: reverse, safe: safe) unless block_given?
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(:gt, key, reverse: reverse, safe: safe) unless block_given?
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(:gte, key, reverse: reverse, safe: safe) unless block_given?
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(:between, min, max, include_min: include_min, include_max: include_max, reverse: reverse, safe: safe) unless block_given?
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(:values, key) { value_count(key) } unless block_given?
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
  #
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbtree-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masahito Suzuki