public synchronized boolean changeParent ( int depStreamID , int newPriority , int newParentStreamID , boolean exclusive ) { if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isDebugEnabled ( ) ) { Tr . debug ( tc , "changeParent entry: depStreamID: " + depStreamID + " newParentStreamID: " + newParentStreamID + " exclusive: " + exclusive ) ; } // notice that the new dependent node and parent do not have to be directly related coming into this method. // Therefore, find both nodes starting at the root. Node depNode = root . findNode ( depStreamID ) ; Node newParentNode = root . findNode ( newParentStreamID ) ; if ( ( depNode == null ) || ( newParentNode == null ) ) { return false ; } // If the new parent can not be found in the tree under the dependent node, then changing parents is straight forward. if ( depNode . findNode ( newParentStreamID ) == null ) { // simple move, since the new parent is not a dependent of the stream that is changing parents if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isDebugEnabled ( ) ) { Tr . debug ( tc , "new parent is not a dependent of the stream that is changing parents" ) ; } Node oldParent = depNode . getParent ( ) ; // move the dependent node, reset write counters, and re-sort the affected set of siblings according to original priorities depNode . setParent ( newParentNode , true ) ; depNode . setPriority ( newPriority ) ; newParentNode . clearDependentsWriteCount ( ) ; newParentNode . sortDependents ( ) ; // where it left from needs to be re-sorted also oldParent . clearDependentsWriteCount ( ) ; oldParent . sortDependents ( ) ; // according to spec: after setting the new parent, if this node is to be exclusive, then invode the exclusive algorithm on it. if ( exclusive ) { makeExclusiveDependency ( depNode , newParentNode ) ; } } else { // so much for simple. The parent is in the dependency tree underneath the node that we now want to be dependent on the new Parent. // in the above example: A - depNode, D - newParentNode. // The below steps are following how that spec says to handle this case (or at least it is suppose to). if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isDebugEnabled ( ) ) { Tr . debug ( tc , "new parent is a dependent of the stream that is changing parents" ) ; } // move the current newParentNode to be the dependent on the new dependent node's previous parent. Node grandParent = depNode . getParent ( ) ; Node oldDepParent = newParentNode . getParent ( ) ; newParentNode . setParent ( grandParent , true ) ; // set Parent will also remove newParentNode as a dependent of its current/old parent // now make the new dependent node depend on the newParentNode depNode . setParent ( newParentNode , true ) ; depNode . setPriority ( newPriority ) ; // clear and re-sort the effective levels we touched grandParent . clearDependentsWriteCount ( ) ; grandParent . sortDependents ( ) ; newParentNode . clearDependentsWriteCount ( ) ; newParentNode . sortDependents ( ) ; oldDepParent . clearDependentsWriteCount ( ) ; oldDepParent . sortDependents ( ) ; // and finally if the new dependency node is suppose to end up exclusive, make it so now. if ( exclusive ) { makeExclusiveDependency ( depNode , newParentNode ) ; } } if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isDebugEnabled ( ) ) { Tr . debug ( tc , "changeParent exit: depNode on exit: " + depNode . toStringDetails ( ) ) ; } return true ; }
Implement the above spec functionality