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

com.tinkerpop.gremlin.hadoop.structure.io.kryo.VertexStreamIterator Maven / Gradle / Ivy

The newest version!
package com.tinkerpop.gremlin.hadoop.structure.io.kryo;

import com.tinkerpop.gremlin.hadoop.structure.io.VertexWritable;
import com.tinkerpop.gremlin.structure.Direction;
import com.tinkerpop.gremlin.structure.Edge;
import com.tinkerpop.gremlin.structure.Graph;
import com.tinkerpop.gremlin.structure.Vertex;
import com.tinkerpop.gremlin.structure.io.kryo.KryoReader;
import com.tinkerpop.gremlin.structure.util.detached.DetachedEdge;
import com.tinkerpop.gremlin.structure.util.detached.DetachedVertex;
import com.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.function.Function;

/**
 * @author Marko A. Rodriguez (http://markorodriguez.com)
 */
public class VertexStreamIterator implements Iterator {

    // this is VertexTerminator's long terminal 4185403236219066774L as an array of positive int's
    private static final int[] TERMINATOR = new int[]{58, 21, 138, 17, 112, 155, 153, 150};

    private static int BUFLEN = TERMINATOR.length;

    private final InputStream inputStream;
    private static final KryoReader KRYO_READER = KryoReader.build().create();
    private final ByteArrayOutputStream output = new ByteArrayOutputStream();
    private final int[] buffer = new int[BUFLEN];

    private int len;
    private int currentByte;
    private Vertex currentVertex;
    private final long maxLength;
    private long currentLength = 0;

    public VertexStreamIterator(final InputStream inputStream, final long maxLength) {
        this.inputStream = inputStream;
        this.maxLength = maxLength;
    }

    public float getProgress() {
        if (0 == this.currentLength || 0 == this.maxLength)
            return 0.0f;
        else if (this.currentLength >= this.maxLength || this.maxLength == Long.MAX_VALUE)
            return 1.0f;
        else
            return (float) this.currentLength / (float) this.maxLength;

    }

    @Override
    public boolean hasNext() {
        if (this.currentLength >= this.maxLength) // gone beyond the split boundary
            return false;
        if (null != this.currentVertex)
            return true;
        else if (-1 == this.currentByte)
            return false;
        else {
            try {
                this.currentVertex = advanceToNextVertex();
                return null != this.currentVertex;
            } catch (final IOException e) {
                throw new IllegalStateException(e.getMessage(), e);
            }
        }
    }

    @Override
    public VertexWritable next() {
        try {
            if (null == this.currentVertex) {
                if (this.hasNext())
                    return new VertexWritable(this.currentVertex);
                else
                    throw new IllegalStateException("There are no more vertices in this split");
            } else
                return new VertexWritable(this.currentVertex);
        } finally {
            this.currentVertex = null;
            this.len = 0;
            this.output.reset();
        }
    }

    private final Vertex advanceToNextVertex() throws IOException {
        while (true) {
            this.currentByte = this.inputStream.read();
            this.currentLength++;
            if (-1 == this.currentByte) {
                if (this.len > 0) {
                    throw new IllegalStateException("Remainder of stream exhausted without matching a vertex");
                } else {
                    return null;
                }
            }

            if (this.len >= BUFLEN)
                this.output.write(this.buffer[this.len % BUFLEN]);

            this.buffer[this.len % BUFLEN] = this.currentByte;
            this.len++;

            if (this.len > BUFLEN) {
                boolean terminated = true;
                for (int i = 0; i < BUFLEN; i++) {
                    if (this.buffer[(this.len + i) % BUFLEN] != TERMINATOR[i]) {
                        terminated = false;
                        break;
                    }
                }

                if (terminated) {
                    final Graph gLocal = TinkerGraph.open();
                    final Function vertexMaker = detachedVertex -> DetachedVertex.addTo(gLocal, detachedVertex);
                    final Function edgeMaker = detachedEdge -> DetachedEdge.addTo(gLocal, detachedEdge);
                    try (InputStream in = new ByteArrayInputStream(this.output.toByteArray())) {
                        return KRYO_READER.readVertex(in, Direction.BOTH, vertexMaker, edgeMaker);
                    }
                }
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy