Merge blueprints-ramcloud-graph into ONOS code
diff --git a/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudEdge.java b/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudEdge.java
new file mode 100644
index 0000000..d61c2a4
--- /dev/null
+++ b/src/main/java/com/tinkerpop/blueprints/impls/ramcloud/RamCloudEdge.java
@@ -0,0 +1,222 @@
+package com.tinkerpop.blueprints.impls.ramcloud;
+
+import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.Arrays;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.sun.jersey.core.util.Base64;
+import com.tinkerpop.blueprints.Direction;
+import com.tinkerpop.blueprints.Edge;
+import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.blueprints.util.ExceptionFactory;
+import com.tinkerpop.blueprints.impls.ramcloud.PerfMon;
+import edu.stanford.ramcloud.JRamCloud;
+
+public class RamCloudEdge extends RamCloudElement implements Edge {
+
+ private final static Logger log = LoggerFactory.getLogger(RamCloudGraph.class);
+ private RamCloudVertex outVertex;
+ private RamCloudVertex inVertex;
+ private String label;
+ private byte[] rcKey;
+ private RamCloudGraph graph;
+
+ public RamCloudEdge(RamCloudVertex outVertex, RamCloudVertex inVertex, String label, RamCloudGraph graph) {
+ super(edgeToRcKey(outVertex, inVertex, label), graph.edgePropTableId, graph);
+
+ this.outVertex = outVertex;
+ this.inVertex = inVertex;
+ this.label = label;
+ this.rcKey = edgeToRcKey(outVertex, inVertex, label);
+ this.graph = graph;
+ }
+
+ public RamCloudEdge(byte[] rcKey, RamCloudGraph graph) {
+ super(rcKey, graph.edgePropTableId, graph);
+
+ ByteBuffer edgeId = ByteBuffer.wrap(rcKey).order(ByteOrder.LITTLE_ENDIAN);
+ outVertex = new RamCloudVertex(edgeId.getLong(), graph);
+ inVertex = new RamCloudVertex(edgeId.getLong(), graph);
+ label = new String(rcKey, 16, rcKey.length - 16);
+
+ this.rcKey = rcKey;
+ this.graph = graph;
+ }
+
+ private static byte[] edgeToRcKey(RamCloudVertex outVertex, RamCloudVertex inVertex, String label) {
+ return ByteBuffer.allocate(16 + label.length()).order(ByteOrder.LITTLE_ENDIAN).putLong((Long) outVertex.getId()).putLong((Long) inVertex.getId()).put(label.getBytes()).array();
+ }
+
+ @Override
+ public Vertex getVertex(Direction direction) throws IllegalArgumentException {
+ if (direction.equals(Direction.OUT)) {
+ return outVertex;
+ } else if (direction.equals(Direction.IN)) {
+ return inVertex;
+ } else {
+ throw ExceptionFactory.bothIsNotSupported();
+ }
+ }
+
+ @Override
+ public String getLabel() {
+ return label;
+ }
+
+ public boolean isLoop() {
+ return outVertex.equals(inVertex);
+ }
+
+ public Vertex getNeighbor(Vertex vertex) {
+ if (outVertex.equals(vertex)) {
+ return inVertex;
+ } else if (inVertex.equals(vertex)) {
+ return outVertex;
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public void remove() {
+ if (isLoop()) {
+ outVertex.removeEdgeFromAdjList(this);
+ } else {
+ outVertex.removeEdgeFromAdjList(this);
+ inVertex.removeEdgeFromAdjList(this);
+ }
+
+ super.remove();
+ }
+
+ void removeProperties() {
+ super.remove();
+ }
+
+ @Override
+ public Object getId() {
+ return new String(Base64.encode(rcKey));
+ }
+
+ public boolean exists() {
+ boolean edgePropTableEntryExists;
+ boolean outVertexEntryExists;
+ boolean inVertexEntryExists;
+
+ PerfMon pm = PerfMon.getInstance();
+ try {
+ JRamCloud edgeTable = graph.getRcClient();
+ pm.read_start("RamCloudEdge exists()");
+ edgeTable.read(graph.edgePropTableId, rcKey);
+ pm.read_end("RamCloudEdge exists()");
+ edgePropTableEntryExists = true;
+ } catch (Exception e) {
+ pm.read_end("RamCloudEdge exists()");
+ // Edge property table entry does not exist
+ edgePropTableEntryExists = false;
+ }
+
+ outVertexEntryExists = outVertex.getEdgeSet().contains(this);
+
+ if (!outVertex.equals(inVertex)) {
+ inVertexEntryExists = inVertex.getEdgeSet().contains(this);
+ } else {
+ inVertexEntryExists = outVertexEntryExists;
+ }
+
+ if (edgePropTableEntryExists && outVertexEntryExists && inVertexEntryExists) {
+ return true;
+ } else if (!edgePropTableEntryExists && !outVertexEntryExists && !inVertexEntryExists) {
+ return false;
+ } else {
+ log.warn("{}: Detected RamCloudGraph inconsistency: edgePropTableEntryExists={}, outVertexEntryExists={}, inVertexEntryExists={}.", this, edgePropTableEntryExists, outVertexEntryExists, inVertexEntryExists);
+ return true;
+ }
+ }
+
+ public void create() throws Exception {
+ // TODO: Existence check costs extra (presently 3 reads), could use option to turn on/off
+ if (!exists()) {
+ PerfMon pm = PerfMon.getInstance();
+ // create edge property table
+ JRamCloud edgeTable = graph.getRcClient();
+ pm.write_start("RamCloudEdge create()");
+ edgeTable.write(graph.edgePropTableId, rcKey, ByteBuffer.allocate(0).array());
+ pm.write_end("RamCloudEdge create()");
+
+ boolean addSucc = outVertex.addEdgeToAdjList(this);
+ if ( !addSucc ) {
+ edgeTable.remove(graph.edgePropTableId, rcKey);
+ throw ExceptionFactory.edgeWithIdAlreadyExist(rcKey);
+ }
+ if (!isLoop()) {
+ addSucc = inVertex.addEdgeToAdjList(this);
+ if ( !addSucc ) {
+ edgeTable.remove(graph.edgePropTableId, rcKey);
+ outVertex.removeEdgeFromAdjList(this);
+ throw ExceptionFactory.edgeWithIdAlreadyExist(rcKey);
+ }
+ }
+ } else {
+ throw ExceptionFactory.edgeWithIdAlreadyExist(rcKey);
+ }
+ }
+
+ public static boolean isValidEdgeId(byte[] id) {
+ if (id == null) {
+ return false;
+ }
+ if (id.length == 0) {
+ return false;
+ }
+
+ ByteBuffer edgeId = ByteBuffer.wrap(id);
+ try {
+ edgeId.getLong();
+ } catch (BufferUnderflowException e) {
+ return false;
+ }
+
+ try {
+ edgeId.getLong();
+ } catch (BufferUnderflowException e) {
+ return false;
+ }
+
+ if (edgeId.remaining() == 0) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return Arrays.hashCode(rcKey);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ RamCloudEdge other = (RamCloudEdge) obj;
+ return Arrays.equals(rcKey, other.rcKey);
+ }
+
+ @Override
+ public String toString() {
+ return "RamCloudEdge [outVertex=" + outVertex + ", inVertex=" + inVertex
+ + ", label=" + label + "]";
+ }
+}