11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/* 21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2011 The Guava Authors 31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * in compliance with the License. You may obtain a copy of the License at 61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0 81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unless required by applicable law or agreed to in writing, software distributed under the 101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * express or implied. See the License for the specific language governing permissions and 121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * limitations under the License. 131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.collect; 161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkNotNull; 181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.collect.BstOperations.extractMax; 191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.collect.BstOperations.extractMin; 201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.collect.BstOperations.insertMax; 211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.collect.BstOperations.insertMin; 221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.collect.BstSide.LEFT; 231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.collect.BstSide.RIGHT; 241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtCompatible; 261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport javax.annotation.Nullable; 281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/** 301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * A tree-size-based set of balancing policies, based on <a 311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * href="http://www.swiss.ai.mit.edu/~adams/BB/"> Stephen Adams, "Efficient sets: a balancing 321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * act."</a>. 331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Louis Wasserman 351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@GwtCompatible 371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertfinal class BstCountBasedBalancePolicies { 381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private BstCountBasedBalancePolicies() {} 391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final int SINGLE_ROTATE_RATIO = 4; 411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final int SECOND_ROTATE_RATIO = 2; 421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a balance policy that does no balancing or the bare minimum (for {@code combine}). 451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <N extends BstNode<?, N>> BstBalancePolicy<N> noRebalancePolicy( 471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final BstAggregate<N> countAggregate) { 481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(countAggregate); 491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new BstBalancePolicy<N>() { 501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public N balance( 521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert BstNodeFactory<N> nodeFactory, N source, @Nullable N left, @Nullable N right) { 531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return checkNotNull(nodeFactory).createNode(source, left, right); 541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Nullable 571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public N combine(BstNodeFactory<N> nodeFactory, @Nullable N left, @Nullable N right) { 591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (left == null) { 601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return right; 611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else if (right == null) { 621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return left; 631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else if (countAggregate.treeValue(left) > countAggregate.treeValue(right)) { 641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return nodeFactory.createNode( 651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert left, left.childOrNull(LEFT), combine(nodeFactory, left.childOrNull(RIGHT), right)); 661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else { 671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return nodeFactory.createNode(right, combine(nodeFactory, left, right.childOrNull(LEFT)), 681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert right.childOrNull(RIGHT)); 691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a balance policy that expects the sizes of each side to be at most one node (added or 761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * removed) away from being balanced. {@code balance} takes {@code O(1)} time, and {@code 771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * combine} takes {@code O(log n)} time. 781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, N extends BstNode<K, N>> BstBalancePolicy<N> singleRebalancePolicy( 801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final BstAggregate<N> countAggregate) { 811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(countAggregate); 821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new BstBalancePolicy<N>() { 831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public N balance( 851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert BstNodeFactory<N> nodeFactory, N source, @Nullable N left, @Nullable N right) { 861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert long countL = countAggregate.treeValue(left); 871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert long countR = countAggregate.treeValue(right); 881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (countL + countR > 1) { 891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (countR >= SINGLE_ROTATE_RATIO * countL) { 901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return rotateL(nodeFactory, source, left, right); 911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else if (countL >= SINGLE_ROTATE_RATIO * countR) { 921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return rotateR(nodeFactory, source, left, right); 931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return nodeFactory.createNode(source, left, right); 961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private N rotateL(BstNodeFactory<N> nodeFactory, N source, @Nullable N left, N right) { 991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(right); 1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert N rl = right.childOrNull(LEFT); 1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert N rr = right.childOrNull(RIGHT); 1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (countAggregate.treeValue(rl) >= SECOND_ROTATE_RATIO * countAggregate.treeValue(rr)) { 1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert right = singleR(nodeFactory, right, rl, rr); 1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return singleL(nodeFactory, source, left, right); 1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private N rotateR(BstNodeFactory<N> nodeFactory, N source, N left, @Nullable N right) { 1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(left); 1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert N lr = left.childOrNull(RIGHT); 1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert N ll = left.childOrNull(LEFT); 1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (countAggregate.treeValue(lr) >= SECOND_ROTATE_RATIO * countAggregate.treeValue(ll)) { 1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert left = singleL(nodeFactory, left, ll, lr); 1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return singleR(nodeFactory, source, left, right); 1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private N singleL(BstNodeFactory<N> nodeFactory, N source, @Nullable N left, N right) { 1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(right); 1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return nodeFactory.createNode(right, 1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert nodeFactory.createNode(source, left, right.childOrNull(LEFT)), 1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert right.childOrNull(RIGHT)); 1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private N singleR(BstNodeFactory<N> nodeFactory, N source, N left, @Nullable N right) { 1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(left); 1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return nodeFactory.createNode(left, left.childOrNull(LEFT), 1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert nodeFactory.createNode(source, left.childOrNull(RIGHT), right)); 1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Nullable 1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public N combine(BstNodeFactory<N> nodeFactory, @Nullable N left, @Nullable N right) { 1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (left == null) { 1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return right; 1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else if (right == null) { 1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return left; 1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert N newRootSource; 1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (countAggregate.treeValue(left) > countAggregate.treeValue(right)) { 1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert BstMutationResult<K, N> extractLeftMax = extractMax(left, nodeFactory, this); 1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert newRootSource = extractLeftMax.getOriginalTarget(); 1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert left = extractLeftMax.getChangedRoot(); 1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else { 1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert BstMutationResult<K, N> extractRightMin = extractMin(right, nodeFactory, this); 1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert newRootSource = extractRightMin.getOriginalTarget(); 1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert right = extractRightMin.getChangedRoot(); 1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return nodeFactory.createNode(newRootSource, left, right); 1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a balance policy that makes no assumptions on the relative balance of the two sides 1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * and performs a full rebalancing as necessary. Both {@code balance} and {@code combine} take 1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code O(log n)} time. 1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, N extends BstNode<K, N>> BstBalancePolicy<N> fullRebalancePolicy( 1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final BstAggregate<N> countAggregate) { 1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(countAggregate); 1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final BstBalancePolicy<N> singleBalancePolicy = 1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert BstCountBasedBalancePolicies.<K, N>singleRebalancePolicy(countAggregate); 1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new BstBalancePolicy<N>() { 1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public N balance( 1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert BstNodeFactory<N> nodeFactory, N source, @Nullable N left, @Nullable N right) { 1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (left == null) { 1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return insertMin(right, source, nodeFactory, singleBalancePolicy); 1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else if (right == null) { 1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return insertMax(left, source, nodeFactory, singleBalancePolicy); 1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert long countL = countAggregate.treeValue(left); 1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert long countR = countAggregate.treeValue(right); 1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (SINGLE_ROTATE_RATIO * countL <= countR) { 1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert N resultLeft = balance(nodeFactory, source, left, right.childOrNull(LEFT)); 1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return singleBalancePolicy.balance( 1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert nodeFactory, right, resultLeft, right.childOrNull(RIGHT)); 1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else if (SINGLE_ROTATE_RATIO * countR <= countL) { 1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert N resultRight = balance(nodeFactory, source, left.childOrNull(RIGHT), right); 1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return singleBalancePolicy.balance( 1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert nodeFactory, left, left.childOrNull(LEFT), resultRight); 1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else { 1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return nodeFactory.createNode(source, left, right); 1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Nullable 1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public N combine(BstNodeFactory<N> nodeFactory, @Nullable N left, @Nullable N right) { 1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (left == null) { 1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return right; 1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else if (right == null) { 1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return left; 1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert long countL = countAggregate.treeValue(left); 1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert long countR = countAggregate.treeValue(right); 1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (SINGLE_ROTATE_RATIO * countL <= countR) { 1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert N resultLeft = combine(nodeFactory, left, right.childOrNull(LEFT)); 2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return singleBalancePolicy.balance( 2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert nodeFactory, right, resultLeft, right.childOrNull(RIGHT)); 2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else if (SINGLE_ROTATE_RATIO * countR <= countL) { 2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert N resultRight = combine(nodeFactory, left.childOrNull(RIGHT), right); 2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return singleBalancePolicy.balance( 2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert nodeFactory, left, left.childOrNull(LEFT), resultRight); 2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else { 2071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return singleBalancePolicy.combine(nodeFactory, left, right); 2081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 2111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert} 213