Package com.thinkaurelius.faunus

Source Code of com.thinkaurelius.faunus.FaunusVertex$EdgeList

package com.thinkaurelius.faunus;

import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.VertexQuery;
import com.tinkerpop.blueprints.util.DefaultVertexQuery;
import com.tinkerpop.blueprints.util.ExceptionFactory;
import com.tinkerpop.blueprints.util.StringFactory;
import org.apache.hadoop.io.WritableUtils;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static com.tinkerpop.blueprints.Direction.*;

/**
* @author Marko A. Rodriguez (http://markorodriguez.com)
*/
public class FaunusVertex extends FaunusElement implements Vertex {

    private Map<String, List<Edge>> outEdges = new HashMap<String, List<Edge>>();
    private Map<String, List<Edge>> inEdges = new HashMap<String, List<Edge>>();

    public FaunusVertex() {
        super(-1l);
    }

    public FaunusVertex(final boolean enablePaths) {
        super(-1l);
        this.enablePath(enablePaths);
    }

    public FaunusVertex(final long id) {
        super(id);
    }

    public FaunusVertex(final DataInput in) throws IOException {
        super(-1l);
        this.readFields(in);
    }

    public FaunusVertex reuse(final long id) {
        super.reuse(id);
        this.outEdges.clear();
        this.inEdges.clear();
        return this;
    }

    public void enablePath(final boolean enablePath) {
        super.enablePath(enablePath);
        if (this.pathEnabled) {
            for (final Edge edge : this.getEdges(BOTH)) {
                ((FaunusEdge) edge).enablePath(true);
            }
        }
    }

    public void addAll(final FaunusVertex vertex) {
        this.id = vertex.getIdAsLong();
        this.properties = vertex.getProperties();
        this.getPaths(vertex, false);
        this.addEdges(BOTH, vertex);
    }

    public VertexQuery query() {
        return new DefaultVertexQuery(this);
    }

    public Set<String> getEdgeLabels(final Direction direction) {
        if (direction.equals(Direction.OUT))
            return this.outEdges.keySet();
        else if (direction.equals(Direction.IN))
            return this.inEdges.keySet();
        else {
            final Set<String> labels = new HashSet<String>();
            labels.addAll(this.outEdges.keySet());
            labels.addAll(this.inEdges.keySet());
            return labels;
        }
    }

    public Iterable<Vertex> getVertices(final Direction direction, final String... labels) {
        return new Iterable<Vertex>() {
            public Iterator<Vertex> iterator() {
                return new Iterator<Vertex>() {
                    final Iterator<Edge> edges = getEdges(direction, labels).iterator();
                    final Direction opposite = direction.opposite();

                    public void remove() {
                        throw new UnsupportedOperationException();
                    }

                    public boolean hasNext() {
                        return this.edges.hasNext();
                    }

                    public Vertex next() {
                        return this.edges.next().getVertex(this.opposite);
                    }
                };
            }
        };
    }

    public Iterable<Edge> getEdges(final Direction direction, final String... labels) {
        final List<List<Edge>> edgeLists = new ArrayList<List<Edge>>();

        if (direction.equals(OUT) || direction.equals(BOTH)) {
            if (null == labels || labels.length == 0) {
                for (final List<Edge> temp : this.outEdges.values()) {
                    edgeLists.add(temp);
                }
            } else {
                for (final String label : labels) {
                    final List<Edge> temp = this.outEdges.get(label);
                    if (null != temp)
                        edgeLists.add(temp);
                }
            }

        }

        if (direction.equals(IN) || direction.equals(BOTH)) {
            if (null == labels || labels.length == 0) {
                for (final List<Edge> temp : this.inEdges.values()) {
                    edgeLists.add(temp);
                }
            } else {
                for (final String label : labels) {
                    final List<Edge> temp = this.inEdges.get(label);
                    if (null != temp)
                        edgeLists.add(temp);
                }
            }

        }
        return new EdgeList(edgeLists);
    }

    private void addEdges(final Direction direction, final String label, final List<FaunusEdge> edges) {
        List<Edge> list;
        if (direction.equals(OUT))
            list = this.outEdges.get(label);
        else if (direction.equals(IN))
            list = this.inEdges.get(label);
        else
            throw ExceptionFactory.bothIsNotSupported();

        if (null == list) {
            list = new ArrayList<Edge>();
            if (direction.equals(OUT))
                this.outEdges.put(label, list);
            else
                this.inEdges.put(label, list);
        }
        list.addAll(edges);
    }

    public void addEdges(final Direction direction, final FaunusVertex vertex) {
        if (direction.equals(OUT) || direction.equals(BOTH)) {
            for (final String label : vertex.getEdgeLabels(OUT)) {
                this.addEdges(OUT, label, (List) vertex.getEdges(OUT, label));
            }
        }

        if (direction.equals(IN) || direction.equals(BOTH)) {
            for (final String label : vertex.getEdgeLabels(IN)) {
                this.addEdges(IN, label, (List) vertex.getEdges(IN, label));
            }
        }
    }

    public Edge addEdge(final String label, final Vertex inVertex) {
        return this.addEdge(Direction.OUT, new FaunusEdge(this.getIdAsLong(), ((FaunusVertex) inVertex).getIdAsLong(), label));
    }

    public Edge addEdge(final Direction direction, final String label, final long otherVertexId) {
        if (direction.equals(Direction.OUT))
            return this.addEdge(Direction.OUT, new FaunusEdge(this.id, otherVertexId, label));
        else if (direction.equals(Direction.IN))
            return this.addEdge(Direction.IN, new FaunusEdge(otherVertexId, this.id, label));
        else
            throw ExceptionFactory.bothIsNotSupported();
    }

    public FaunusEdge addEdge(final Direction direction, final FaunusEdge edge) {
        if (OUT.equals(direction)) {
            List<Edge> edges = this.outEdges.get(edge.getLabel());
            if (null == edges) {
                edges = new ArrayList<Edge>();
                this.outEdges.put(edge.getLabel(), edges);
            }
            edges.add(edge);
        } else if (IN.equals(direction)) {
            List<Edge> edges = this.inEdges.get(edge.getLabel());
            if (null == edges) {
                edges = new ArrayList<Edge>();
                this.inEdges.put(edge.getLabel(), edges);
            }
            edges.add(edge);
        } else
            throw ExceptionFactory.bothIsNotSupported();

        return edge;
    }

    public void removeEdgesToFrom(final Set<Long> ids) {
        Iterator<Edge> itty = this.getEdges(OUT).iterator();
        while (itty.hasNext()) {
            final Long id = (Long) itty.next().getVertex(IN).getId();
            if (ids.contains(id))
                itty.remove();
        }

        itty = this.getEdges(IN).iterator();
        while (itty.hasNext()) {
            final Long id = (Long) itty.next().getVertex(OUT).getId();
            if (ids.contains(id))
                itty.remove();
        }
    }

    public void removeEdges(final Tokens.Action action, final Direction direction, final String... labels) {
        if (action.equals(Tokens.Action.KEEP)) {
            final Set<String> keep = new HashSet<String>(Arrays.asList(labels));
            if (direction.equals(BOTH) || direction.equals(OUT)) {
                if (labels.length > 0) {
                    for (final String label : new ArrayList<String>(this.outEdges.keySet())) {
                        if (!keep.contains(label))
                            this.outEdges.remove(label);
                    }
                } else if (direction.equals(OUT))
                    this.inEdges.clear();
            }

            if (direction.equals(BOTH) || direction.equals(IN)) {
                if (labels.length > 0) {
                    for (final String label : new ArrayList<String>(this.inEdges.keySet())) {
                        if (!keep.contains(label))
                            this.inEdges.remove(label);
                    }
                } else if (direction.equals(IN))
                    this.outEdges.clear();
            }
        } else {
            if (direction.equals(BOTH) || direction.equals(OUT)) {
                if (labels.length == 0) {
                    this.outEdges.clear();
                } else {
                    for (final String label : labels) {
                        this.outEdges.remove(label);
                    }
                }
            }

            if (direction.equals(BOTH) || direction.equals(IN)) {
                if (labels.length == 0) {
                    this.inEdges.clear();
                } else {
                    for (final String label : labels) {
                        this.inEdges.remove(label);
                    }
                }
            }
        }
    }

    public void write(final DataOutput out) throws IOException {
        super.write(out);
        EdgeMap.write((Map) this.inEdges, out, Direction.OUT);
        EdgeMap.write((Map) this.outEdges, out, Direction.IN);
    }

    public void readFields(final DataInput in) throws IOException {
        super.readFields(in);
        this.inEdges = (Map) EdgeMap.readFields(in, Direction.OUT, this.id);
        this.outEdges = (Map) EdgeMap.readFields(in, Direction.IN, this.id);
    }

    public String toString() {
        return StringFactory.vertexString(this);
    }

    private class EdgeList extends AbstractList<Edge> {

        final List<List<Edge>> edges;

        int size;

        public EdgeList(final List<List<Edge>> edgeLists) {
            this.edges = edgeLists;
            int counter = 0;
            for (final List<Edge> temp : this.edges) {
                counter = counter + temp.size();
            }
            this.size = counter;
        }

        public int size() {
            return this.size;
        }

        public Edge get(final int index) {
            int lowIndex = 0;
            int highIndex = 0;
            for (final List<Edge> temp : this.edges) {
                highIndex = highIndex + temp.size();
                if (index < highIndex) {
                    return temp.get(index - lowIndex);
                }
                lowIndex = lowIndex + temp.size();
            }
            throw new ArrayIndexOutOfBoundsException(index);
        }

        private void removeList(final int index) {
            int lowIndex = 0;
            int highIndex = 0;
            for (final List<Edge> temp : this.edges) {
                highIndex = highIndex + temp.size();
                if (index < highIndex) {
                    temp.remove(index - lowIndex);
                    return;
                }
                lowIndex = lowIndex + temp.size();

            }
            throw new ArrayIndexOutOfBoundsException(index);
        }

        public Iterator<Edge> iterator() {
            return new Iterator<Edge>() {
                private int index = 0;

                @Override
                public boolean hasNext() {
                    return this.index < size;
                }

                @Override
                public Edge next() {
                    return get(this.index++);
                }

                @Override
                public void remove() {
                    removeList(--this.index);
                    size--;
                }
            };
        }

    }

    private static class EdgeMap {

        public static Map<String, List<FaunusEdge>> readFields(final DataInput in, final Direction idToRead, final long otherId) throws IOException {
            final Map<String, List<FaunusEdge>> edges = new HashMap<String, List<FaunusEdge>>();
            int edgeTypes = WritableUtils.readVInt(in);
            for (int i = 0; i < edgeTypes; i++) {
                final String label = in.readUTF();
                final int size = WritableUtils.readVInt(in);
                final List<FaunusEdge> temp = new ArrayList<FaunusEdge>(size);
                for (int j = 0; j < size; j++) {
                    final FaunusEdge edge = new FaunusEdge();
                    edge.readFieldsCompressed(in, idToRead);
                    edge.setLabel(label);
                    if (idToRead.equals(Direction.OUT))
                        edge.inVertex = otherId;
                    else
                        edge.outVertex = otherId;
                    temp.add(edge);
                }
                edges.put(label, temp);
            }
            return edges;
        }

        public static void write(final Map<String, List<FaunusEdge>> edges, final DataOutput out, final Direction idToWrite) throws IOException {
            WritableUtils.writeVInt(out, edges.size());
            for (final Map.Entry<String, List<FaunusEdge>> entry : edges.entrySet()) {
                out.writeUTF(entry.getKey());
                WritableUtils.writeVInt(out, entry.getValue().size());
                for (final FaunusEdge edge : entry.getValue()) {
                    edge.writeCompressed(out, idToWrite);
                }
            }
        }
    }

    public static class MicroVertex extends MicroElement {

        private static final String V1 = "v[";
        private static final String V2 = "]";

        public MicroVertex(final long id) {
            super(id);
        }

        public String toString() {
            return V1 + this.id + V2;
        }
    }
}
TOP

Related Classes of com.thinkaurelius.faunus.FaunusVertex$EdgeList

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.