rbtree-ruby 0.3.0 → 0.3.1

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: 28594e663eac8519467b09c0756a032b2ef887d69df9e9335d1d79c36744a134
4
- data.tar.gz: 492d6896dd4a0644ecc8ad721214afe2827daf3acbde38dce938e6da54cac87f
3
+ metadata.gz: df8aaee3fedf309a0079082fa38c10e3748bc68873131800e13f30dee1202273
4
+ data.tar.gz: 5e6dd162b0ebb1b50929d9127c4ac57598c7391ecf63a7d1dca7e42107d4ca3a
5
5
  SHA512:
6
- metadata.gz: 3aeeca5b0d3de1a8826fac660dc6b201c046cb193328ba75bcd20f679f682fbf65479179fcddebe63920522eaa9ede28a9f8a784c76387e86530105a7378c8cd
7
- data.tar.gz: 1e960a2132c1c3bc8988e233ebfb249f121900ac6eabbbcce0aa86186ceb24caa3224d4e7ebb8ad2acda5b927976ec0d5a0437ec20ad5fe2162eda841d15f909
6
+ metadata.gz: c1df7b56cad01d4a0725668f415510a3e65fd6409a0271143504ec1223d64a7e395a93a1dbd43881ceb75e5a36ea9328f60e86e95cdfcde653ab075fab81cb7b
7
+ data.tar.gz: cecad1db1c9fba3eb4c91b20493dc849cfbf70f8d2e1fede1c09e8b22d59d925e724e26788e06627a02b620de42c655afef4a8be51d31fdeaff5fa5158a2d192
data/CHANGELOG.md CHANGED
@@ -5,9 +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.3.1] - 2026-01-15
9
+
10
+ ### Added
11
+ - **`to_h`**: Added `to_h` method to `RBTree` and `MultiRBTree` for efficient conversion to Hash.
12
+ - **`merge!`**: Added `merge!` method to `RBTree` and `MultiRBTree`.
13
+ - `RBTree#merge!`: Supports `overwrite` option (default: `true`). Raises `ArgumentError` if merging a `MultiRBTree` (incompatible value structures).
14
+ - `MultiRBTree#merge!`: Always appends values from the source.
15
+
8
16
  ## [0.3.0] - 2026-01-15
9
17
 
10
- ### Changed
11
18
  ### API Changes (Method Renaming & Deprecation)
12
19
  > [!WARNING]
13
20
  > The public API has been refactored to improve consistency. The following methods have been renamed.
data/README.ja.md CHANGED
@@ -174,6 +174,25 @@ tree.lt(3).first # => [1, "one"] (遅延評価、配列は作
174
174
  tree.gt(0).lazy.take(2).to_a # => [[1, "one"], [2, "two"]] (最初の2件のみ計算)
175
175
  ```
176
176
 
177
+ ### 変換と結合
178
+
179
+ 標準のRubyオブジェクトへの変換や、他のコレクションとの結合も簡単です:
180
+
181
+ ```ruby
182
+ tree = RBTree.new({1 => 'one', 2 => 'two'})
183
+
184
+ # 配列への変換(Enumerable経由)
185
+ tree.to_a # => [[1, "one"], [2, "two"]]
186
+
187
+ # ハッシュへの変換
188
+ tree.to_h # => {1 => "one", 2 => "two"}
189
+
190
+ # 他のツリー、ハッシュ、またはEnumerableの結合
191
+ other = {3 => 'three'}
192
+ tree.merge!(other)
193
+ tree.size # => 3
194
+ ```
195
+
177
196
  ### MultiRBTree 値配列アクセス
178
197
 
179
198
  複数の値を持つキーで、どの値にアクセスするか選択:
data/README.md CHANGED
@@ -174,6 +174,25 @@ tree.lt(3).first # => [1, "one"] (lazy, no array created)
174
174
  tree.gt(0).lazy.take(2).to_a # => [[1, "one"], [2, "two"]] (only computes first 2)
175
175
  ```
176
176
 
177
+ ### Conversion and Merging
178
+
179
+ Seamlessly convert to standard Ruby objects or merge other collections:
180
+
181
+ ```ruby
182
+ tree = RBTree.new({1 => 'one', 2 => 'two'})
183
+
184
+ # Convert to Array (via Enumerable)
185
+ tree.to_a # => [[1, "one"], [2, "two"]]
186
+
187
+ # Convert to Hash
188
+ tree.to_h # => {1 => "one", 2 => "two"}
189
+
190
+ # Merge another tree, hash, or enumerable
191
+ other = {3 => 'three'}
192
+ tree.merge!(other)
193
+ tree.size # => 3
194
+ ```
195
+
177
196
  ### MultiRBTree Value Array Access
178
197
 
179
198
  For keys with multiple values, choose which value to access:
@@ -2,5 +2,5 @@
2
2
 
3
3
  class RBTree
4
4
  # The version of the rbtree-ruby gem
5
- VERSION = "0.3.0"
5
+ VERSION = "0.3.1"
6
6
  end
data/lib/rbtree.rb CHANGED
@@ -107,6 +107,11 @@ class RBTree
107
107
  end
108
108
  end
109
109
 
110
+ # Returns a Hash containing all key-value pairs from the tree.
111
+ #
112
+ # @return [Hash] a new Hash with the tree's contents
113
+ def to_h = @hash_index.transform_values(&:value)
114
+
110
115
  # Checks if the tree is empty.
111
116
  #
112
117
  # @return [Boolean] true if the tree contains no elements, false otherwise
@@ -335,6 +340,19 @@ class RBTree
335
340
  end
336
341
  end
337
342
  alias :[]= :insert
343
+
344
+ # Merges the contents of another tree, hash, or enumerable into this tree.
345
+ #
346
+ # @param other [RBTree, Hash, Enumerable] the source to merge from
347
+ # @param overwrite [Boolean] whether to overwrite existing keys (default: true)
348
+ # @return [RBTree] self
349
+ def merge!(other, overwrite: true)
350
+ if defined?(MultiRBTree) && other.is_a?(MultiRBTree)
351
+ raise ArgumentError, "Cannot merge MultiRBTree into RBTree"
352
+ end
353
+ insert(other, overwrite: overwrite)
354
+ self
355
+ end
338
356
 
339
357
  # Deletes the key-value pair with the specified key.
340
358
  #
@@ -1548,61 +1566,15 @@ class MultiRBTree < RBTree
1548
1566
  # tree.succ(4) # => [5, "five"]
1549
1567
  def succ(key, last: false) = (pair = super(key)) && [pair[0], pair[1].send(last ? :last : :first)]
1550
1568
 
1551
- # Inserts a value for the given key.
1569
+ # Merges the contents of another tree, hash, or enumerable into this tree.
1552
1570
  #
1553
- # If the key already exists, the value is appended to its list.
1554
- # If the key doesn't exist, a new node is created.
1571
+ # Appends values from the other source to the existing values for each key.
1555
1572
  #
1556
- # @param key [Object] the key (must implement <=>)
1557
- # @param value [Object] the value to insert
1558
- # @param overwrite [Boolean] ignored for MultiRBTree which always appends
1559
- # @return [Boolean] always returns true
1560
- # @example
1561
- # tree = MultiRBTree.new
1562
- # tree.insert(1, 'first')
1563
- # tree.insert(1, 'second') # adds another value for key 1
1564
- def insert_entry(key, value, **)
1565
- if (node = @hash_index[key])
1566
- node.value << value
1567
- @value_count += 1
1568
- return true
1569
- end
1570
- y = @nil_node
1571
- x = @root
1572
- while x != @nil_node
1573
- y = x
1574
- cmp = key <=> x.key
1575
- if cmp == 0
1576
- x.value << value
1577
- @value_count += 1
1578
- return true
1579
- elsif cmp < 0
1580
- x = x.left
1581
- else
1582
- x = x.right
1583
- end
1584
- end
1585
- z = allocate_node(key, [value], Node::RED, @nil_node, @nil_node, @nil_node)
1586
- z.parent = y
1587
- if y == @nil_node
1588
- @root = z
1589
- elsif (key <=> y.key) < 0
1590
- y.left = z
1591
- else
1592
- y.right = z
1593
- end
1594
- z.left = @nil_node
1595
- z.right = @nil_node
1596
- z.color = Node::RED
1597
- insert_fixup(z)
1598
- @value_count += 1
1599
-
1600
- if @min_node == @nil_node || (key <=> @min_node.key) < 0
1601
- @min_node = z
1602
- end
1603
-
1604
- @hash_index[key] = z # Add to hash index
1605
- true
1573
+ # @param other [RBTree, Hash, Enumerable] the source to merge from
1574
+ # @return [MultiRBTree] self
1575
+ def merge!(other)
1576
+ insert(other)
1577
+ self
1606
1578
  end
1607
1579
 
1608
1580
  # Deletes a single value for the specified key.
@@ -1692,6 +1664,63 @@ class MultiRBTree < RBTree
1692
1664
  # @!visibility private
1693
1665
  private
1694
1666
 
1667
+ # Inserts a value for the given key.
1668
+ #
1669
+ # If the key already exists, the value is appended to its list.
1670
+ # If the key doesn't exist, a new node is created.
1671
+ #
1672
+ # @param key [Object] the key (must implement <=>)
1673
+ # @param value [Object] the value to insert
1674
+ # @param overwrite [Boolean] ignored for MultiRBTree which always appends
1675
+ # @return [Boolean] always returns true
1676
+ # @example
1677
+ # tree = MultiRBTree.new
1678
+ # tree.insert(1, 'first')
1679
+ # tree.insert(1, 'second') # adds another value for key 1
1680
+ def insert_entry(key, value, **)
1681
+ if (node = @hash_index[key])
1682
+ node.value << value
1683
+ @value_count += 1
1684
+ return true
1685
+ end
1686
+ y = @nil_node
1687
+ x = @root
1688
+ while x != @nil_node
1689
+ y = x
1690
+ cmp = key <=> x.key
1691
+ if cmp == 0
1692
+ x.value << value
1693
+ @value_count += 1
1694
+ return true
1695
+ elsif cmp < 0
1696
+ x = x.left
1697
+ else
1698
+ x = x.right
1699
+ end
1700
+ end
1701
+ z = allocate_node(key, [value], Node::RED, @nil_node, @nil_node, @nil_node)
1702
+ z.parent = y
1703
+ if y == @nil_node
1704
+ @root = z
1705
+ elsif (key <=> y.key) < 0
1706
+ y.left = z
1707
+ else
1708
+ y.right = z
1709
+ end
1710
+ z.left = @nil_node
1711
+ z.right = @nil_node
1712
+ z.color = Node::RED
1713
+ insert_fixup(z)
1714
+ @value_count += 1
1715
+
1716
+ if @min_node == @nil_node || (key <=> @min_node.key) < 0
1717
+ @min_node = z
1718
+ end
1719
+
1720
+ @hash_index[key] = z # Add to hash index
1721
+ true
1722
+ end
1723
+
1695
1724
  # Traverses the tree in ascending order, yielding each key-value pair.
1696
1725
  #
1697
1726
  # @param range [Range] the range of keys to traverse
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.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masahito Suzuki
@@ -25,7 +25,6 @@ files:
25
25
  - README.ja.md
26
26
  - README.md
27
27
  - Rakefile
28
- - lib/rbtree.old.rb
29
28
  - lib/rbtree.rb
30
29
  - lib/rbtree/version.rb
31
30
  - rbtree-ruby.gemspec