package org.vertexium.accumulo.iterator; import org.apache.accumulo.core.data.Key; import org.apache.accumulo.core.data.Value; import org.apache.accumulo.core.iterators.IteratorEnvironment; import org.apache.accumulo.core.iterators.SortedKeyValueIterator; import org.apache.hadoop.io.Text; import org.vertexium.accumulo.iterator.model.EdgeInfo; import org.vertexium.accumulo.iterator.model.IteratorFetchHint; import org.vertexium.accumulo.iterator.model.SoftDeleteEdgeInfo; import org.vertexium.accumulo.iterator.model.VertexElementData; import java.util.EnumSet; import java.util.List; public class VertexIterator extends ElementIterator<VertexElementData> { public static final String CF_SIGNAL_STRING = "V"; public static final Text CF_SIGNAL = new Text(CF_SIGNAL_STRING); public static final String CF_OUT_EDGE_STRING = "EOUT"; public static final Text CF_OUT_EDGE = new Text(CF_OUT_EDGE_STRING); public static final String CF_OUT_EDGE_HIDDEN_STRING = "EOUTH"; public static final Text CF_OUT_EDGE_HIDDEN = new Text(CF_OUT_EDGE_HIDDEN_STRING); public static final String CF_OUT_EDGE_SOFT_DELETE_STRING = "EOUTD"; public static final Text CF_OUT_EDGE_SOFT_DELETE = new Text(CF_OUT_EDGE_SOFT_DELETE_STRING); public static final String CF_IN_EDGE_STRING = "EIN"; public static final Text CF_IN_EDGE = new Text(CF_IN_EDGE_STRING); public static final String CF_IN_EDGE_HIDDEN_STRING = "EINH"; public static final Text CF_IN_EDGE_HIDDEN = new Text(CF_IN_EDGE_HIDDEN_STRING); public static final String CF_IN_EDGE_SOFT_DELETE_STRING = "EIND"; public static final Text CF_IN_EDGE_SOFT_DELETE = new Text(CF_IN_EDGE_SOFT_DELETE_STRING); public VertexIterator() { this(IteratorFetchHint.ALL); } public VertexIterator(EnumSet<IteratorFetchHint> fetchHints) { super(null, fetchHints); } public VertexIterator(SortedKeyValueIterator<Key, Value> source, EnumSet<IteratorFetchHint> fetchHints) { super(source, fetchHints); } @Override protected boolean populateElementData(List<Key> keys, List<Value> values) { boolean ret = super.populateElementData(keys, values); if (ret) { removeHiddenAndSoftDeletes(); } return ret; } private void removeHiddenAndSoftDeletes() { if (!getFetchHints().contains(IteratorFetchHint.INCLUDE_HIDDEN)) { for (Text edgeId : this.getElementData().hiddenEdges) { this.getElementData().inEdges.remove(edgeId); this.getElementData().outEdges.remove(edgeId); } } for (SoftDeleteEdgeInfo inSoftDelete : this.getElementData().inSoftDeletes) { EdgeInfo inEdge = this.getElementData().inEdges.get(inSoftDelete.getEdgeId()); if (inEdge != null && inSoftDelete.getTimestamp() >= inEdge.getTimestamp()) { this.getElementData().inEdges.remove(inSoftDelete.getEdgeId()); } } for (SoftDeleteEdgeInfo outSoftDelete : this.getElementData().outSoftDeletes) { EdgeInfo outEdge = this.getElementData().outEdges.get(outSoftDelete.getEdgeId()); if (outEdge != null && outSoftDelete.getTimestamp() >= outEdge.getTimestamp()) { this.getElementData().outEdges.remove(outSoftDelete.getEdgeId()); } } } @Override protected boolean processColumn(Key key, Value value, Text columnFamily, Text columnQualifier) { if (CF_OUT_EDGE.equals(columnFamily)) { Text edgeId = key.getColumnQualifier(); EdgeInfo edgeInfo = EdgeInfo.parse(value, key.getTimestamp()); getElementData().outEdges.add(edgeId, edgeInfo); return true; } if (CF_IN_EDGE.equals(columnFamily)) { Text edgeId = key.getColumnQualifier(); EdgeInfo edgeInfo = EdgeInfo.parse(value, key.getTimestamp()); getElementData().inEdges.add(edgeId, edgeInfo); return true; } if (CF_OUT_EDGE_HIDDEN.equals(columnFamily) || CF_IN_EDGE_HIDDEN.equals(columnFamily)) { Text edgeId = key.getColumnQualifier(); getElementData().hiddenEdges.add(edgeId); return true; } if (CF_IN_EDGE_SOFT_DELETE.equals(columnFamily)) { Text edgeId = key.getColumnQualifier(); getElementData().inSoftDeletes.add(new SoftDeleteEdgeInfo(edgeId, key.getTimestamp())); return true; } if (CF_OUT_EDGE_SOFT_DELETE.equals(columnFamily)) { Text edgeId = key.getColumnQualifier(); getElementData().outSoftDeletes.add(new SoftDeleteEdgeInfo(edgeId, key.getTimestamp())); return true; } return false; } @Override protected Text getVisibilitySignal() { return CF_SIGNAL; } @Override public SortedKeyValueIterator<Key, Value> deepCopy(IteratorEnvironment env) { if (sourceIter != null) { return new VertexIterator(sourceIter.deepCopy(env), getFetchHints()); } return new VertexIterator(getFetchHints()); } @Override protected VertexElementData createElementData() { return new VertexElementData(); } }