rbtree-ruby 0.2.2 → 0.3.0
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 +35 -0
- data/README.ja.md +24 -18
- data/README.md +21 -17
- data/lib/rbtree/version.rb +1 -1
- data/lib/rbtree.old.rb +1588 -0
- data/lib/rbtree.rb +418 -243
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 28594e663eac8519467b09c0756a032b2ef887d69df9e9335d1d79c36744a134
|
|
4
|
+
data.tar.gz: 492d6896dd4a0644ecc8ad721214afe2827daf3acbde38dce938e6da54cac87f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3aeeca5b0d3de1a8826fac660dc6b201c046cb193328ba75bcd20f679f682fbf65479179fcddebe63920522eaa9ede28a9f8a784c76387e86530105a7378c8cd
|
|
7
|
+
data.tar.gz: 1e960a2132c1c3bc8988e233ebfb249f121900ac6eabbbcce0aa86186ceb24caa3224d4e7ebb8ad2acda5b927976ec0d5a0437ec20ad5fe2162eda841d15f909
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,37 @@ 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.0] - 2026-01-15
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
### API Changes (Method Renaming & Deprecation)
|
|
12
|
+
> [!WARNING]
|
|
13
|
+
> The public API has been refactored to improve consistency. The following methods have been renamed.
|
|
14
|
+
> Old methods are preserved as aliases for backward compatibility but are **deprecated** and may be removed in future versions.
|
|
15
|
+
|
|
16
|
+
* `get_all` -> `values` (Returns Enumerator by default)
|
|
17
|
+
* `delete_one` -> `delete_value`
|
|
18
|
+
* `delete` (MultiRBTree) -> `delete_key`
|
|
19
|
+
* *Note: `delete` is now an alias for `delete_key` in MultiRBTree for compatibility.*
|
|
20
|
+
* `get` (MultiRBTree) -> *Behavior clarified*: Returns first value (alias for `first_value` or `value(key)`)
|
|
21
|
+
* `get_first`/`get_last` -> `first_value`/`last_value`
|
|
22
|
+
* `delete_first`/`delete_last` -> `delete_first_value`/`delete_last_value`
|
|
23
|
+
|
|
24
|
+
- **Visibility**: `insert_entry` (RBTree) and traversal helper methods (MultiRBTree) are now `private` instead of `protected`, as they are internal implementation details.
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
- **MultiRBTree Traversal Fix**: Fixed an issue where `MultiRBTree#each` and other traversal methods yielded `key, value` as separate arguments instead of a single `[key, value]` array. This ensures compatibility with `Enumerable` methods like `count` and consistent behavior with `RBTree` and standard `Hash`.
|
|
28
|
+
|
|
29
|
+
## [0.2.3] - 2026-01-14
|
|
30
|
+
|
|
31
|
+
### Added
|
|
32
|
+
- **Bulk Insert**: `insert` now supports bulk insertion from Hash, Array of pairs, Enumerator, or Block.
|
|
33
|
+
- `tree.insert({1 => 'one', 2 => 'two'})`
|
|
34
|
+
- `tree.insert([[1, 'one'], [2, 'two']])`
|
|
35
|
+
- `tree.insert { source_data }`
|
|
36
|
+
- **Flexible Initialization**: `RBTree.new` and `MultiRBTree.new` now accept bulk data and an `overwrite:` option.
|
|
37
|
+
- `RBTree.new([[1, 'a'], [1, 'b']], overwrite: false)`
|
|
38
|
+
|
|
8
39
|
## [0.2.2] - 2026-01-14
|
|
9
40
|
|
|
10
41
|
### Changed
|
|
@@ -153,6 +184,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
153
184
|
- ASCII diagrams for tree rotation operations
|
|
154
185
|
- MIT License (Copyright © 2026 Masahito Suzuki)
|
|
155
186
|
|
|
187
|
+
[0.3.0]: https://github.com/firelzrd/rbtree-ruby/releases/tag/v0.3.0
|
|
188
|
+
[0.2.3]: https://github.com/firelzrd/rbtree-ruby/releases/tag/v0.2.3
|
|
189
|
+
[0.2.2]: https://github.com/firelzrd/rbtree-ruby/releases/tag/v0.2.2
|
|
190
|
+
[0.2.1]: https://github.com/firelzrd/rbtree-ruby/releases/tag/v0.2.1
|
|
156
191
|
[0.2.0]: https://github.com/firelzrd/rbtree-ruby/releases/tag/v0.2.0
|
|
157
192
|
[0.1.8]: https://github.com/firelzrd/rbtree-ruby/releases/tag/v0.1.8
|
|
158
193
|
[0.1.7]: https://github.com/firelzrd/rbtree-ruby/releases/tag/v0.1.7
|
data/README.ja.md
CHANGED
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
🌍 *[English](README.md) | [日本語](README.ja.md)*
|
|
4
4
|
|
|
5
|
-
Red-Black Tree(赤黒木)データ構造のピュアRuby実装です。挿入、削除、検索操作がO(log n)
|
|
6
|
-
効率的な順序付きキーバリューストレージを提供します。
|
|
5
|
+
Red-Black Tree(赤黒木)データ構造のピュアRuby実装です。挿入、削除、検索操作がO(log n)の時間計算量で実行できる、効率的な順序付きキーバリューストレージを提供します。
|
|
7
6
|
|
|
8
7
|
## 特徴
|
|
9
8
|
|
|
@@ -43,13 +42,18 @@ require 'rbtree'
|
|
|
43
42
|
# 空のツリーを作成
|
|
44
43
|
tree = RBTree.new
|
|
45
44
|
|
|
46
|
-
#
|
|
45
|
+
# データで初期化(バルク挿入)
|
|
47
46
|
tree = RBTree.new({3 => 'three', 1 => 'one', 2 => 'two'})
|
|
48
47
|
tree = RBTree[[5, 'five'], [4, 'four']]
|
|
48
|
+
tree = RBTree.new do # ブロック初期化
|
|
49
|
+
data_source.each { |data| [data.time, data.content] }
|
|
50
|
+
end
|
|
49
51
|
|
|
50
52
|
# 値の挿入と取得
|
|
51
53
|
tree.insert(10, 'ten')
|
|
52
54
|
tree[20] = 'twenty'
|
|
55
|
+
# バルク挿入
|
|
56
|
+
tree.insert({30 => 'thirty', 40 => 'forty'})
|
|
53
57
|
puts tree[10] # => "ten"
|
|
54
58
|
|
|
55
59
|
# ソート順でイテレーション
|
|
@@ -104,11 +108,11 @@ tree.insert(2, 'two')
|
|
|
104
108
|
tree.size # => 4 (キーバリューペアの総数)
|
|
105
109
|
|
|
106
110
|
# 最初の値を取得
|
|
107
|
-
tree.
|
|
111
|
+
tree.value(1) # => "first one"
|
|
108
112
|
tree[1] # => "first one"
|
|
109
113
|
|
|
110
114
|
# キーの全ての値を取得(Enumeratorを返す)
|
|
111
|
-
tree.
|
|
115
|
+
tree.values(1).to_a # => ["first one", "second one", "third one"]
|
|
112
116
|
|
|
113
117
|
# 全キーバリューペアをイテレーション
|
|
114
118
|
tree.each { |k, v| puts "#{k}: #{v}" }
|
|
@@ -119,11 +123,11 @@ tree.each { |k, v| puts "#{k}: #{v}" }
|
|
|
119
123
|
# 2: two
|
|
120
124
|
|
|
121
125
|
# 最初の値のみ削除
|
|
122
|
-
tree.
|
|
123
|
-
tree.
|
|
126
|
+
tree.delete_value(1) # => "first one"
|
|
127
|
+
tree.value(1) # => "second one"
|
|
124
128
|
|
|
125
129
|
# キーの全ての値を削除
|
|
126
|
-
tree.
|
|
130
|
+
tree.delete_key(1) # 残りの値を全て削除
|
|
127
131
|
```
|
|
128
132
|
|
|
129
133
|
### 最近傍キー検索
|
|
@@ -138,6 +142,8 @@ tree.nearest(8) # => [10, "ten"]
|
|
|
138
142
|
|
|
139
143
|
### 前後キー検索
|
|
140
144
|
|
|
145
|
+
ツリーの中で次のキーまたは前のキーを検索します。
|
|
146
|
+
|
|
141
147
|
```ruby
|
|
142
148
|
tree = RBTree.new({1 => 'one', 3 => 'three', 5 => 'five', 7 => 'seven'})
|
|
143
149
|
|
|
@@ -179,15 +185,15 @@ tree.insert(1, 'second')
|
|
|
179
185
|
tree.insert(1, 'third')
|
|
180
186
|
|
|
181
187
|
# 最初または最後の値にアクセス
|
|
182
|
-
tree.
|
|
183
|
-
tree.
|
|
184
|
-
tree.
|
|
185
|
-
tree.
|
|
188
|
+
tree.value(1) # => "first"
|
|
189
|
+
tree.value(1, last: true) # => "third"
|
|
190
|
+
tree.first_value(1) # => "first"
|
|
191
|
+
tree.last_value(1) # => "third"
|
|
186
192
|
|
|
187
193
|
# どちらの端からも削除可能
|
|
188
|
-
tree.
|
|
189
|
-
tree.
|
|
190
|
-
tree.
|
|
194
|
+
tree.delete_first_value(1) # => "first"
|
|
195
|
+
tree.delete_last_value(1) # => "third"
|
|
196
|
+
tree.value(1) # => "second"
|
|
191
197
|
|
|
192
198
|
# min/maxの:lastオプション
|
|
193
199
|
tree.insert(2, 'a')
|
|
@@ -202,8 +208,8 @@ tree.max(last: true) # => [2, "b"] (最大キーの最後の値)
|
|
|
202
208
|
|
|
203
209
|
- `insert(key, value)` - O(log n)
|
|
204
210
|
- `delete(key)` - O(log n)
|
|
205
|
-
- `
|
|
206
|
-
- `has_key?` - **O(1)** (
|
|
211
|
+
- `value(key)` / `[]` - **O(1)** (内部ハッシュインデックスによる超高速アクセス)
|
|
212
|
+
- `has_key?` - **O(1)** (内部ハッシュインデックスによる超高速チェック)
|
|
207
213
|
- `min` - **O(1)**
|
|
208
214
|
- `max` - O(log n)
|
|
209
215
|
- `shift` / `pop` - O(log n)
|
|
@@ -227,7 +233,7 @@ RBTreeは内部的な**メモリプール**を使用してノードオブジェ
|
|
|
227
233
|
| **範囲クエリ** | **O(log n + k)** | O(n) フィルター | **〜540倍高速** | 部分木へ直接ジャンプ vs 全件スキャン |
|
|
228
234
|
| **最小値抽出** | **O(log n)** | O(n) 検索 | **〜160倍高速** | 連続的なリバランス vs 全件スキャン |
|
|
229
235
|
| **ソート済みイテレーション** | **O(n)** | O(n log n) | **無料** | 常にソート済み vs 明示的な`sort` |
|
|
230
|
-
| **キー検索** | **O(1)** | O(1) | **同等** |
|
|
236
|
+
| **キー検索** | **O(1)** | O(1) | **同等** | **ハイブリッドハッシュインデックスにより、Hashと同等のO(1)検索速度を実現** |
|
|
231
237
|
|
|
232
238
|
### RBTreeを使うべき場面
|
|
233
239
|
|
data/README.md
CHANGED
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
🌍 *[English](README.md) | [日本語](README.ja.md)*
|
|
4
4
|
|
|
5
|
-
A pure Ruby implementation of the Red-Black Tree data structure, providing efficient ordered
|
|
6
|
-
key-value storage with O(log n) time complexity for insertion, deletion, and lookup operations.
|
|
5
|
+
A pure Ruby implementation of the Red-Black Tree data structure, providing efficient ordered key-value storage with O(log n) time complexity for insertion, deletion, and lookup operations.
|
|
7
6
|
|
|
8
7
|
## Features
|
|
9
8
|
|
|
@@ -43,13 +42,18 @@ require 'rbtree'
|
|
|
43
42
|
# Create an empty tree
|
|
44
43
|
tree = RBTree.new
|
|
45
44
|
|
|
46
|
-
# Or initialize with data
|
|
45
|
+
# Or initialize with data (Bulk Insert)
|
|
47
46
|
tree = RBTree.new({3 => 'three', 1 => 'one', 2 => 'two'})
|
|
48
47
|
tree = RBTree[[5, 'five'], [4, 'four']]
|
|
48
|
+
tree = RBTree.new do # Block initialization
|
|
49
|
+
data_source.each { |data| [data.time, data.content] }
|
|
50
|
+
end
|
|
49
51
|
|
|
50
52
|
# Insert and retrieve values
|
|
51
53
|
tree.insert(10, 'ten')
|
|
52
54
|
tree[20] = 'twenty'
|
|
55
|
+
# Bulk insert
|
|
56
|
+
tree.insert({30 => 'thirty', 40 => 'forty'})
|
|
53
57
|
puts tree[10] # => "ten"
|
|
54
58
|
|
|
55
59
|
# Iterate in sorted order
|
|
@@ -104,11 +108,11 @@ tree.insert(2, 'two')
|
|
|
104
108
|
tree.size # => 4 (total number of key-value pairs)
|
|
105
109
|
|
|
106
110
|
# Get first value
|
|
107
|
-
tree.
|
|
111
|
+
tree.value(1) # => "first one"
|
|
108
112
|
tree[1] # => "first one"
|
|
109
113
|
|
|
110
114
|
# Get all values for a key (returns Enumerator)
|
|
111
|
-
tree.
|
|
115
|
+
tree.values(1).to_a # => ["first one", "second one", "third one"]
|
|
112
116
|
|
|
113
117
|
# Iterate over all key-value pairs
|
|
114
118
|
tree.each { |k, v| puts "#{k}: #{v}" }
|
|
@@ -119,11 +123,11 @@ tree.each { |k, v| puts "#{k}: #{v}" }
|
|
|
119
123
|
# 2: two
|
|
120
124
|
|
|
121
125
|
# Delete only first value
|
|
122
|
-
tree.
|
|
123
|
-
tree.
|
|
126
|
+
tree.delete_value(1) # => "first one"
|
|
127
|
+
tree.value(1) # => "second one"
|
|
124
128
|
|
|
125
129
|
# Delete all values for a key
|
|
126
|
-
tree.
|
|
130
|
+
tree.delete_key(1) # removes all remaining values
|
|
127
131
|
```
|
|
128
132
|
|
|
129
133
|
### Nearest Key Search
|
|
@@ -181,15 +185,15 @@ tree.insert(1, 'second')
|
|
|
181
185
|
tree.insert(1, 'third')
|
|
182
186
|
|
|
183
187
|
# Access first or last value
|
|
184
|
-
tree.
|
|
185
|
-
tree.
|
|
186
|
-
tree.
|
|
187
|
-
tree.
|
|
188
|
+
tree.value(1) # => "first"
|
|
189
|
+
tree.value(1, last: true) # => "third"
|
|
190
|
+
tree.first_value(1) # => "first"
|
|
191
|
+
tree.last_value(1) # => "third"
|
|
188
192
|
|
|
189
193
|
# Delete from either end
|
|
190
|
-
tree.
|
|
191
|
-
tree.
|
|
192
|
-
tree.
|
|
194
|
+
tree.delete_first_value(1) # => "first"
|
|
195
|
+
tree.delete_last_value(1) # => "third"
|
|
196
|
+
tree.value(1) # => "second"
|
|
193
197
|
|
|
194
198
|
# min/max with :last option
|
|
195
199
|
tree.insert(2, 'a')
|
|
@@ -204,7 +208,7 @@ All major operations run in **O(log n)** time:
|
|
|
204
208
|
|
|
205
209
|
- `insert(key, value)` - O(log n)
|
|
206
210
|
- `delete(key)` - O(log n)
|
|
207
|
-
- `
|
|
211
|
+
- `value(key)` / `[]` - **O(1)** (hybrid hash index)
|
|
208
212
|
- `has_key?` - **O(1)** (hybrid hash index)
|
|
209
213
|
- `min` - **O(1)**
|
|
210
214
|
- `max` - O(log n)
|
|
@@ -229,7 +233,7 @@ For ordered and spatial operations, RBTree is not just faster—it is in a compl
|
|
|
229
233
|
| **Range Queries** | **O(log n + k)** | O(n) filter | **~540x faster** | Direct subtree jump vs full scan |
|
|
230
234
|
| **Min Extraction** | **O(log n)** | O(n) search | **~160x faster** | Continuous rebalancing vs full scan |
|
|
231
235
|
| **Sorted Iteration** | **O(n)** | O(n log n) | **FREE** | Always sorted vs explicit `sort` |
|
|
232
|
-
| **Key Lookup** | **O(1)** | O(1) | **Equal** |
|
|
236
|
+
| **Key Lookup** | **O(1)** | O(1) | **Equal** | **Hybrid Hash Index provides O(1) access like standard Hash** |
|
|
233
237
|
|
|
234
238
|
### When to Use RBTree
|
|
235
239
|
|
data/lib/rbtree/version.rb
CHANGED