From bc39bd9fe76431c535f7cafd311842838bb5fa7d Mon Sep 17 00:00:00 2001 From: "rjc%netscape.com" Date: Mon, 17 Jan 2000 13:15:44 +0000 Subject: [PATCH] More preparations to land an optimized binary insertion node. (Going to test more later. Currently #ifdef'ed out.) git-svn-id: svn://10.0.0.236/trunk@58014 18797224-902f-48f8-a5cc-f745e15eee43 --- .../xul/templates/src/nsXULSortService.cpp | 75 ++++++++++++++++--- .../templates/src/nsXULTemplateBuilder.cpp | 3 + .../rdf/content/src/nsRDFGenericBuilder.cpp | 3 + mozilla/rdf/content/src/nsXULSortService.cpp | 75 ++++++++++++++++--- .../rdf/content/src/nsXULTemplateBuilder.cpp | 3 + 5 files changed, 139 insertions(+), 20 deletions(-) diff --git a/mozilla/content/xul/templates/src/nsXULSortService.cpp b/mozilla/content/xul/templates/src/nsXULSortService.cpp index 296d05264af..0f5643f4290 100644 --- a/mozilla/content/xul/templates/src/nsXULSortService.cpp +++ b/mozilla/content/xul/templates/src/nsXULSortService.cpp @@ -1415,12 +1415,17 @@ XULSortServiceImpl::SortTreeChildren(nsIContent *container, sortPtr sortInfo) typedef class sortState { public: + // state match strings nsAutoString sortResource, sortResource2; + // state variables nsCOMPtr mCache; nsCOMPtr sortProperty, sortProperty2; nsCOMPtr sortPropertyColl, sortPropertyColl2; nsCOMPtr sortPropertySort, sortPropertySort2; + + nsCOMPtr lastContainer; + PRBool lastWasFirst, lastWasLast; } sortStateClass; @@ -1445,6 +1450,7 @@ XULSortServiceImpl::InsertContainerNode(nsIRDFCompositeDataSource *db, sortState sortInfo.sortProperty2 = nsnull; sortInfo.inbetweenSeparatorSort = PR_FALSE; sortInfo.cacheFirstHint = PR_TRUE; + sortInfo.cacheFirstNode = nsnull; sortInfo.cacheIsFirstNodeCollationKey = PR_FALSE; if (sortState->mCache) @@ -1456,6 +1462,13 @@ XULSortServiceImpl::InsertContainerNode(nsIRDFCompositeDataSource *db, sortState sortInfo.mInner = nsnull; } + if (container != sortState->lastContainer.get()) + { + sortState->lastContainer = container; + sortState->lastWasFirst = PR_FALSE; + sortState->lastWasLast = PR_FALSE; + } + PRBool sortInfoAvailable = PR_FALSE; if (IsTreeElement(root) == PR_TRUE) @@ -1622,30 +1635,71 @@ XULSortServiceImpl::InsertContainerNode(nsIRDFCompositeDataSource *db, sortState (isContainerRDFSeq == PR_TRUE))) { // figure out where to insert the node when a sort order is being imposed - // using a smart binary comparison PRInt32 numChildren = 0; if (NS_FAILED(rv = container->ChildCount(numChildren))) return(rv); if (numChildren > 0) { nsCOMPtr child; + nsIContent *temp; // #define OPTIMIZED_BINARY_INSERTION #ifdef OPTIMIZED_BINARY_INSERTION - PRInt32 direction = 0, left = 1, right = numChildren, x; - while (right >= 1) + // rjc says: The following is an implementaion of a fairly optimal + // binary search insertion sort... with interpolation at either end-point. + PRInt32 direction; + + if (sortState->lastWasFirst == PR_TRUE) + { + container->ChildAt(0, *getter_AddRefs(child)); + temp = child.get(); + direction = inplaceSortCallback(&node, &temp, &sortInfo); + if (direction < 0) + { + container->InsertChildAt(node, 0, aNotify); + childAdded = PR_TRUE; + } + else + { + sortState->lastWasFirst = PR_FALSE; + } + } + else if (sortState->lastWasLast == PR_TRUE) + { + container->ChildAt(numChildren-1, *getter_AddRefs(child)); + temp = child.get(); + direction = inplaceSortCallback(&node, &temp, &sortInfo); + if (direction > 0) + { + container->AppendChildTo(node, aNotify); + childAdded = PR_TRUE; + } + else + { + sortState->lastWasLast = PR_FALSE; + } + } + + PRInt32 left = 1, right = numChildren, x; + while ((childAdded == PR_FALSE) && (right >= 1)) { - x = (1 + right) / 2; + x = (left + right) / 2; container->ChildAt(x-1, *getter_AddRefs(child)); - nsIContent *theChild = child.get(); - // Note: since cacheFirstHint is PR_TRUE, the first node passed + temp = child.get(); + + // rjc says: since cacheFirstHint is PR_TRUE, the first node passed // into inplaceSortCallback() must be the node that doesn't change - direction = inplaceSortCallback(&node, &theChild, &sortInfo); - if (right - left <= 1 ) + + direction = inplaceSortCallback(&node, &temp, &sortInfo); + if (((x == left) && (direction < 0)) || (((x == right)) && (direction > 0)) || (left == right)) { PRInt32 thePos = ((direction > 0) ? x : x-1); container->InsertChildAt(node, thePos, aNotify); childAdded = PR_TRUE; + + sortState->lastWasFirst = (thePos == 0) ? PR_TRUE: PR_FALSE; + sortState->lastWasLast = (thePos >= numChildren) ? PR_TRUE: PR_FALSE; + break; } if (direction < 0) right = x-1; @@ -1677,10 +1731,10 @@ XULSortServiceImpl::InsertContainerNode(nsIRDFCompositeDataSource *db, sortState if (current != last) { container->ChildAt(current, *getter_AddRefs(child)); - nsIContent *theChild = child.get(); + temp = child.get(); // Note: since cacheFirstHint is PR_TRUE, the first node passed // into inplaceSortCallback() must be the node that doesn't change - direction = inplaceSortCallback(&node, &theChild, &sortInfo); + direction = inplaceSortCallback(&node, &temp, &sortInfo); } if ( (direction == 0) || ((current == last + 1) && (direction < 0)) || @@ -1756,6 +1810,7 @@ XULSortServiceImpl::DoSort(nsIDOMNode* node, const nsString& sortResource, sortInfo.parentContainer = treeNode; sortInfo.inbetweenSeparatorSort = PR_FALSE; sortInfo.cacheFirstHint = PR_FALSE; + sortInfo.cacheFirstNode = nsnull; sortInfo.cacheIsFirstNodeCollationKey = PR_FALSE; // remove any sort hints on tree root node diff --git a/mozilla/content/xul/templates/src/nsXULTemplateBuilder.cpp b/mozilla/content/xul/templates/src/nsXULTemplateBuilder.cpp index 3a895954fd0..612c4b60d33 100644 --- a/mozilla/content/xul/templates/src/nsXULTemplateBuilder.cpp +++ b/mozilla/content/xul/templates/src/nsXULTemplateBuilder.cpp @@ -132,6 +132,9 @@ public: nsCOMPtr sortProperty, sortProperty2; nsCOMPtr sortPropertyColl, sortPropertyColl2; nsCOMPtr sortPropertySort, sortPropertySort2; + + nsCOMPtr lastContainer; + PRBool lastWasFirst, lastWasLast; } sortStateClass; class RDFGenericBuilderImpl : public nsIRDFContentModelBuilder, diff --git a/mozilla/rdf/content/src/nsRDFGenericBuilder.cpp b/mozilla/rdf/content/src/nsRDFGenericBuilder.cpp index 3a895954fd0..612c4b60d33 100644 --- a/mozilla/rdf/content/src/nsRDFGenericBuilder.cpp +++ b/mozilla/rdf/content/src/nsRDFGenericBuilder.cpp @@ -132,6 +132,9 @@ public: nsCOMPtr sortProperty, sortProperty2; nsCOMPtr sortPropertyColl, sortPropertyColl2; nsCOMPtr sortPropertySort, sortPropertySort2; + + nsCOMPtr lastContainer; + PRBool lastWasFirst, lastWasLast; } sortStateClass; class RDFGenericBuilderImpl : public nsIRDFContentModelBuilder, diff --git a/mozilla/rdf/content/src/nsXULSortService.cpp b/mozilla/rdf/content/src/nsXULSortService.cpp index 296d05264af..0f5643f4290 100644 --- a/mozilla/rdf/content/src/nsXULSortService.cpp +++ b/mozilla/rdf/content/src/nsXULSortService.cpp @@ -1415,12 +1415,17 @@ XULSortServiceImpl::SortTreeChildren(nsIContent *container, sortPtr sortInfo) typedef class sortState { public: + // state match strings nsAutoString sortResource, sortResource2; + // state variables nsCOMPtr mCache; nsCOMPtr sortProperty, sortProperty2; nsCOMPtr sortPropertyColl, sortPropertyColl2; nsCOMPtr sortPropertySort, sortPropertySort2; + + nsCOMPtr lastContainer; + PRBool lastWasFirst, lastWasLast; } sortStateClass; @@ -1445,6 +1450,7 @@ XULSortServiceImpl::InsertContainerNode(nsIRDFCompositeDataSource *db, sortState sortInfo.sortProperty2 = nsnull; sortInfo.inbetweenSeparatorSort = PR_FALSE; sortInfo.cacheFirstHint = PR_TRUE; + sortInfo.cacheFirstNode = nsnull; sortInfo.cacheIsFirstNodeCollationKey = PR_FALSE; if (sortState->mCache) @@ -1456,6 +1462,13 @@ XULSortServiceImpl::InsertContainerNode(nsIRDFCompositeDataSource *db, sortState sortInfo.mInner = nsnull; } + if (container != sortState->lastContainer.get()) + { + sortState->lastContainer = container; + sortState->lastWasFirst = PR_FALSE; + sortState->lastWasLast = PR_FALSE; + } + PRBool sortInfoAvailable = PR_FALSE; if (IsTreeElement(root) == PR_TRUE) @@ -1622,30 +1635,71 @@ XULSortServiceImpl::InsertContainerNode(nsIRDFCompositeDataSource *db, sortState (isContainerRDFSeq == PR_TRUE))) { // figure out where to insert the node when a sort order is being imposed - // using a smart binary comparison PRInt32 numChildren = 0; if (NS_FAILED(rv = container->ChildCount(numChildren))) return(rv); if (numChildren > 0) { nsCOMPtr child; + nsIContent *temp; // #define OPTIMIZED_BINARY_INSERTION #ifdef OPTIMIZED_BINARY_INSERTION - PRInt32 direction = 0, left = 1, right = numChildren, x; - while (right >= 1) + // rjc says: The following is an implementaion of a fairly optimal + // binary search insertion sort... with interpolation at either end-point. + PRInt32 direction; + + if (sortState->lastWasFirst == PR_TRUE) + { + container->ChildAt(0, *getter_AddRefs(child)); + temp = child.get(); + direction = inplaceSortCallback(&node, &temp, &sortInfo); + if (direction < 0) + { + container->InsertChildAt(node, 0, aNotify); + childAdded = PR_TRUE; + } + else + { + sortState->lastWasFirst = PR_FALSE; + } + } + else if (sortState->lastWasLast == PR_TRUE) + { + container->ChildAt(numChildren-1, *getter_AddRefs(child)); + temp = child.get(); + direction = inplaceSortCallback(&node, &temp, &sortInfo); + if (direction > 0) + { + container->AppendChildTo(node, aNotify); + childAdded = PR_TRUE; + } + else + { + sortState->lastWasLast = PR_FALSE; + } + } + + PRInt32 left = 1, right = numChildren, x; + while ((childAdded == PR_FALSE) && (right >= 1)) { - x = (1 + right) / 2; + x = (left + right) / 2; container->ChildAt(x-1, *getter_AddRefs(child)); - nsIContent *theChild = child.get(); - // Note: since cacheFirstHint is PR_TRUE, the first node passed + temp = child.get(); + + // rjc says: since cacheFirstHint is PR_TRUE, the first node passed // into inplaceSortCallback() must be the node that doesn't change - direction = inplaceSortCallback(&node, &theChild, &sortInfo); - if (right - left <= 1 ) + + direction = inplaceSortCallback(&node, &temp, &sortInfo); + if (((x == left) && (direction < 0)) || (((x == right)) && (direction > 0)) || (left == right)) { PRInt32 thePos = ((direction > 0) ? x : x-1); container->InsertChildAt(node, thePos, aNotify); childAdded = PR_TRUE; + + sortState->lastWasFirst = (thePos == 0) ? PR_TRUE: PR_FALSE; + sortState->lastWasLast = (thePos >= numChildren) ? PR_TRUE: PR_FALSE; + break; } if (direction < 0) right = x-1; @@ -1677,10 +1731,10 @@ XULSortServiceImpl::InsertContainerNode(nsIRDFCompositeDataSource *db, sortState if (current != last) { container->ChildAt(current, *getter_AddRefs(child)); - nsIContent *theChild = child.get(); + temp = child.get(); // Note: since cacheFirstHint is PR_TRUE, the first node passed // into inplaceSortCallback() must be the node that doesn't change - direction = inplaceSortCallback(&node, &theChild, &sortInfo); + direction = inplaceSortCallback(&node, &temp, &sortInfo); } if ( (direction == 0) || ((current == last + 1) && (direction < 0)) || @@ -1756,6 +1810,7 @@ XULSortServiceImpl::DoSort(nsIDOMNode* node, const nsString& sortResource, sortInfo.parentContainer = treeNode; sortInfo.inbetweenSeparatorSort = PR_FALSE; sortInfo.cacheFirstHint = PR_FALSE; + sortInfo.cacheFirstNode = nsnull; sortInfo.cacheIsFirstNodeCollationKey = PR_FALSE; // remove any sort hints on tree root node diff --git a/mozilla/rdf/content/src/nsXULTemplateBuilder.cpp b/mozilla/rdf/content/src/nsXULTemplateBuilder.cpp index 3a895954fd0..612c4b60d33 100644 --- a/mozilla/rdf/content/src/nsXULTemplateBuilder.cpp +++ b/mozilla/rdf/content/src/nsXULTemplateBuilder.cpp @@ -132,6 +132,9 @@ public: nsCOMPtr sortProperty, sortProperty2; nsCOMPtr sortPropertyColl, sortPropertyColl2; nsCOMPtr sortPropertySort, sortPropertySort2; + + nsCOMPtr lastContainer; + PRBool lastWasFirst, lastWasLast; } sortStateClass; class RDFGenericBuilderImpl : public nsIRDFContentModelBuilder,