All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ibm.wala.util.graph.impl.DelegatingNumberedNodeManager Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2002 - 2006 IBM Corporation.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 */
package com.ibm.wala.util.graph.impl;

import static com.ibm.wala.util.nullability.NullabilityUtil.castToNonNull;

import com.ibm.wala.util.debug.Assertions;
import com.ibm.wala.util.graph.INodeWithNumber;
import com.ibm.wala.util.graph.NumberedNodeManager;
import com.ibm.wala.util.intset.IntSet;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Objects;
import java.util.stream.Stream;
import org.jspecify.annotations.Nullable;

/**
 * Basic implementation of a numbered graph -- this implementation relies on nodes that carry
 * numbers and edges.
 *
 * 

The management of node numbers is a bit fragile, but designed this way for efficiency. Use * this class with care. */ public class DelegatingNumberedNodeManager implements NumberedNodeManager { private final double BUFFER_FACTOR = 1.5; private @Nullable INodeWithNumber[] nodes = new INodeWithNumber[20]; private int maxNumber = -1; private int numberOfNodes = 0; @Override public int getNumber(@Nullable T N) { if (N == null) { throw new IllegalArgumentException("N is null"); } INodeWithNumber n = N; return n.getGraphNodeId(); } @Override @SuppressWarnings("unchecked") public T getNode(int number) { try { return (T) castToNonNull(nodes[number]); } catch (ArrayIndexOutOfBoundsException e) { throw new IllegalArgumentException("Invalid number " + number, e); } } @Override public int getMaxNumber() { return maxNumber; } /** * @see com.ibm.wala.util.graph.Graph#iterator() */ @Override @SuppressWarnings("unused") public Iterator iterator() { final @Nullable INodeWithNumber[] arr = nodes; return new Iterator() { int nextCounter = -1; { advance(); } void advance() { for (int i = nextCounter + 1; i < arr.length; i++) { if (arr[i] != null) { nextCounter = i; return; } } nextCounter = -1; } @Override public boolean hasNext() { return nextCounter != -1; } @Override @SuppressWarnings("unchecked") public @Nullable T next() { if (hasNext()) { int r = nextCounter; advance(); return (T) arr[r]; } else { return null; } } @Override public void remove() { Assertions.UNREACHABLE(); } }; } @SuppressWarnings("unchecked") @Override public Stream stream() { return Arrays.stream(nodes).filter(Objects::nonNull).map(node -> (T) node); } /** * @see com.ibm.wala.util.graph.Graph#getNumberOfNodes() */ @Override public int getNumberOfNodes() { return numberOfNodes; } /** * If N.getNumber() == -1, then set N.number and insert this node in the graph. Use with extreme * care. * * @see com.ibm.wala.util.graph.NodeManager#addNode(java.lang.Object) * @throws IllegalArgumentException if n is null */ @Override public void addNode(T n) { if (n == null) { throw new IllegalArgumentException("n is null"); } INodeWithNumber N = n; int number = N.getGraphNodeId(); if (number == -1) { maxNumber++; N.setGraphNodeId(maxNumber); number = maxNumber; } else { if (number > maxNumber) { maxNumber = number; } } ensureCapacity(number); if (nodes[number] != null && nodes[number] != N) { Assertions.UNREACHABLE("number: " + number + " N: " + N + " nodes[number]: " + nodes[number]); } nodes[number] = N; numberOfNodes++; } private void ensureCapacity(int number) { if (nodes.length < number + 1) { int newLength = (int) ((number + 1) * BUFFER_FACTOR); nodes = Arrays.copyOf(nodes, newLength); } } /** * @see com.ibm.wala.util.graph.NodeManager#removeNode(Object) */ @Override public void removeNode(T n) { if (n == null) { throw new IllegalArgumentException("n is null"); } INodeWithNumber N = n; int number = N.getGraphNodeId(); if (number == -1) { throw new IllegalArgumentException("Cannot remove node, not in graph"); } if (nodes[number] != null) { nodes[number] = null; numberOfNodes--; } } @Override public String toString() { StringBuilder result = new StringBuilder("Nodes:\n"); for (int i = 0; i <= maxNumber; i++) { result.append(i).append(' '); if (nodes[i] != null) { result.append(nodes[i].toString()); } result.append('\n'); } return result.toString(); } /** * @see com.ibm.wala.util.graph.NodeManager#containsNode(Object) */ @Override public boolean containsNode(@Nullable T n) { if (n == null) { throw new IllegalArgumentException("n is null"); } INodeWithNumber N = n; int number = N.getGraphNodeId(); if (number == -1) { return false; } if (number >= nodes.length) { throw new IllegalArgumentException( "node already has a graph node id, but is not registered there in this graph (number too big)\n" + "this graph implementation is fragile and won't support this kind of test\n" + n.getClass() + " : " + n); } if (nodes[number] != N) { throw new IllegalArgumentException( "node already has a graph node id, but is not registered there in this graph\n" + "this graph implementation is fragile and won't support this kind of test\n" + n.getClass() + " : " + n); } return true; // return (nodes[number] == N); } @Override public Iterator iterateNodes(IntSet s) { return new NumberedNodeIterator<>(s, this); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy