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

overflowdb.util.DummyEdgeIterator Maven / Gradle / Ivy

There is a newer version: 1.173
Show newest version
package overflowdb.util;

import overflowdb.Direction;
import overflowdb.Edge;
import overflowdb.NodeRef;

import java.util.Iterator;
import java.util.NoSuchElementException;

public class DummyEdgeIterator implements Iterator {
  private final Object[] array;
  private int current;
  private final int begin;
  private final int exclusiveEnd;
  private final int strideSize;
  private final Direction direction;
  private final String label;
  private final NodeRef thisRef;

  /**
   * Used for peeking forward, and also handle a benign race condition: the given `array` can be modified from the
   * outside, e.g. if an adjacent node or edge is removed after this Iterator was created. That's ok, but we want to at
   * least guarantee correct Iterator semantics, i.e. if `.hasNext` returned `true`, then `.next()` should never be null
   * or throw an exception.
   * */
  private Edge nextCached;

  public DummyEdgeIterator(Object[] array, int begin, int exclusiveEnd, int strideSize,
                           Direction direction, String label, NodeRef thisRef) {
    this.array = array;
    this.begin = begin;
    this.current = begin;
    this.exclusiveEnd = exclusiveEnd;
    this.strideSize = strideSize;
    this.direction = direction;
    this.label = label;
    this.thisRef = thisRef;
  }

  @Override
  public final boolean hasNext() {
    return peekNext() != null;
  }

  private Edge peekNext() {
    if (nextCached != null)
      return nextCached;

    /* there may be holes, e.g. if an edge was removed */
    while (current < exclusiveEnd && array[current] == null) {
      current += strideSize;
    }

    if (current < exclusiveEnd) {
      nextCached = readNext();
      current += strideSize;
      return peekNext();
    }

    // we've reached the end
    return null;
  }

  private Edge readNext() {
    NodeRef otherRef = (NodeRef) array[current];
    Edge dummyEdge;
    if (direction == Direction.OUT) {
      dummyEdge = thisRef.get().instantiateDummyEdge(label, thisRef, otherRef);
      dummyEdge.setOutBlockOffset(current - begin);
    } else {
      dummyEdge = thisRef.get().instantiateDummyEdge(label, otherRef, thisRef);
      dummyEdge.setInBlockOffset(current - begin);
    }
    return dummyEdge;
  }

  @Override
  public Edge next() {
    if (hasNext()) {
      Edge ret = peekNext();
      nextCached = null;
      return ret;
    } else {
      throw new NoSuchElementException();
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy