/// <summary> /// adds a ptdur to this sieve /// </summary> /// <param name="ptdur">the ptdur to add</param> /// <param name="forceAddition">forces the addition of the ptdur without testing if a ptdur already exists that is 'better' in terms of optional components</param> /// <returns>the leaf that this ptdur is stored in</returns> public Leaf Add(PTD ptdur, bool forceAddition = false) { SieveNode currentNode = startNode; // traverse the tree do { InnerNode currentInnerNode = currentNode as InnerNode; // if it exists, then find the child with the matching interval BitSet and mark it as the current node bool currentNodeHasMatchingChild = false; for (int i = 0; i < currentInnerNode.children.Count; i++) { (BitSet childSet, SieveNode sieveNode) = currentInnerNode.children[i]; if (ptdur.vertices.EqualsOnInterval(childSet, currentInnerNode.intervalFrom, currentInnerNode.intervalTo)) { currentNode = sieveNode; currentNodeHasMatchingChild = true; break; } } // if such a child does not exist, make one if (!currentNodeHasMatchingChild) { // add new inner node that covers the rest of the interval if the current node doesn't cover it fully if (currentInnerNode.intervalTo < vertexCount) { InnerNode newNode = new InnerNode(currentInnerNode.intervalTo, vertexCount, currentInnerNode); BitSet intervalBitSet = ptdur.vertices; currentInnerNode.AddChild(intervalBitSet, newNode); currentInnerNode = newNode; } Debug.Assert(currentInnerNode.intervalTo == vertexCount); // add leaf Leaf newLeaf = new Leaf(ptdur, currentInnerNode); currentInnerNode.AddChild(ptdur.vertices, newLeaf); currentNode = newLeaf; return(newLeaf); } }while (!currentNode.isLeaf); // test if a ptdur exists in this leaf that is 'better' than the one to add or vice versa Leaf currentNodeAsLeaf = currentNode as Leaf; currentNodeAsLeaf.ptdur = ptdur; return(currentNodeAsLeaf); }
/// <summary> /// Adds a child node to this node. /// </summary> /// <param name="n">The node to add.</param> /// <returns>Returns true if the node was added or false if nodes can not be added to this node.</returns> public virtual bool AddChild(Node <M> n) { if (InnerNode != null) { return(InnerNode.AddChild(n)); // Children should always be added to the inner most node (note that decoration happens at construction so children can only be on the inner most node) } if (!Terminal) { children.Add(n); } return(!Terminal); }
/// <summary> /// splits this node into two layers which cover smaller intervals than the old node /// </summary> public void Split() { int splitVertex = GetSplitVertex(); int childrenIntervalFrom = splitVertex; int childrenIntervalTo = intervalTo; intervalTo = splitVertex; // create new children list List <(BitSet, SieveNode)> newChildrenList = new List <(BitSet, SieveNode)>(); // loop over all former children for (int i = 0; i < children.Count; i++) { (BitSet currentChildIntervalBitSet, SieveNode currentChildNode) = children[i]; // find correct new child to attach the former child to bool newChildExists = false; for (int j = 0; j < newChildrenList.Count; j++) { (BitSet currentNewChildIntervalBitSet, SieveNode currentNewChildNode) = newChildrenList[j]; if (currentChildIntervalBitSet.EqualsOnInterval(currentNewChildIntervalBitSet, intervalFrom, intervalTo)) { ((InnerNode)currentNewChildNode).AddChild(currentChildIntervalBitSet, currentChildNode); currentChildNode.parent = (InnerNode)currentNewChildNode; Debug.Assert(currentChildNode.parent == currentNewChildNode); newChildExists = true; break; } } // if no such new child exists, create it if (!newChildExists) { InnerNode newNode = new InnerNode(childrenIntervalFrom, childrenIntervalTo, this); newNode.AddChild(currentChildIntervalBitSet, currentChildNode); //currentChildNode.parent = newNode; Debug.Assert(currentChildNode.parent == newNode); newChildrenList.Add((currentChildIntervalBitSet, newNode)); } } // replace the old children list by the new one children = newChildrenList; }