rbtree-ruby 0.1.3 → 0.1.4

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: bc2846050227a83e7ae7bb63d1e6208ed39acc54de759c98e08d994685d1b067
4
- data.tar.gz: 2a28105ee3667fb794c1f5d32c396b21542f45bceb3c858c160d7389f6d2ae3b
3
+ metadata.gz: 3d5898bb2e8aaea4617747c5f4024ab023a1afeabba3abafeaf2b86bb6afa986
4
+ data.tar.gz: c6651a33b8e66ee3528dc8ab3abf2359f3e2647fc27491e8bd5083ef08844d77
5
5
  SHA512:
6
- metadata.gz: 22239d22c7b771a93bbb1811407d6ea6364ae21b22008d53d44e102188991b7299b6dacdcbc28a206dbfd21658d8081f964bf855b7c69c3d19d3312be49ffe3d
7
- data.tar.gz: 8f98487332a3cb77f478f745b775b148aff862ab80fc020d064cade6a84692a4e498854cce864b4d49806a760ee7c6d9c38e4e9ac3e5c7598444ead625e91eb7
6
+ metadata.gz: e7d1619486160150a91842631953842f3bddcb90213d415ec9aaca846184220ada9494cdae1eadf05ae5d523c5646b1ce19590d0b60c9df8ddd0c0f01a40ede7
7
+ data.tar.gz: ed2f20ab619e64c6daf16f4484fc52b0bc724e3b9b0f8b08c3a61921cbde5077f99beace823afbf3133c74ab3dfd838b48c5b09392bcaaee4fc0a930eb507589
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.1.4] - 2026-01-13
9
+
10
+ ### Changed
11
+ - **Memory Pool**: Implemented internal node recycling mechanism
12
+ - Reuse `RBTree::Node` objects instead of creating new ones for every insertion
13
+ - Significantly reduces GC pressure during frequent insert/delete operations
14
+ - Automatically manages pool size (grows on delete, shrinks on insert)
15
+ - Fully transparent to the user
16
+
8
17
  ## [0.1.3] - 2026-01-13
9
18
 
10
19
  ### Changed
@@ -59,5 +68,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
59
68
  - ASCII diagrams for tree rotation operations
60
69
  - MIT License (Copyright © 2026 Masahito Suzuki)
61
70
 
71
+ [0.1.4]: https://github.com/firelzrd/rbtree-ruby/releases/tag/v0.1.4
62
72
  [0.1.3]: https://github.com/firelzrd/rbtree-ruby/releases/tag/v0.1.3
63
73
  [0.1.2]: https://github.com/firelzrd/rbtree-ruby/releases/tag/v0.1.2
data/README.md CHANGED
@@ -133,12 +133,47 @@ All major operations run in **O(log n)** time:
133
133
 
134
134
  - `insert(key, value)` - O(log n)
135
135
  - `delete(key)` - O(log n)
136
- - `get(key)` / `[]` - O(log n)
137
- - `min` / `max` - O(1) for min, O(log n) for max
136
+ - `get(key)` / `[]` - **O(1)** (hybrid hash index)
137
+ - `has_key?` - **O(1)** (hybrid hash index)
138
+ - `min` - **O(1)**
139
+ - `max` - O(log n)
138
140
  - `shift` / `pop` - O(log n)
139
141
 
140
142
  Iteration over all elements takes O(n) time.
141
143
 
144
+ ### Memory Efficiency
145
+
146
+ RBTree uses an internal **Memory Pool** to recycle node objects.
147
+ - Significantly reduces Garbage Collection (GC) pressure during frequent insertions and deletions (e.g., in high-throughput queues).
148
+ - In benchmarks with 100,000 cyclic operations, **GC time was 0.0s** compared to significant pauses without pooling.
149
+
150
+ ### RBTree vs Hash vs Array
151
+
152
+ RBTree provides significant advantages for ordered operations:
153
+
154
+ | Operation | RBTree | Hash | Speedup |
155
+ |-----------|--------|------|---------|
156
+ | `min` / `max` | O(1) / O(log n) | O(n) | **~1000x faster** |
157
+ | Range queries (`between`, `lt`, `gt`) | O(log n + k) | O(n) | **10-100x faster** |
158
+ | Nearest key search | O(log n) | O(n) | **100x+ faster** |
159
+ | Ordered iteration | O(n), always sorted | Requires `sort` O(n log n) | **Free sorting** |
160
+ | Key lookup | O(1) | O(1) | Equal |
161
+
162
+ ### When to Use RBTree
163
+
164
+ ✅ **Use RBTree when you need:**
165
+ - Ordered iteration by key
166
+ - Fast min/max retrieval
167
+ - Range queries (`between`, `lt`, `gt`, `lte`, `gte`)
168
+ - Nearest key search
169
+ - Priority queue behavior (shift/pop by key order)
170
+
171
+ ✅ **Use Hash when you only need:**
172
+ - Fast key-value lookup (RBTree is now equally fast!)
173
+ - No ordering requirements
174
+
175
+ Run `ruby demo.rb` for a full benchmark demonstration.
176
+
142
177
  ## API Documentation
143
178
 
144
179
  Full RDoc documentation is available. Generate it locally with:
@@ -2,5 +2,5 @@
2
2
 
3
3
  class RBTree
4
4
  # The version of the rbtree-ruby gem
5
- VERSION = "0.1.3"
5
+ VERSION = "0.1.4"
6
6
  end
data/lib/rbtree.rb CHANGED
@@ -93,6 +93,7 @@ class RBTree
93
93
  @root = @nil_node
94
94
  @min_node = @nil_node
95
95
  @hash_index = {} # Hash index for O(1) key lookup
96
+ @node_pool = [] # Memory pool for recycling nodes
96
97
  @size = 0
97
98
 
98
99
  if args.any?
@@ -188,7 +189,7 @@ class RBTree
188
189
  x = x.right
189
190
  end
190
191
  end
191
- z = Node.new(key, value, Node::RED, @nil_node, @nil_node, @nil_node)
192
+ z = allocate_node(key, value, Node::RED, @nil_node, @nil_node, @nil_node)
192
193
  z.parent = y
193
194
  if y == @nil_node
194
195
  @root = z
@@ -680,7 +681,9 @@ class RBTree
680
681
  @min_node = next_min_node
681
682
  end
682
683
 
683
- z.value
684
+ value = z.value
685
+ release_node(z)
686
+ value
684
687
  end
685
688
 
686
689
  # Restores red-black tree properties after deletion.
@@ -900,6 +903,32 @@ class RBTree
900
903
  y.parent = x
901
904
  end
902
905
 
906
+ # Allocates a new node or recycles one from the pool.
907
+ # @return [Node]
908
+ def allocate_node(key, value, color, left, right, parent)
909
+ if (node = @node_pool.pop)
910
+ node.key = key
911
+ node.value = value
912
+ node.color = color
913
+ node.left = left
914
+ node.right = right
915
+ node.parent = parent
916
+ node
917
+ else
918
+ Node.new(key, value, color, left, right, parent)
919
+ end
920
+ end
921
+
922
+ # Releases a node back to the pool.
923
+ # @param node [Node] the node to release
924
+ def release_node(node)
925
+ node.left = nil
926
+ node.right = nil
927
+ node.parent = nil
928
+ node.value = nil # Help GC
929
+ @node_pool << node
930
+ end
931
+
903
932
  # Recursively checks black height consistency.
904
933
  #
905
934
  # Verifies that:
@@ -1024,7 +1053,7 @@ class MultiRBTree < RBTree
1024
1053
  x = x.right
1025
1054
  end
1026
1055
  end
1027
- z = Node.new(key, [value], Node::RED, @nil_node, @nil_node, @nil_node)
1056
+ z = allocate_node(key, [value], Node::RED, @nil_node, @nil_node, @nil_node)
1028
1057
  z.parent = y
1029
1058
  if y == @nil_node
1030
1059
  @root = z
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.1.3
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masahito Suzuki