6
6
// Copyright © 2016 Károly Lőrentey.
7
7
//
8
8
9
- public enum BTreeMergeStrategy {
9
+ public enum BTreeMatchStrategy {
10
10
case groupingMatches
11
11
case countingMatches
12
12
}
@@ -40,7 +40,7 @@ extension BTree {
40
40
/// - Complexity:
41
41
/// - O(min(`self.count`, `other.count`)) in general.
42
42
/// - O(log(`self.count` + `other.count`)) if there are only a constant amount of interleaving element runs.
43
- public func union( _ other: BTree , by strategy: BTreeMergeStrategy ) -> BTree {
43
+ public func union( _ other: BTree , by strategy: BTreeMatchStrategy ) -> BTree {
44
44
var m = BTreeMerger ( first: self , second: other)
45
45
switch strategy {
46
46
case . groupingMatches:
@@ -84,7 +84,7 @@ extension BTree {
84
84
/// - Complexity:
85
85
/// - O(min(`self.count`, `tree.count`)) in general.
86
86
/// - O(log(`self.count` + `tree.count`)) if there are only a constant amount of interleaving element runs.
87
- public func subtracting( _ other: BTree , by strategy: BTreeMergeStrategy ) -> BTree {
87
+ public func subtracting( _ other: BTree , by strategy: BTreeMatchStrategy ) -> BTree {
88
88
var m = BTreeMerger ( first: self , second: other)
89
89
while !m. done {
90
90
m. copyFromFirst ( . excludingOtherKey)
@@ -127,7 +127,7 @@ extension BTree {
127
127
/// - Complexity:
128
128
/// - O(min(`self.count`, `other.count`)) in general.
129
129
/// - O(log(`self.count` + `other.count`)) if there are only a constant amount of interleaving element runs.
130
- public func symmetricDifference( _ other: BTree , by strategy: BTreeMergeStrategy ) -> BTree {
130
+ public func symmetricDifference( _ other: BTree , by strategy: BTreeMatchStrategy ) -> BTree {
131
131
var m = BTreeMerger ( first: self , second: other)
132
132
while !m. done {
133
133
m. copyFromFirst ( . excludingOtherKey)
@@ -171,7 +171,7 @@ extension BTree {
171
171
/// - Complexity:
172
172
/// - O(min(`self.count`, `other.count`)) in general.
173
173
/// - O(log(`self.count` + `other.count`)) if there are only a constant amount of interleaving element runs.
174
- public func intersection( _ other: BTree , by strategy: BTreeMergeStrategy ) -> BTree {
174
+ public func intersection( _ other: BTree , by strategy: BTreeMatchStrategy ) -> BTree {
175
175
var m = BTreeMerger ( first: self , second: other)
176
176
while !m. done {
177
177
m. skipFromFirst ( . excludingOtherKey)
@@ -195,7 +195,7 @@ extension BTree {
195
195
///
196
196
/// - Requires: `sortedKeys` is sorted in ascending order.
197
197
/// - Complexity: O(*n* + `self.count`), where *n* is the number of keys in `sortedKeys`.
198
- public func subtracting< S: Sequence > ( sortedKeys: S , by strategy: BTreeMergeStrategy ) -> BTree where S. Iterator. Element == Key {
198
+ public func subtracting< S: Sequence > ( sortedKeys: S , by strategy: BTreeMatchStrategy ) -> BTree where S. Iterator. Element == Key {
199
199
if self . isEmpty { return self }
200
200
201
201
var b = BTreeBuilder < Key , Value > ( order: self . order)
@@ -237,7 +237,7 @@ extension BTree {
237
237
///
238
238
/// - Requires: `sortedKeys` is sorted in ascending order.
239
239
/// - Complexity: O(*n* + `self.count`), where *n* is the number of keys in `sortedKeys`.
240
- public func intersection< S: Sequence > ( sortedKeys: S , by strategy: BTreeMergeStrategy ) -> BTree where S. Iterator. Element == Key {
240
+ public func intersection< S: Sequence > ( sortedKeys: S , by strategy: BTreeMatchStrategy ) -> BTree where S. Iterator. Element == Key {
241
241
if self . isEmpty { return self }
242
242
243
243
var b = BTreeBuilder < Key , Value > ( order: self . order)
@@ -481,8 +481,9 @@ internal struct BTreeMerger<Key: Comparable, Value> {
481
481
var common : Node
482
482
repeat {
483
483
key = a. node. last!. 0
484
+ common = a. node
484
485
a. ascendOneLevel ( )
485
- common = b. ascendOneLevel ( )
486
+ b. ascendOneLevel ( )
486
487
} while !a. isAtEnd && !b. isAtEnd && a. node === b. node && a. slot == 0 && b. slot == 0
487
488
builder. append ( common)
488
489
if !a. isAtEnd {
@@ -518,8 +519,9 @@ internal struct BTreeMerger<Key: Comparable, Value> {
518
519
/// the shared subtree. The slot & leaf checks above & below ensure that this isn't the case.
519
520
var common : Node
520
521
repeat {
522
+ common = a. node
521
523
a. ascendOneLevel ( )
522
- common = b. ascendOneLevel ( )
524
+ b. ascendOneLevel ( )
523
525
} while !a. isAtEnd && !b. isAtEnd && a. node === b. node && a. slot == 0 && b. slot == 0
524
526
builder. append ( common)
525
527
if !a. isAtEnd { a. ascendToKey ( ) }
@@ -589,7 +591,7 @@ internal struct BTreeMerger<Key: Comparable, Value> {
589
591
590
592
mutating func skipMatchingNumberOfCommonElements( ) {
591
593
while !done && a. key == b. key {
592
- if a. node === b. node && a. node. isLeaf && a. slot == 0 && b. slot == 0 {
594
+ if a. node === b. node && a. node. isLeaf && a. slot == b. slot {
593
595
/// We're at the first element of a shared subtree. Find the ancestor at which the shared subtree
594
596
/// starts, and append it in a single step.
595
597
///
@@ -602,7 +604,7 @@ internal struct BTreeMerger<Key: Comparable, Value> {
602
604
if a. isAtEnd || b. isAtEnd {
603
605
done = true
604
606
}
605
- } while !done && a. node === b. node && a. slot == 0 && b. slot == 0
607
+ } while !done && a. node === b. node && a. slot == b. slot
606
608
if !a. isAtEnd { a. ascendToKey ( ) }
607
609
if !b. isAtEnd { b. ascendToKey ( ) }
608
610
}
@@ -622,6 +624,25 @@ internal enum BTreePart<Key: Comparable, Value> {
622
624
case nodeRange( BTreeNode < Key , Value > , CountableRange < Int > )
623
625
}
624
626
627
+ extension BTreePart {
628
+ var count : Int {
629
+ switch self {
630
+ case . element( _, _) :
631
+ return 1
632
+ case . node( let node) :
633
+ return node. count
634
+ case . nodeRange( let parent, let range) :
635
+ var count = range. count
636
+ if !parent. isLeaf {
637
+ for i in range. lowerBound ... range. upperBound {
638
+ count += parent. children [ i] . count
639
+ }
640
+ }
641
+ return count
642
+ }
643
+ }
644
+ }
645
+
625
646
extension BTreeBuilder {
626
647
mutating func append( _ part: BTreePart < Key , Value > ) {
627
648
switch part {
@@ -668,16 +689,14 @@ internal extension BTreeStrongPath {
668
689
669
690
/// Remove the deepest path component, leaving the path at the element following the node that was previously focused,
670
691
/// or the spot after all elements if the node was the rightmost child.
671
- @discardableResult
672
- mutating func ascendOneLevel( ) -> Node {
692
+ mutating func ascendOneLevel( ) {
673
693
if length == 1 {
674
694
offset = count
675
695
slot = node. elements. count
676
- return node
696
+ return
677
697
}
678
698
popFromSlots ( )
679
699
popFromPath ( )
680
- return node. children [ slot!]
681
700
}
682
701
683
702
/// If this path got to a slot at the end of a node but it hasn't reached the end of the tree yet,
@@ -704,10 +723,9 @@ internal extension BTreeStrongPath {
704
723
assert ( !isAtEnd)
705
724
var includeLeftmostSubtree = false
706
725
if slot == 0 && node. isLeaf {
707
- while slot == 0 {
708
- guard let pk = parentKey else { break }
709
- guard limit. match ( pk) else { break }
710
- ascendOneLevel ( )
726
+ while slot == 0 , let pk = parentKey, limit. match ( pk) {
727
+ popFromSlots ( )
728
+ popFromPath ( )
711
729
includeLeftmostSubtree = true
712
730
}
713
731
}
0 commit comments