package io.hgraphdb.models; import io.hgraphdb.Constants; import io.hgraphdb.HBaseGraph; import io.hgraphdb.HBaseGraphException; import io.hgraphdb.HBaseGraphNotFoundException; import io.hgraphdb.ValueUtils; import io.hgraphdb.mutators.PropertyIncrementer; import io.hgraphdb.mutators.PropertyRemover; import io.hgraphdb.mutators.PropertyWriter; import io.hgraphdb.readers.LoadingElementReader; import org.apache.hadoop.hbase.client.Get; import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.client.Scan; import org.apache.hadoop.hbase.client.Table; import org.apache.hadoop.hbase.filter.BinaryComparator; import org.apache.hadoop.hbase.filter.CompareFilter; import org.apache.hadoop.hbase.filter.FilterList; import org.apache.hadoop.hbase.filter.SingleColumnValueFilter; import org.apache.tinkerpop.gremlin.structure.Element; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.List; import java.util.stream.Collectors; public abstract class ElementModel extends BaseModel { private static final Logger LOGGER = LoggerFactory.getLogger(ElementModel.class); public ElementModel(HBaseGraph graph, Table table) { super(graph, table); } public abstract LoadingElementReader getReader(); /** * Load the element from the backing table. * * @param element The element */ @SuppressWarnings("unchecked") public void load(Element element) { LOGGER.trace("Executing Get, type: {}, id: {}", getClass().getSimpleName(), element.id()); Get get = new Get(ValueUtils.serializeWithSalt(element.id())); try { Result result = table.get(get); getReader().load(element, result); } catch (IOException e) { throw new HBaseGraphException(e); } } /** * Load the elements from the backing table. * * @param elements The elements */ @SuppressWarnings("unchecked") public void load(List<? extends Element> elements) { LOGGER.trace("Executing Batch Get, type: {}", getClass().getSimpleName()); List<Get> gets = elements.stream() .map(e -> new Get(ValueUtils.serializeWithSalt(e.id()))) .collect(Collectors.toList()); try { Result[] results = table.get(gets); for (int i = 0; i < results.length; i++) { try { getReader().load(elements.get(i), results[i]); } catch (HBaseGraphNotFoundException e) { // ignore, the element will not have its properties fully loaded } } } catch (IOException e) { throw new HBaseGraphException(e); } } /** * Delete the property entry from property table. * * @param element The element * @param key The property key */ public PropertyRemover clearProperty(Element element, String key) { return new PropertyRemover(graph, element, key); } /** * Write the given property to the property table. * * @param element The element * @param key The property key * @param value The property value */ public PropertyWriter writeProperty(Element element, String key, Object value) { return new PropertyWriter(graph, element, key, value); } /** * Increment the given property in the property table. * * @param element The element * @param key The property key * @param value The amount to increment */ public PropertyIncrementer incrementProperty(Element element, String key, long value) { return new PropertyIncrementer(graph, element, key, value); } protected Scan getPropertyScan(String label) { Scan scan = new Scan(); SingleColumnValueFilter valueFilter = new SingleColumnValueFilter(Constants.DEFAULT_FAMILY_BYTES, Constants.LABEL_BYTES, CompareFilter.CompareOp.EQUAL, new BinaryComparator(ValueUtils.serialize(label))); valueFilter.setFilterIfMissing(true); scan.setFilter(valueFilter); return scan; } protected Scan getPropertyScan(String label, byte[] key, byte[] val) { Scan scan = new Scan(); SingleColumnValueFilter labelFilter = new SingleColumnValueFilter(Constants.DEFAULT_FAMILY_BYTES, Constants.LABEL_BYTES, CompareFilter.CompareOp.EQUAL, new BinaryComparator(ValueUtils.serialize(label))); labelFilter.setFilterIfMissing(true); SingleColumnValueFilter valueFilter = new SingleColumnValueFilter(Constants.DEFAULT_FAMILY_BYTES, key, CompareFilter.CompareOp.EQUAL, new BinaryComparator(val)); valueFilter.setFilterIfMissing(true); FilterList filterList = new FilterList(labelFilter, valueFilter); scan.setFilter(filterList); return scan; } protected Scan getPropertyScan(String label, byte[] key, byte[] inclusiveFromValue, byte[] exclusiveToValue) { Scan scan = new Scan(); SingleColumnValueFilter labelFilter = new SingleColumnValueFilter(Constants.DEFAULT_FAMILY_BYTES, Constants.LABEL_BYTES, CompareFilter.CompareOp.EQUAL, new BinaryComparator(ValueUtils.serialize(label))); labelFilter.setFilterIfMissing(true); SingleColumnValueFilter fromValueFilter = new SingleColumnValueFilter(Constants.DEFAULT_FAMILY_BYTES, key, CompareFilter.CompareOp.GREATER_OR_EQUAL, new BinaryComparator(inclusiveFromValue)); fromValueFilter.setFilterIfMissing(true); SingleColumnValueFilter toValueFilter = new SingleColumnValueFilter(Constants.DEFAULT_FAMILY_BYTES, key, CompareFilter.CompareOp.LESS, new BinaryComparator(exclusiveToValue)); toValueFilter.setFilterIfMissing(true); FilterList filterList = new FilterList(labelFilter, fromValueFilter, toValueFilter); scan.setFilter(filterList); return scan; } }