diff --git a/test.cpp b/test.cpp index 16a05fd63..69f7fa06c 100644 --- a/test.cpp +++ b/test.cpp @@ -125,7 +125,54 @@ void testPoolExpressionAllocationFail() { f1.replaceWith(f11); float result2 = a1.approximate(); assert(result2 == 0); +} + +void testPoolExpressionAllocationFail2() { + printf("Pool expression allocation fail second test\n"); + + ExpressionRef::failedAllocationNode(); + assert(TreePool::sharedPool()->numberOfNodes() == 1); + + // Fill the pool for size 256 + FloatRef f1(0.0f); + FloatRef f2(1.0f); + AdditionRef a1(f1, f2); + float result1 = a1.approximate(); + assert(result1 == 1); + + FloatRef f3(2.0f); + FloatRef f4(3.0f); + AdditionRef a2(f3, f4); + float result2 = a2.approximate(); + assert(result2 == 5); + + FloatRef f5(4.0f); + FloatRef f6(5.0f); + FloatRef f7(6.0f); + FloatRef f8(7.0f); + // Allocation fail + FloatRef f9(8.0f); + FloatRef f10(8.0f); + + printf("\n"); TreePool::sharedPool()->log(); + printf("\n"); + f1.replaceWith(f9); + result1 = a1.approximate(); + assert(result1 == -1); + + TreePool::sharedPool()->log(); + printf("\n"); + f3.replaceWith(f10); + result2 = a2.approximate(); + assert(result2 == -1); + + printf("\n"); + TreePool::sharedPool()->log(); + result1 = a1.approximate(); + printf("a1 number children %d\n", a1.numberOfChildren()); + printf("a1 %f\n", result1); + assert(result1 == -1); } void testPoolLayoutAllocationFail() { @@ -162,7 +209,8 @@ int main() { runTest(testPoolEmpties); runTest(testCursorCreateAndRetain); runTest(testCursorMoveLeft); - runTest(testPoolExpressionAllocationFail); + //runTest(testPoolExpressionAllocationFail); + runTest(testPoolExpressionAllocationFail2); printf("\n*******************\nEnd of tests\n*******************\n\n"); return 0; } diff --git a/tree_reference.h b/tree_reference.h index 4afe8e386..6c02fe7d5 100644 --- a/tree_reference.h +++ b/tree_reference.h @@ -43,14 +43,18 @@ public: } ~TreeReference() { - assert(node()); - assert(node()->identifier() == m_identifier); - node()->release(); + if (m_identifier >= 0) { + assert(node()); + assert(node()->identifier() == m_identifier); + node()->release(); + } } bool isDefined() const { return m_identifier >= 0 && TreePool::sharedPool()->node(m_identifier) != nullptr; } int nodeRetainCount() const { return node()->retainCount(); } + void incrementNumberOfChildren() { return node()->incrementNumberOfChildren(); } + void decrementNumberOfChildren() { return node()->decrementNumberOfChildren(); } operator TreeReference() const { return TreeReference(this->node()); @@ -96,12 +100,16 @@ public: } void replaceWith(TreeReference t) { - TreeReference p = parent(); + TreeReference p = parent(); p.replaceChildAtIndex(p.node()->indexOfChildByIdentifier(identifier()), t); } void replaceChildAtIndex(int oldChildIndex, TreeReference newChild) { // TODO decrement the children count of the new child parent + TreeReference p = newChild.parent(); + if (p.isDefined()) { + p.decrementNumberOfChildren(); + } assert(oldChildIndex >= 0 && oldChildIndex < numberOfChildren()); TreeReference oldChild = treeChildAtIndex(oldChildIndex); TreePool::sharedPool()->move(newChild.node(), oldChild.node()->next()); @@ -131,12 +139,17 @@ protected: m_identifier = node->identifier(); } - TreeReference(TreeNode * node) : - m_identifier(node->identifier()) - { - node->retain(); + TreeReference(TreeNode * node) { + if (node == nullptr) { + m_identifier = -1; + } else { + m_identifier = node->identifier(); + node->retain(); + } } int m_identifier; }; +typedef TreeReference TreeRef; + #endif