OcTreeNodeJointAngles* OcTreeJointAngles::updateNode(const OcTreeKey& k) { if (root == NULL){ root = new OcTreeNodeJointAngles(); tree_size++; } OcTreeNodeJointAngles* currNode(root); // follow or construct nodes down to last level... for (int i = (tree_depth - 1); i >= 0; i--) { unsigned int pos = computeChildIdx(k, i); // requested node does not exist if (!currNode->childExists(pos)) { currNode->createChild(pos); tree_size++; } // descend tree currNode = static_cast<OcTreeNodeJointAngles*> (currNode->getChild(pos)); assert(currNode); } return currNode; }
void nsAccUtils::GetPositionAndSizeForXULSelectControlItem(nsIDOMNode *aNode, PRInt32 *aPosInSet, PRInt32 *aSetSize) { nsCOMPtr<nsIDOMXULSelectControlItemElement> item(do_QueryInterface(aNode)); if (!item) return; nsCOMPtr<nsIDOMXULSelectControlElement> control; item->GetControl(getter_AddRefs(control)); if (!control) return; PRUint32 itemsCount = 0; control->GetItemCount(&itemsCount); PRInt32 indexOf = 0; control->GetIndexOfItem(item, &indexOf); *aSetSize = itemsCount; *aPosInSet = indexOf; for (PRUint32 index = 0; index < itemsCount; index++) { nsCOMPtr<nsIDOMXULSelectControlItemElement> currItem; control->GetItemAtIndex(index, getter_AddRefs(currItem)); nsCOMPtr<nsIDOMNode> currNode(do_QueryInterface(currItem)); nsCOMPtr<nsIAccessible> itemAcc; GetAccService()->GetAccessibleFor(currNode, getter_AddRefs(itemAcc)); if (!itemAcc || State(itemAcc) & nsIAccessibleStates::STATE_INVISIBLE) { (*aSetSize)--; if (index < static_cast<PRUint32>(indexOf)) (*aPosInSet)--; } } (*aPosInSet)++; // group position is 1-index based. }
void Dbtux::searchToScanDescending(Frag& frag, ConstData boundInfo, unsigned boundCount, TreePos& treePos) { const TreeHead& tree = frag.m_tree; NodeHandle currNode(frag); currNode.m_loc = tree.m_root; NodeHandle glbNode(frag); // potential g.l.b of final node NodeHandle bottomNode(frag); while (true) { jam(); selectNode(currNode, currNode.m_loc); int ret; // compare prefix ret = cmpScanBound(frag, 1, boundInfo, boundCount, currNode.getPref(), tree.m_prefSize); if (ret == NdbSqlUtil::CmpUnknown) { jam(); // read and compare all attributes readKeyAttrs(frag, currNode.getMinMax(0), 0, c_entryKey); ret = cmpScanBound(frag, 1, boundInfo, boundCount, c_entryKey); ndbrequire(ret != NdbSqlUtil::CmpUnknown); } if (ret < 0) { // bound is left of this node jam(); const TupLoc loc = currNode.getLink(0); if (loc != NullTupLoc) { jam(); // continue to left subtree currNode.m_loc = loc; continue; } if (! glbNode.isNull()) { jam(); // move up to the g.l.b but remember the bottom node bottomNode = currNode; currNode = glbNode; } else { // empty result set return; } } else { // bound is at or right of this node jam(); const TupLoc loc = currNode.getLink(1); if (loc != NullTupLoc) { jam(); // save potential g.l.b glbNode = currNode; // continue to right subtree currNode.m_loc = loc; continue; } } break; } for (unsigned j = 0, occup = currNode.getOccup(); j < occup; j++) { jam(); int ret; // read and compare attributes readKeyAttrs(frag, currNode.getEnt(j), 0, c_entryKey); ret = cmpScanBound(frag, 1, boundInfo, boundCount, c_entryKey); ndbrequire(ret != NdbSqlUtil::CmpUnknown); if (ret < 0) { if (j > 0) { // start scanning from previous entry treePos.m_loc = currNode.m_loc; treePos.m_pos = j - 1; treePos.m_dir = 3; return; } // start scanning upwards (pretend we came from left child) treePos.m_loc = currNode.m_loc; treePos.m_pos = 0; treePos.m_dir = 0; return; } } // start scanning this node treePos.m_loc = currNode.m_loc; treePos.m_pos = currNode.getOccup() - 1; treePos.m_dir = 3; }
/* * Search for entry to add. * * Similar to searchToRemove (see below). */ bool Dbtux::searchToAdd(Frag& frag, ConstData searchKey, TreeEnt searchEnt, TreePos& treePos) { const TreeHead& tree = frag.m_tree; const unsigned numAttrs = frag.m_numAttrs; NodeHandle currNode(frag); currNode.m_loc = tree.m_root; if (currNode.m_loc == NullTupLoc) { // empty tree jam(); return true; } NodeHandle glbNode(frag); // potential g.l.b of final node /* * In order to not (yet) change old behaviour, a position between * 2 nodes returns the one at the bottom of the tree. */ NodeHandle bottomNode(frag); while (true) { jam(); selectNode(currNode, currNode.m_loc); int ret; // compare prefix unsigned start = 0; ret = cmpSearchKey(frag, start, searchKey, currNode.getPref(), tree.m_prefSize); if (ret == NdbSqlUtil::CmpUnknown) { jam(); // read and compare remaining attributes ndbrequire(start < numAttrs); readKeyAttrs(frag, currNode.getMinMax(0), start, c_entryKey); ret = cmpSearchKey(frag, start, searchKey, c_entryKey); ndbrequire(ret != NdbSqlUtil::CmpUnknown); } if (ret == 0) { jam(); // keys are equal, compare entry values ret = searchEnt.cmp(currNode.getMinMax(0)); } if (ret < 0) { jam(); const TupLoc loc = currNode.getLink(0); if (loc != NullTupLoc) { jam(); // continue to left subtree currNode.m_loc = loc; continue; } if (! glbNode.isNull()) { jam(); // move up to the g.l.b but remember the bottom node bottomNode = currNode; currNode = glbNode; } } else if (ret > 0) { jam(); const TupLoc loc = currNode.getLink(1); if (loc != NullTupLoc) { jam(); // save potential g.l.b glbNode = currNode; // continue to right subtree currNode.m_loc = loc; continue; } } else { jam(); treePos.m_loc = currNode.m_loc; treePos.m_pos = 0; // entry found - error return false; } break; } // anticipate treePos.m_loc = currNode.m_loc; // binary search int lo = -1; int hi = currNode.getOccup(); int ret; while (1) { jam(); // hi - lo > 1 implies lo < j < hi int j = (hi + lo) / 2; // read and compare attributes unsigned start = 0; readKeyAttrs(frag, currNode.getEnt(j), start, c_entryKey); ret = cmpSearchKey(frag, start, searchKey, c_entryKey); ndbrequire(ret != NdbSqlUtil::CmpUnknown); if (ret == 0) { jam(); // keys are equal, compare entry values ret = searchEnt.cmp(currNode.getEnt(j)); } if (ret < 0) hi = j; else if (ret > 0) lo = j; else { treePos.m_pos = j; // entry found - error return false; } if (hi - lo == 1) break; } if (ret < 0) { jam(); treePos.m_pos = hi; return true; } if ((uint) hi < currNode.getOccup()) { jam(); treePos.m_pos = hi; return true; } if (bottomNode.isNull()) { jam(); treePos.m_pos = hi; return true; } jam(); // backwards compatible for now treePos.m_loc = bottomNode.m_loc; treePos.m_pos = 0; return true; }
/* * Search for entry to remove. * * Compares search key to each node min. A move to right subtree can * overshoot target node. The last such node is saved. The final node * is a semi-leaf or leaf. If search key is less than final node min * then the saved node is the g.l.b of the final node and we move back * to it. */ bool Dbtux::searchToRemove(Frag& frag, ConstData searchKey, TreeEnt searchEnt, TreePos& treePos) { const TreeHead& tree = frag.m_tree; const unsigned numAttrs = frag.m_numAttrs; NodeHandle currNode(frag); currNode.m_loc = tree.m_root; if (currNode.m_loc == NullTupLoc) { // empty tree - failed jam(); return false; } NodeHandle glbNode(frag); // potential g.l.b of final node while (true) { jam(); selectNode(currNode, currNode.m_loc); int ret; // compare prefix unsigned start = 0; ret = cmpSearchKey(frag, start, searchKey, currNode.getPref(), tree.m_prefSize); if (ret == NdbSqlUtil::CmpUnknown) { jam(); // read and compare remaining attributes ndbrequire(start < numAttrs); readKeyAttrs(frag, currNode.getMinMax(0), start, c_entryKey); ret = cmpSearchKey(frag, start, searchKey, c_entryKey); ndbrequire(ret != NdbSqlUtil::CmpUnknown); } if (ret == 0) { jam(); // keys are equal, compare entry values ret = searchEnt.cmp(currNode.getMinMax(0)); } if (ret < 0) { jam(); const TupLoc loc = currNode.getLink(0); if (loc != NullTupLoc) { jam(); // continue to left subtree currNode.m_loc = loc; continue; } if (! glbNode.isNull()) { jam(); // move up to the g.l.b currNode = glbNode; } } else if (ret > 0) { jam(); const TupLoc loc = currNode.getLink(1); if (loc != NullTupLoc) { jam(); // save potential g.l.b glbNode = currNode; // continue to right subtree currNode.m_loc = loc; continue; } } else { jam(); treePos.m_loc = currNode.m_loc; treePos.m_pos = 0; return true; } break; } // anticipate treePos.m_loc = currNode.m_loc; // pos 0 was handled above for (unsigned j = 1, occup = currNode.getOccup(); j < occup; j++) { jam(); // compare only the entry if (searchEnt.eq(currNode.getEnt(j))) { jam(); treePos.m_pos = j; return true; } } treePos.m_pos = currNode.getOccup(); // not found - failed return false; }
nsresult nsTextAttrsMgr::GetRange(const nsTPtrArray<nsITextAttr>& aTextAttrArray, PRInt32 *aStartHTOffset, PRInt32 *aEndHTOffset) { nsCOMPtr<nsIDOMElement> rootElm = nsCoreUtils::GetDOMElementFor(mHyperTextNode); NS_ENSURE_STATE(rootElm); nsCOMPtr<nsIDOMNode> tmpNode(mOffsetNode); nsCOMPtr<nsIDOMNode> currNode(mOffsetNode); PRUint32 len = aTextAttrArray.Length(); // Navigate backwards and forwards from current node to the root node to // calculate range bounds for the text attribute. Navigation sequence is the // following: // 1. Navigate through the siblings. // 2. If the traversed sibling has children then navigate from its leaf child // to it through whole tree of the traversed sibling. // 3. Get the parent and cycle algorithm until the root node. // Navigate backwards (find the start offset). while (currNode && currNode != rootElm) { nsCOMPtr<nsIDOMElement> currElm(nsCoreUtils::GetDOMElementFor(currNode)); NS_ENSURE_STATE(currElm); if (currNode != mOffsetNode) { PRBool stop = PR_FALSE; for (PRUint32 idx = 0; idx < len; idx++) { nsITextAttr *textAttr = aTextAttrArray[idx]; if (!textAttr->Equal(currElm)) { PRInt32 startHTOffset = 0; nsCOMPtr<nsIAccessible> startAcc; nsresult rv = mHyperTextAcc-> DOMPointToHypertextOffset(tmpNode, -1, &startHTOffset, getter_AddRefs(startAcc)); NS_ENSURE_SUCCESS(rv, rv); if (!startAcc) startHTOffset = 0; if (startHTOffset > *aStartHTOffset) *aStartHTOffset = startHTOffset; stop = PR_TRUE; break; } } if (stop) break; } currNode->GetPreviousSibling(getter_AddRefs(tmpNode)); if (tmpNode) { // Navigate through the subtree of traversed children to calculate // left bound of the range. FindStartOffsetInSubtree(aTextAttrArray, tmpNode, currNode, aStartHTOffset); } currNode->GetParentNode(getter_AddRefs(tmpNode)); currNode.swap(tmpNode); } // Navigate forwards (find the end offset). PRBool moveIntoSubtree = PR_TRUE; currNode = mOffsetNode; while (currNode && currNode != rootElm) { nsCOMPtr<nsIDOMElement> currElm(nsCoreUtils::GetDOMElementFor(currNode)); NS_ENSURE_STATE(currElm); // Stop new end offset searching if the given text attribute changes its // value. PRBool stop = PR_FALSE; for (PRUint32 idx = 0; idx < len; idx++) { nsITextAttr *textAttr = aTextAttrArray[idx]; if (!textAttr->Equal(currElm)) { PRInt32 endHTOffset = 0; nsresult rv = mHyperTextAcc-> DOMPointToHypertextOffset(currNode, -1, &endHTOffset); NS_ENSURE_SUCCESS(rv, rv); if (endHTOffset < *aEndHTOffset) *aEndHTOffset = endHTOffset; stop = PR_TRUE; break; } } if (stop) break; if (moveIntoSubtree) { // Navigate through subtree of traversed node. We use 'moveIntoSubtree' // flag to avoid traversing the same subtree twice. currNode->GetFirstChild(getter_AddRefs(tmpNode)); if (tmpNode) FindEndOffsetInSubtree(aTextAttrArray, tmpNode, aEndHTOffset); } currNode->GetNextSibling(getter_AddRefs(tmpNode)); moveIntoSubtree = PR_TRUE; if (!tmpNode) { currNode->GetParentNode(getter_AddRefs(tmpNode)); moveIntoSubtree = PR_FALSE; } currNode.swap(tmpNode); } return NS_OK; }