package hdgl.db.store.impl.cache;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import org.apache.hadoop.io.Writable;
import hdgl.db.exception.HdglException;
import hdgl.db.graph.Edge;
import hdgl.db.graph.LabelValue;
import hdgl.db.graph.Vertex;
import hdgl.db.store.GraphStore;
import hdgl.util.IterableHelper;
import hdgl.util.NetHelper;
public class MemoryGraphStore implements GraphStore {
Map<Long,byte[]> vdata = new HashMap<Long, byte[]>();
Map<Long,byte[]> edata = new HashMap<Long, byte[]>();
public static void writeVertex(Vertex v, DataOutput out) throws IOException{
out.writeLong(v.getId());
out.writeUTF(v.getType());
Iterable<Edge> outedges = v.getOutEdges();
out.writeInt(IterableHelper.count(outedges));
for(Edge e:outedges){
out.writeLong(e.getId());
}
Iterable<Edge> inedges = v.getInEdges();
out.writeInt(IterableHelper.count(inedges));
for(Edge e:inedges){
out.writeLong(e.getId());
}
Iterable<LabelValue> labels = v.getLabels();
out.writeInt(IterableHelper.count(labels));
for(LabelValue l:labels){
out.writeUTF(l.getName());
out.writeInt(l.getValue().length);
out.write(l.getValue());
}
}
public static void writeEdge(Edge e, DataOutput out) throws IOException{
out.writeLong(e.getId());
out.writeUTF(e.getType());
out.writeLong(e.getOutVertex().getId());
out.writeLong(e.getInVertex().getId());
Iterable<LabelValue> labels = e.getLabels();
out.writeInt(IterableHelper.count(labels));
for(LabelValue l:labels){
out.writeUTF(l.getName());
out.writeInt(l.getValue().length);
out.write(l.getValue());
}
}
public MemoryVertexImpl getVertex(long id){
try {
return (MemoryVertexImpl) parseVertex(id);
} catch (IOException e) {
throw new HdglException("Unexpected bad format");
}
}
public MemoryEdgeImpl getEdge(long id){
try {
return (MemoryEdgeImpl) parseEdge(id);
} catch (IOException e) {
throw new HdglException("Unexpected bad format");
}
}
public void addVertex(Vertex v){
try{
ByteArrayOutputStream buf = new ByteArrayOutputStream();
if(v instanceof Writable){
((Writable) v).write(new DataOutputStream(buf));
}else{
writeVertex(v, new DataOutputStream(buf));
}
byte[] data = buf.toByteArray();
vdata.put(v.getId(), data);
}catch(IOException ex){
throw new HdglException("unexpected exception", ex);
}
}
public void addEdge(Edge e){
try{
ByteArrayOutputStream buf = new ByteArrayOutputStream();
if(e instanceof Writable){
((Writable) e).write(new DataOutputStream(buf));
}else{
writeEdge(e, new DataOutputStream(buf));
}
byte[] data = buf.toByteArray();
edata.put(e.getId(), data);
}catch(IOException ex){
throw new HdglException("unexpected exception", ex);
}
}
@Override
public InputStream getVertexData(long id) throws IOException {
if(!vdata.containsKey(id)){
throw new HdglException("Bad vertex id: "+id);
}
return new ByteArrayInputStream(vdata.get(id));
}
@Override
public InputStream getEdgeData(long id) throws IOException {
if(!edata.containsKey(id)){
throw new HdglException("Bad edge id: "+id);
}
return new ByteArrayInputStream(edata.get(id));
}
@Override
public Vertex parseVertex(long id) throws IOException {
MemoryVertexImpl v=new MemoryVertexImpl(this);
DataInputStream in=new DataInputStream(getVertexData(id));
v.readFields(in);
in.close();
return v;
}
@Override
public Edge parseEdge(long id) throws IOException {
MemoryEdgeImpl e=new MemoryEdgeImpl(this);
DataInputStream in=new DataInputStream(getEdgeData(id));
e.readFields(in);
in.close();
return e;
}
@Override
public String[] bestPlacesForVertex(long entityId) throws IOException {
return new String[]{NetHelper.getMyHostName()};
}
@Override
public String[] bestPlacesForEdge(long entityId) throws IOException {
return new String[]{NetHelper.getMyHostName()};
}
@Override
public long getVertexCount() throws IOException {
return vdata.size();
}
@Override
public long getVertexCountPerBlock() throws IOException {
return vdata.size();
}
@Override
public long getEdgeCount() throws IOException {
return edata.size();
}
@Override
public long getEdgeCountPerBlock() throws IOException {
return edata.size();
}
@Override
public void close() {
}
}