void nsGenConList::Insert(nsGenConNode* aNode) { if (mFirstNode) { // Check for append. if (NodeAfter(aNode, Prev(mFirstNode))) { PR_INSERT_BEFORE(aNode, mFirstNode); } else { // Binary search. // the range of indices at which |aNode| could end up. // (We already know it can't be at index mSize.) PRUint32 first = 0, last = mSize - 1; // A cursor to avoid walking more than the length of the list. nsGenConNode *curNode = Prev(mFirstNode); PRUint32 curIndex = mSize - 1; while (first != last) { PRUint32 test = (first + last) / 2; if (last == curIndex) { for ( ; curIndex != test; --curIndex) curNode = Prev(curNode); } else { for ( ; curIndex != test; ++curIndex) curNode = Next(curNode); } if (NodeAfter(aNode, curNode)) { first = test + 1; // if we exit the loop, we need curNode to be right ++curIndex; curNode = Next(curNode); } else { last = test; } } PR_INSERT_BEFORE(aNode, curNode); if (curNode == mFirstNode) { mFirstNode = aNode; } } } else { // initialize list with first node PR_INIT_CLIST(aNode); mFirstNode = aNode; } ++mSize; NS_ASSERTION(aNode == mFirstNode || NodeAfter(aNode, Prev(aNode)), "sorting error"); NS_ASSERTION(IsLast(aNode) || NodeAfter(Next(aNode), aNode), "sorting error"); }
void nsGenConList::Insert(nsGenConNode* aNode) { // Check for append. if (mList.isEmpty() || NodeAfter(aNode, mList.getLast())) { mList.insertBack(aNode); } else { // Binary search. // the range of indices at which |aNode| could end up. // (We already know it can't be at index mSize.) uint32_t first = 0, last = mSize - 1; // A cursor to avoid walking more than the length of the list. nsGenConNode* curNode = mList.getLast(); uint32_t curIndex = mSize - 1; while (first != last) { uint32_t test = (first + last) / 2; if (last == curIndex) { for ( ; curIndex != test; --curIndex) curNode = Prev(curNode); } else { for ( ; curIndex != test; ++curIndex) curNode = Next(curNode); } if (NodeAfter(aNode, curNode)) { first = test + 1; // if we exit the loop, we need curNode to be right ++curIndex; curNode = Next(curNode); } else { last = test; } } curNode->setPrevious(aNode); } ++mSize; // Set the mapping only if it is the first node of the frame. // The DEBUG blocks below are for ensuring the invariant required by // nsGenConList::DestroyNodesFor. See comment there. if (IsFirst(aNode) || Prev(aNode)->mPseudoFrame != aNode->mPseudoFrame) { #ifdef DEBUG if (nsGenConNode* oldFrameFirstNode = mNodes.Get(aNode->mPseudoFrame)) { MOZ_ASSERT(Next(aNode) == oldFrameFirstNode, "oldFrameFirstNode should now be immediately after " "the newly-inserted one."); } else { // If the node is not the only node in the list. if (!IsFirst(aNode) || !IsLast(aNode)) { nsGenConNode* nextNode = Next(aNode); MOZ_ASSERT(!nextNode || nextNode->mPseudoFrame != aNode->mPseudoFrame, "There shouldn't exist any node for this frame."); // If the node is neither the first nor the last node if (!IsFirst(aNode) && !IsLast(aNode)) { MOZ_ASSERT(Prev(aNode)->mPseudoFrame != nextNode->mPseudoFrame, "New node should not break contiguity of nodes of " "the same frame."); } } } #endif mNodes.Put(aNode->mPseudoFrame, aNode); } else { #ifdef DEBUG nsGenConNode* frameFirstNode = mNodes.Get(aNode->mPseudoFrame); MOZ_ASSERT(frameFirstNode, "There should exist node map for the frame."); for (nsGenConNode* curNode = Prev(aNode); curNode != frameFirstNode; curNode = Prev(curNode)) { MOZ_ASSERT(curNode->mPseudoFrame == aNode->mPseudoFrame, "Every node between frameFirstNode and the new node inserted " "should refer to the same frame."); MOZ_ASSERT(!IsFirst(curNode), "The newly-inserted node should be in a contiguous run after " "frameFirstNode, thus frameFirstNode should be reached before " "the first node of mList."); } #endif } NS_ASSERTION(IsFirst(aNode) || NodeAfter(aNode, Prev(aNode)), "sorting error"); NS_ASSERTION(IsLast(aNode) || NodeAfter(Next(aNode), aNode), "sorting error"); }
status_t ArpIndexedList::NodeAt(int32 index, ArpIndexedNode **node, int32 findNode, int32 direction) { if (direction == ARP_BACKWARDS) return(NodeBefore(index, node, findNode)); if (direction == ARP_FORWARDS) return(NodeAfter(index, node, findNode)); return B_ERROR; }