/** * Calculates how every traffic light should be switched Per node, per sign the waiting roadusers * are passed and per each roaduser the gain is calculated. * * @param The TLDecision is a tuple consisting of a traffic light and a reward (Q) value, for it * to be green * @see gld.algo.tlc.TLDecision */ public TLDecision[][] decideTLs() { int num_dec; int num_tld = tld.length; // Determine wheter it should be random or not boolean do_this_random = false; if (random_number.nextFloat() < random_chance) do_this_random = true; for (int i = 0; i < num_tld; i++) { num_dec = tld[i].length; for (int j = 0; j < num_dec; j++) { Sign currenttl = tld[i][j].getTL(); float gain = 0; Drivelane currentlane = currenttl.getLane(); int waitingsize = currentlane.getNumRoadusersWaiting(); ListIterator queue = currentlane.getQueue().listIterator(); if (!do_this_random) { for (; waitingsize > 0; waitingsize--) { Roaduser ru = (Roaduser) queue.next(); int pos = ru.getPosition(); Node destination = ru.getDestNode(); gain += q_table[currenttl.getId()][pos][destination.getId()][1] - q_table[currenttl.getId()][pos][destination.getId()][0]; // red - green } float q = gain; } else gain = random_number.nextFloat(); tld[i][j].setGain(gain); } } return tld; }
public IXArchElement cloneElement(int depth) { synchronized (DOMUtils.getDOMLock(elt)) { Document doc = elt.getOwnerDocument(); if (depth == 0) { Element cloneElt = (Element) elt.cloneNode(false); cloneElt = (Element) doc.importNode(cloneElt, true); AbstractChangeSetImpl cloneImpl = new AbstractChangeSetImpl(cloneElt); cloneImpl.setXArch(getXArch()); return cloneImpl; } else if (depth == 1) { Element cloneElt = (Element) elt.cloneNode(false); cloneElt = (Element) doc.importNode(cloneElt, true); AbstractChangeSetImpl cloneImpl = new AbstractChangeSetImpl(cloneElt); cloneImpl.setXArch(getXArch()); NodeList nl = elt.getChildNodes(); int size = nl.getLength(); for (int i = 0; i < size; i++) { Node n = nl.item(i); Node cloneNode = (Node) n.cloneNode(false); cloneNode = doc.importNode(cloneNode, true); cloneElt.appendChild(cloneNode); } return cloneImpl; } else /* depth = infinity */ { Element cloneElt = (Element) elt.cloneNode(true); cloneElt = (Element) doc.importNode(cloneElt, true); AbstractChangeSetImpl cloneImpl = new AbstractChangeSetImpl(cloneElt); cloneImpl.setXArch(getXArch()); return cloneImpl; } } }
/** Derefernce a node which may be a functor node */ public static Node derefPossFunctor(Node node) { if (node instanceof Node_RuleVariable) { Node dnode = ((Node_RuleVariable) node).deref(); if (dnode.isVariable()) { // Problem with variable in return result "should never happen" throw new ReasonerException("Internal error in LP reasoner: variable in triple result"); } if (Functor.isFunctor(dnode)) { Functor f = (Functor) dnode.getLiteralValue(); Node[] fargs = f.getArgs(); boolean needCopy = false; for (Node farg : fargs) { if (farg.isVariable()) { needCopy = true; break; } } if (needCopy) { Node[] newArgs = new Node[fargs.length]; for (int i = 0; i < fargs.length; i++) { newArgs[i] = deref(fargs[i]); } dnode = Functor.makeFunctorNode(f.getName(), newArgs); } return dnode; } else { return dnode; } } else { return node; } }
/** * Converts an XML element into an <code>EppCommandRenewXriName</code> object. The caller of this * method must make sure that the root node is of an EPP Command Renew entity for EPP XRI I-Name * object * * @param root root node for an <code>EppCommandRenewXriName</code> object in XML format * @return an <code>EppCommandRenewXriName</code> object, or null if the node is invalid */ public static EppEntity fromXML(Node root) { EppCommandRenewXriName cmd = null; String iname = null; Calendar curExpDate = null; EppPeriod period = null; NodeList list = root.getChildNodes(); for (int i = 0; i < list.getLength(); i++) { Node node = list.item(i); String name = node.getLocalName(); if (name == null) { continue; } if (name.equals("iname")) { iname = EppUtil.getText(node); } else if (name.equals("curExpDate")) { curExpDate = EppUtil.getDate(node, true); } else if (name.equals("period")) { period = (EppPeriod) EppPeriod.fromXML(node); } } if (iname != null) { cmd = new EppCommandRenewXriName(iname, curExpDate, period, null); } return cmd; }
void left(Node node) { String str = node.getState(); String parent = node.getParent(); Node newState = new Node(); int a = str.indexOf("0"); char temp; char[] s = str.toCharArray(); String newStr; if (a != 0) { temp = s[a - 1]; s[a - 1] = '0'; s[a] = temp; newStr = this.gString(s); newState.setState(newStr); newState.setParent(str); // newState.setLevel(node.getLevel()+1); // newState.setHeuristic(newState.calculateHeuristic(goal)); // newState.setFvalue(newState.getHeuristic() + newState.getLevel()); add(newState, map.get(str) + 1); // add(s,map.get(str)+1); if (newStr.equals("www0bbb")) { System.out.println( "Solution found after searching through " + map.get(newStr) + " states of the tree"); printSolution(); System.exit(0); } } }
/** * A real node-function (using the node argument). Returns the next newer node of same type. Also * a nice example on the difference between core and bridge. */ public Object successor() { if (node == null) throw new IllegalArgumentException("successor is a node-function"); if (cloud != null) { log.debug("Using bridge (security restrictions will be honoured)"); NodeManager nm = node.getNodeManager(); NodeQuery q = nm.createQuery(); StepField field = q.getStepField(nm.getField("number")); q.setConstraint( q.createConstraint( field, FieldCompareConstraint.GREATER, Integer.valueOf(node.getNumber()))); q.addSortOrder(field, SortOrder.ORDER_ASCENDING); q.setMaxNumber(1); NodeIterator i = nm.getList(q).nodeIterator(); return i.hasNext() ? i.nextNode() : null; } else { log.debug("Using core."); throw new UnsupportedOperationException("Core implementation was dropped. See source code."); /* This is how it would go with core objects MMObjectBuilder builder = MMBase.getMMBase().getBuilder(node.getNodeManager().getName()); NodeSearchQuery query = new NodeSearchQuery(builder); StepField field = query.getField(builder.getField("number")); BasicFieldValueConstraint cons = new BasicFieldValueConstraint(field, node.getNumber()); cons.setOperator(FieldCompareConstraint.GREATER); query.setConstraint(cons); query.addSortOrder(field); query.setMaxNumber(1); try { java.util.Iterator<MMObjectNode> i = builder.getNodes(query).iterator(); return i.hasNext() ? i.next() : null; } catch (Exception e) { return null; } */ } }
private Graph changeLatentNames(Graph full, Clusters measurements, List<String> latentVarList) { Graph g2 = null; try { g2 = (Graph) new MarshalledObject(full).get(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } for (int i = 0; i < measurements.getNumClusters(); i++) { List<String> d = measurements.getCluster(i); String latentName = latentVarList.get(i); for (Node node : full.getNodes()) { if (!(node.getNodeType() == NodeType.LATENT)) { continue; } List<Node> _children = full.getChildren(node); _children.removeAll(ReidentifyVariables.getLatents(full)); List<String> childNames = getNames(_children); if (new HashSet<String>(childNames).equals(new HashSet<String>(d))) { g2.getNode(node.getName()).setName(latentName); } } } return g2; }
public final Object getColumnValue(Object row, int columnIndex) { try { Node node = (Node) row; switch (columnIndex) { case 0: if (node.label == null) { IObject obj = snapshot.getObject(node.objectId); node.label = obj.getDisplayName(); node.shallowHeap = obj.getUsedHeapSize(); } return node.label; case 1: if (node.shallowHeap == -1) node.shallowHeap = snapshot.getHeapSize(node.objectId); return node.shallowHeap; case 2: if (node.retainedHeap == -1) node.retainedHeap = snapshot.getRetainedHeapSize(node.objectId); return node.retainedHeap; } } catch (SnapshotException e) { throw new RuntimeException(e); } return null; }
static void connect(Node ch, Node p, Boolean isLeftChild) { if (ch != null) ch.parent = p; if (isLeftChild != null) { if (isLeftChild) p.left = ch; else p.right = ch; } }
@Override void replaceChild( @SuppressWarnings("unused") Node oldChild, @SuppressWarnings("unused") Node newChild) { // Replace child if (this._quad_ == oldChild) { setQuad((TQuad) newChild); return; } for (ListIterator<TId> i = this._path_.listIterator(); i.hasNext(); ) { if (i.next() == oldChild) { if (newChild != null) { i.set((TId) newChild); newChild.parent(this); oldChild.parent(null); return; } i.remove(); oldChild.parent(null); return; } } if (this._id_ == oldChild) { setId((TId) newChild); return; } throw new RuntimeException("Not a child."); }
/** * Inserts a node into the SplayTree, then splays around that node. * * @param comp Comparable value of new node being added */ public void insert(Comparable comp) { Node node = new Node(comp); if (rootNode == null && size == 0) { rootNode = node; return; } splay(comp); int temp = comp.compareTo(rootNode.getValue()); if (temp == 0) // Double checks for duplicates return; if (temp < 0) { node.setLeft(rootNode.getLeft()); node.setRight(rootNode); rootNode.setLeft(null); } else { node.setRight(rootNode.getRight()); node.setLeft(rootNode); rootNode.setRight(null); } rootNode = node; size++; }
/** * Obtain a new Node from a type that matches the given string. It will try to correctly detect * RealVar and constant nodes. The Node is cloned and initialized, so it can be used separatedly * * @param name The type of the requested Node. It must coincide with one of the class names of * available Nodes, unless it represents a variable or constant terminal * @param currentGlobalDepth The depth of the requested Node in the Tree */ public Node newNode(String name, int currentGlobalDepth) { System.out.println(name); Node outNode = null; if (name.startsWith("X")) { outNode = new RealVar(Integer.parseInt(name.substring("X".length(), name.length()))); } else if (name.startsWith("angle")) { outNode = new Angle(Integer.parseInt(name.substring("angle".length(), name.length()))); } else if (name.substring(0, 1).matches("\\d")) { outNode = new RealConstant(Double.parseDouble(name)); } else if (name.equals("true")) { outNode = new LogicConstant(1); } else if (name.equals("false")) { outNode = new LogicConstant(0); } else { List<Node> all = new ArrayList<Node>(); for (int i = 0; i < nodeSets.length; i++) { all.addAll(nodeSets[i].getAll()); } for (Node n : all) { if (name.equals(n.name())) { try { outNode = (Node) n.clone(); } catch (CloneNotSupportedException e) { Logger.log(e); } break; } } } outNode.setCurrentDepth(currentGlobalDepth); return outNode; }
/** * The constructor for TL controllers * * @param The model being used. */ public SL1TLC(Infrastructure infra) throws InfraException { super(infra); Node[] nodes = infra.getAllNodes(); // Moet Edge zijn eigenlijk, alleen testSimModel knalt er dan op int num_nodes = nodes.length; count = new Vector(); int numSigns = infra.getAllInboundLanes().size(); q_table = new float[numSigns + 1][][][]; int num_specialnodes = infra.getNumSpecialNodes(); for (int i = 0; i < nodes.length; i++) { Node n = nodes[i]; Drivelane[] dls = n.getInboundLanes(); for (int j = 0; j < dls.length; j++) { Drivelane d = dls[j]; Sign s = d.getSign(); int id = s.getId(); int num_pos_on_dl = d.getCompleteLength(); q_table[id] = new float[num_pos_on_dl][][]; for (int k = 0; k < num_pos_on_dl; k++) { q_table[id][k] = new float[num_specialnodes][]; for (int l = 0; l < q_table[id][k].length; l++) { q_table[id][k][l] = new float[2]; q_table[id][k][l][0] = 0.0f; q_table[id][k][l][1] = 0.0f; } } } } System.out.println("Startet med Alpha = " + alpha); random_number = new Random(); }
protected void recalcQ( Sign tl, int pos, Node destination, boolean light, Sign tl_new, int pos_new, boolean light_new, PosMov[] posMovs) { /* Recalculate the Q values, only one PEntry has changed, meaning also only 1 QEntry has to change */ int R; float oldQvalue = 0; float Qmark = 0; float newQvalue = 0; R = rewardFunction(tl_new, pos_new, posMovs); try { oldQvalue = q_table[tl.getId()][pos][destination.getId()][light ? green_index : red_index]; Qmark = q_table[tl_new.getId()][pos_new][destination.getId()][ light_new ? green_index : red_index]; // Q( [ tl' , p' ] , L') } catch (Exception e) { System.out.println("ERROR"); System.out.println("tl: " + tl.getId()); System.out.println("pos:" + pos); System.out.println("des:" + destination.getId()); } newQvalue = oldQvalue + alpha * (R + gamma * Qmark - oldQvalue); q_table[tl.getId()][pos][destination.getId()][light ? green_index : red_index] = newQvalue; }
// Busqueda usando A* public static int search() { HashSet<State> v = new HashSet<>(); Giros mano = new Giros(); ArrayList<int[][]>aux; finall = inicial.createGoalState(); Q.add(inicial); Node actual; int cont = 0; while ( !(actual = Q.remove()).estado.equals(finall.estado) ) { if(v.contains(actual.estado)) continue; System.out.println(actual.estado+" "+actual.costo_hasta_aqui+" "+actual.costo_total); System.out.println("->\n"+((NodeCubo)actual).getValue() ); v.add(actual.estado); int ca = actual.costo_hasta_aqui + 1; //Realiza Movimientos for( int i=0; i<12; i++ ){ aux = mano.girar( ((Cubo)actual.getValue()).getCubo(), i); Node nuevo = new NodeCubo(ca, ca+Heuristica.h1((Cubo)actual.getValue()), new Cubo( aux, ((Cubo)inicial.getValue()).getColors() ) ); Q.add( (Node)nuevo ); } cont++; } return cont; }
protected void recalcQ(Sign tl, int pos, Node destination, boolean light, Sign tl_new, int pos_new, PosMov[] posMovs, int Ktl) { /* The calculation of the Q values in TC-3 */ float newQvalue = qa_table[tl.getId()][pos][destination.getId()][light?green_index:red_index]; float V=0; // Waarom splitst TC2 wel op rood/groen, en TC3 niet?? CountEntry currentsituation = new CountEntry (tl, pos, destination, light, tl_new, pos_new, Ktl); Enumeration e = pKtl_table[tl.getId()][pos][destination.getId()].elements(); while(e.hasMoreElements()) { PKtlEntry P = (PKtlEntry) e.nextElement(); if(P.sameSourceKtl(currentsituation) != -1.0f) { try { V = v_table[P.tl_new.getId()][P.pos_new][destination.getId()]; } catch (Exception excep) { System.out.println("ERROR in q"); } // Moet er hier geen reward functie?? newQvalue += P.getValue() *gamma * V; } } q_table[tl.getId()][pos][destination.getId()][light?green_index:red_index] = newQvalue; //sign, pos, des, color (red=0, green=1) }
/** * Reload the composite nodes of the circuit, this is recursive * * @param g the graphics that will paint the node * @throws CircuitLoadingException if the internal circuit can not be loaded */ public void reloadCompositeNodes(Graphics g) throws CircuitLoadingException { for (iterNodes = this.nodes.iterator(); iterNodes.hasNext(); ) { Node n = iterNodes.next(); if (n.getCategoryID() == Node.COMPOSITE) ((CompositeNode) n).reload(g); } }
protected void recalcQa(Sign tl, int pos, Node destination, boolean light, Sign tl_new, int pos_new, PosMov[] posMovs) { float newQvalue=0; int size = tl.getLane().getCompleteLength()-1; int R; int tlId = tl.getId(); int desId = destination.getId(); float Va; for(; size>=0; size--) { PEntry P = new PEntry(tl, pos, destination, light, tl, size); int p_index = p_table[tlId][pos][desId].indexOf(P); if(p_index>=0) { try { P = (PEntry) p_table[tlId][pos][desId].elementAt(p_index); Va = va_table[tlId][size][desId]; R = rewardFunction(tl_new, pos_new, posMovs); newQvalue += P.getValue() *(((float)R) + gamma * Va); } catch (Exception e) { System.out.println("Error in recalc Q'"); } } } try { qa_table[tl.getId()][pos][destination.getId()][light?green_index:red_index] = newQvalue; } catch (Exception e) { System.out.println("ERROR, Zwaluw is not found"); } }
private Graph condense(Graph mimStructure, Graph mimbuildStructure) { // System.out.println("Uncondensed: " + mimbuildStructure); Map<Node, Node> substitutions = new HashMap<Node, Node>(); for (Node node : mimbuildStructure.getNodes()) { for (Node _node : mimStructure.getNodes()) { if (node.getName().startsWith(_node.getName())) { substitutions.put(node, _node); break; } substitutions.put(node, node); } } HashSet<Node> nodes = new HashSet<Node>(substitutions.values()); Graph graph = new EdgeListGraph(new ArrayList<Node>(nodes)); for (Edge edge : mimbuildStructure.getEdges()) { Node node1 = substitutions.get(edge.getNode1()); Node node2 = substitutions.get(edge.getNode2()); if (node1 == node2) continue; if (graph.isAdjacentTo(node1, node2)) continue; graph.addEdge(new Edge(node1, node2, edge.getEndpoint1(), edge.getEndpoint2())); } // System.out.println("Condensed: " + graph); return graph; }
private static Command parseCommand(Node n) { NamedNodeMap atts = n.getAttributes(); String name = atts.getNamedItem("name").getNodeValue(); String desc = atts.getNamedItem("description").getNodeValue(); String command = atts.getNamedItem("command").getNodeValue(); Command com = new Command(name, desc, command); NodeList children = n.getChildNodes(); for (int i = 0; i < children.getLength(); i++) { Node child = children.item(i); if (!child.getNodeName().equals("Argument")) continue; NamedNodeMap childAtts = child.getAttributes(); String childName = childAtts.getNamedItem("name").getNodeValue(); String childDesc = childAtts.getNamedItem("description").getNodeValue(); String childVal = ""; if (childAtts.getNamedItem("default") != null) childVal = childAtts.getNamedItem("default").getNodeValue(); Argument arg = new Argument(childName, childDesc, childVal); com.addArgument(arg); } return com; }
private List<String> getNames(List<Node> nodes) { List<String> names = new ArrayList<String>(); for (Node node : nodes) { names.add(node.getName()); } return names; }
public void PreOrder(Node localRoot) { if (localRoot != null) { System.out.println(localRoot.getItem()); PreOrder(localRoot.getLeft()); PreOrder(localRoot.getRight()); } }
public static void main(String args[]) { String str = "bbb0www"; // "087465132"; 054832761 // Initial Board State as a String with 0 as the // Blank Space Node top = new Node(); Node node = new Node(); System.out.println("Start state: " + str); /*for(int i=0;i<str.length();i++){ if(i%3==0){ System.out.println(""); } System.out.print(str.charAt(i)+"\t"); }*/ SlidingTileDFS e = new SlidingTileDFS(); node.setState(str); node.setParent(null); e.add(node, 0); // e.s.push(str); while (!(e.s.empty())) { top = e.s.pop(); // node.setState(top); // node.setParent(null); e.left(top); // Move the blank space up and add new state to queue e.leftjump1(top); e.leftjump2(top); e.right(top); // Move the blank space down e.rightjump1(top); // Move left e.rightjump2(top); // Move right and remove the current node from Queue } System.out.println("Solution doesn't exist"); }
/** * Reads in a decision stored in XML. * * @param decN - the XML element. */ public void fromXML(Element decN) { this.fromXML = true; RationaleDB db = RationaleDB.getHandle(); String rid = decN.getAttribute("rid"); id = Integer.parseInt(rid.substring(2)); name = decN.getAttribute("name"); type = DecisionType.fromString(decN.getAttribute("type")); devPhase = Phase.fromString(decN.getAttribute("phase")); status = DecisionStatus.fromString(decN.getAttribute("status")); Node child = decN.getFirstChild(); importHelper(child); Node nextNode = child.getNextSibling(); while (nextNode != null) { importHelper(nextNode); nextNode = nextNode.getNextSibling(); } db.addPatternDecisionFromXML(this); }
public void rn() throws IOException { List<RoadLink> links = loadToDatabase("/Users/duduba/gj.mif", "/Users/duduba/gj.mid", false); GraphDatabaseService graphDb = neo.getDb(); Index<Node> nodeIndex = neo.getNodeIndex(); for (RoadLink link : links) { Transaction tx = graphDb.beginTx(); try { Node fromNode = nodeIndex.get("id", link.fromNode).getSingle(); if (fromNode == null) { fromNode = graphDb.createNode(); fromNode.setProperty("id", link.fromNode); nodeIndex.add(fromNode, "id", link.fromNode); } Node toNode = nodeIndex.get("id", link.toNode).getSingle(); if (toNode == null) { toNode = graphDb.createNode(); toNode.setProperty("id", link.toNode); nodeIndex.add(toNode, "id", link.toNode); } Relationship r = fromNode.createRelationshipTo(toNode, Neo.RelTypes.TO); r.setProperty("no", link.no); r.setProperty("name", link.name); tx.success(); } finally { tx.finish(); } } logger.debug("haha, it's ok!"); }
private void calculateArrowsForward(Node x, Node y, Graph graph) { clearArrow(x, y); if (!knowledgeEmpty()) { if (getKnowledge().isForbidden(x.getName(), y.getName())) { return; } } List<Node> naYX = getNaYX(x, y, graph); List<Node> t = getTNeighbors(x, y, graph); DepthChoiceGenerator gen = new DepthChoiceGenerator(t.size(), t.size()); int[] choice; while ((choice = gen.next()) != null) { List<Node> s = GraphUtils.asList(choice, t); if (!knowledgeEmpty()) { if (!validSetByKnowledge(y, s)) { continue; } } double bump = insertEval(x, y, s, naYX, graph); if (bump > 0.0) { Arrow arrow = new Arrow(bump, x, y, s, naYX); sortedArrows.add(arrow); addLookupArrow(x, y, arrow); } } }
/** {@inheritDoc} */ public JCRNodeWrapper getFrozenVersionAsRegular(Node objectNode, JCRStoreProvider provider) throws RepositoryException { try { VersionHistory vh = objectNode .getSession() .getWorkspace() .getVersionManager() .getVersionHistory(objectNode.getPath()); Version v = null; if (versionLabel != null) { v = JCRVersionService.findVersionByLabel(vh, versionLabel); } if (v == null && versionDate != null) { v = JCRVersionService.findClosestVersion(vh, versionDate); } if (v == null) { throw new PathNotFoundException(); } Node frozen = v.getNode(Constants.JCR_FROZENNODE); return provider.getNodeWrapper(frozen, this); } catch (UnsupportedRepositoryOperationException e) { if (getVersionDate() == null && getVersionLabel() == null) { logger.error("Error while retrieving frozen version", e); } } return null; }
/** * This will set initial places for the x coord of the nodes. * * @param start The `number for the first group to start on (I think). */ private void xPlacer(int start) { // this can be one of a few x_placers (the first) // it will work by placing 1 space inbetween each node // ie the first at 0 the second at 1 and so on // then it will add to this value the place of the parent // node - half of the size // i will break this up into several functions // first the gap setter; // then the shifter // it will require a vector shift function added to the node class // i will write an additional shifter for the untangler // for its particular situation Node r; Edge e; if (m_groupNum > 0) { m_groups[0].m_p.setCenter(0); for (int noa = start; noa < m_groupNum; noa++) { int nob, alter = 0; double c = m_groups[noa].m_gap; r = m_groups[noa].m_p; for (nob = 0; (e = r.getChild(nob)) != null; nob++) { if (e.getTarget().getParent(0) == e) { e.getTarget().setCenter(nob * c); } else { alter++; } } m_groups[noa].m_size = (nob - 1 - alter) * c; xShift(noa); } } }
public boolean addWord(String word) { if (word == null) { return false; } Node curNode = firstNode; for (int i = 0; i < word.length(); i++) { if (curNode.child == null) { curNode.child = new Node(word.charAt(i)); curNode = curNode.child; // System.out.println(curNode.data); } else { curNode = curNode.child; // System.out.println(curNode.data); while (curNode.data != word.charAt(i)) { if (curNode.sibling == null) { curNode.sibling = new Node(word.charAt(i)); curNode = curNode.sibling; // System.out.println(curNode.data+"Sibling"); } else { curNode = curNode.sibling; // System.out.println(curNode.data); } } } } curNode.child = new Node(endChar); curNode = curNode.child; // System.out.println(curNode.data); numWords++; return true; }
Node ceilingNode(double key) { for (; ; ) { Node b = skipListMap.findGrandPredecessor(key, refCntCallback); if (b == null) b = head; if (b != head && key <= b.last()) { return b; } assert b == head || b.last() < key; Node n = safeNext(b); release(b); if (n == null) { return null; } else if (key <= n.last()) { return n; } Node f = safeNext(n); release(n); if (f == null) { return null; } else { if (isInconsistentNextNode(f, key)) { release(f); continue; } return f; } } }