killbill-memoizeit

invoice: fix pruneTree implementation Complete sub-trees

2/16/2015 8:30:27 PM

Details

diff --git a/invoice/src/main/java/org/killbill/billing/invoice/tree/ItemsInterval.java b/invoice/src/main/java/org/killbill/billing/invoice/tree/ItemsInterval.java
index 07b571c..8047cd5 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/tree/ItemsInterval.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/tree/ItemsInterval.java
@@ -165,7 +165,7 @@ public class ItemsInterval {
         // - Nothing at all; this valid, this just means its original items got removed during mergeCancellingPairs logic,
         //   but its NodeInterval has children so it could not be deleted.
         //
-        Preconditions.checkState(items.size() <= 2);
+        Preconditions.checkState(items.size() <= 2, "Double billing detected: %s", items);
 
         final Item item = items.size() > 0 && items.get(0).getAction() == ItemAction.ADD ? items.get(0) : null;
         return item;
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/tree/NodeInterval.java b/invoice/src/main/java/org/killbill/billing/invoice/tree/NodeInterval.java
index 884e31d..e0e6db3 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/tree/NodeInterval.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/tree/NodeInterval.java
@@ -150,22 +150,40 @@ public class NodeInterval {
     }
 
     public void removeChild(final NodeInterval toBeRemoved) {
-
         NodeInterval prevChild = null;
         NodeInterval curChild = leftChild;
         while (curChild != null) {
             if (curChild.isSame(toBeRemoved)) {
                 if (prevChild == null) {
-                    leftChild = curChild.getRightSibling();
+                    if (curChild.getLeftChild() == null) {
+                        leftChild = curChild.getRightSibling();
+                    } else {
+                        leftChild = curChild.getLeftChild();
+                        adjustRightMostSibling(curChild);
+                    }
                 } else {
-                    prevChild.rightSibling = curChild.getRightSibling();
+                    if (curChild.getLeftChild() == null) {
+                        prevChild.rightSibling = curChild.getRightSibling();
+                    } else {
+                        prevChild.rightSibling = curChild.getLeftChild();
+                        adjustRightMostSibling(curChild);
+                    }
                 }
                 break;
             }
             prevChild = curChild;
             curChild = curChild.getRightSibling();
         }
+    }
 
+    private void adjustRightMostSibling(final NodeInterval curChild) {
+        NodeInterval tmpChild = curChild.getLeftChild();
+        NodeInterval preTmpChild = null;
+        while (tmpChild != null) {
+            preTmpChild = tmpChild;
+            tmpChild = tmpChild.getRightSibling();
+        }
+        preTmpChild.rightSibling = curChild.getRightSibling();
     }
 
     @JsonIgnore