rbtree-ruby 0.1.2 → 0.1.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 +11 -0
- data/lib/rbtree/version.rb +1 -1
- data/lib/rbtree.rb +15 -12
- 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: bc2846050227a83e7ae7bb63d1e6208ed39acc54de759c98e08d994685d1b067
|
|
4
|
+
data.tar.gz: 2a28105ee3667fb794c1f5d32c396b21542f45bceb3c858c160d7389f6d2ae3b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 22239d22c7b771a93bbb1811407d6ea6364ae21b22008d53d44e102188991b7299b6dacdcbc28a206dbfd21658d8081f964bf855b7c69c3d19d3312be49ffe3d
|
|
7
|
+
data.tar.gz: 8f98487332a3cb77f478f745b775b148aff862ab80fc020d064cade6a84692a4e498854cce864b4d49806a760ee7c6d9c38e4e9ac3e5c7598444ead625e91eb7
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,16 @@ 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.3] - 2026-01-13
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
- **Hybrid Hash Index**: Added internal `@hash_index` for O(1) key lookup
|
|
12
|
+
- `get(key)` and `has_key?(key)` now use hash lookup instead of tree traversal
|
|
13
|
+
- Search performance now matches Hash (within 10-20% overhead)
|
|
14
|
+
- Benchmark: 10M elements, 1M lookups - RBTree 290ms vs Hash 271ms
|
|
15
|
+
- Both RBTree and MultiRBTree benefit from this optimization
|
|
16
|
+
- Memory trade-off: ~1.5x due to hash index storage
|
|
17
|
+
|
|
8
18
|
## [0.1.2] - 2026-01-13
|
|
9
19
|
|
|
10
20
|
### Changed
|
|
@@ -49,4 +59,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
49
59
|
- ASCII diagrams for tree rotation operations
|
|
50
60
|
- MIT License (Copyright © 2026 Masahito Suzuki)
|
|
51
61
|
|
|
62
|
+
[0.1.3]: https://github.com/firelzrd/rbtree-ruby/releases/tag/v0.1.3
|
|
52
63
|
[0.1.2]: https://github.com/firelzrd/rbtree-ruby/releases/tag/v0.1.2
|
data/lib/rbtree/version.rb
CHANGED
data/lib/rbtree.rb
CHANGED
|
@@ -92,6 +92,7 @@ class RBTree
|
|
|
92
92
|
@nil_node.right = @nil_node
|
|
93
93
|
@root = @nil_node
|
|
94
94
|
@min_node = @nil_node
|
|
95
|
+
@hash_index = {} # Hash index for O(1) key lookup
|
|
95
96
|
@size = 0
|
|
96
97
|
|
|
97
98
|
if args.any?
|
|
@@ -139,7 +140,7 @@ class RBTree
|
|
|
139
140
|
# tree.has_key?(1) # => true
|
|
140
141
|
# tree.has_key?(3) # => false
|
|
141
142
|
def has_key?(key)
|
|
142
|
-
|
|
143
|
+
@hash_index.key?(key)
|
|
143
144
|
end
|
|
144
145
|
|
|
145
146
|
# Retrieves the value associated with the given key.
|
|
@@ -152,8 +153,7 @@ class RBTree
|
|
|
152
153
|
# tree[2] # => "two"
|
|
153
154
|
# tree[3] # => nil
|
|
154
155
|
def get(key)
|
|
155
|
-
|
|
156
|
-
n == @nil_node ? nil : n.value
|
|
156
|
+
@hash_index[key]&.value
|
|
157
157
|
end
|
|
158
158
|
alias_method :[], :get
|
|
159
159
|
|
|
@@ -207,6 +207,7 @@ class RBTree
|
|
|
207
207
|
@min_node = z
|
|
208
208
|
end
|
|
209
209
|
|
|
210
|
+
@hash_index[key] = z # Add to hash index
|
|
210
211
|
true
|
|
211
212
|
end
|
|
212
213
|
alias_method :[]=, :insert
|
|
@@ -232,6 +233,7 @@ class RBTree
|
|
|
232
233
|
def clear
|
|
233
234
|
@root = @nil_node
|
|
234
235
|
@min_node = @nil_node
|
|
236
|
+
@hash_index.clear
|
|
235
237
|
@size = 0
|
|
236
238
|
self
|
|
237
239
|
end
|
|
@@ -622,8 +624,8 @@ class RBTree
|
|
|
622
624
|
# @param key [Object] the key to delete
|
|
623
625
|
# @return [Object, nil] the value of the deleted node, or nil if not found
|
|
624
626
|
def delete_node(key)
|
|
625
|
-
z =
|
|
626
|
-
return nil
|
|
627
|
+
z = @hash_index.delete(key) # O(1) lookup and remove from index
|
|
628
|
+
return nil unless z
|
|
627
629
|
remove_node(z)
|
|
628
630
|
end
|
|
629
631
|
|
|
@@ -936,12 +938,12 @@ end
|
|
|
936
938
|
# A Multi Red-Black Tree that allows duplicate keys.
|
|
937
939
|
#
|
|
938
940
|
# MultiRBTree extends RBTree to support multiple values per key. Each key maps to
|
|
939
|
-
#
|
|
941
|
+
# an array of values rather than a single value. The size reflects the total
|
|
940
942
|
# number of key-value pairs (not unique keys).
|
|
941
943
|
#
|
|
942
944
|
# == Features
|
|
943
945
|
#
|
|
944
|
-
# * Multiple values per key using
|
|
946
|
+
# * Multiple values per key using arrays
|
|
945
947
|
# * Separate methods for single deletion (`delete_one`) vs. all deletions (`delete`)
|
|
946
948
|
# * Values for each key maintain insertion order
|
|
947
949
|
# * min/max return first/last values respectively
|
|
@@ -1041,6 +1043,7 @@ class MultiRBTree < RBTree
|
|
|
1041
1043
|
@min_node = z
|
|
1042
1044
|
end
|
|
1043
1045
|
|
|
1046
|
+
@hash_index[key] = z # Add to hash index
|
|
1044
1047
|
true
|
|
1045
1048
|
end
|
|
1046
1049
|
|
|
@@ -1058,12 +1061,13 @@ class MultiRBTree < RBTree
|
|
|
1058
1061
|
# tree.delete_one(1) # => "first"
|
|
1059
1062
|
# tree.get(1) # => "second"
|
|
1060
1063
|
def delete_one(key)
|
|
1061
|
-
z =
|
|
1062
|
-
return nil
|
|
1064
|
+
z = @hash_index[key] # O(1) lookup
|
|
1065
|
+
return nil unless z
|
|
1063
1066
|
|
|
1064
1067
|
value = z.value.shift
|
|
1065
1068
|
@size -= 1
|
|
1066
1069
|
if z.value.empty?
|
|
1070
|
+
@hash_index.delete(key) # Remove from index when node removed
|
|
1067
1071
|
remove_node(z)
|
|
1068
1072
|
end
|
|
1069
1073
|
value
|
|
@@ -1082,8 +1086,8 @@ class MultiRBTree < RBTree
|
|
|
1082
1086
|
# vals = tree.delete(1) # removes both values
|
|
1083
1087
|
# vals.size # => 2
|
|
1084
1088
|
def delete(key)
|
|
1085
|
-
z =
|
|
1086
|
-
return nil
|
|
1089
|
+
z = @hash_index.delete(key) # O(1) lookup and remove from index
|
|
1090
|
+
return nil unless z
|
|
1087
1091
|
|
|
1088
1092
|
count = z.value.size
|
|
1089
1093
|
remove_node(z)
|
|
@@ -1257,4 +1261,3 @@ class RBTree::Node
|
|
|
1257
1261
|
# @return [Boolean] true if black, false otherwise
|
|
1258
1262
|
def black? = @color == BLACK
|
|
1259
1263
|
end
|
|
1260
|
-
|