From 06bb292b426eaf4d5332709bac84bfe46516197a Mon Sep 17 00:00:00 2001 From: Michael Lieberman Date: Tue, 30 Dec 2014 16:32:11 -0500 Subject: [PATCH] Move getProperty and getPropertyKeys inside AccumuloElement Other cruft cleanup --- .../edu/jhuapl/tinkerpop/AccumuloElement.java | 86 +++++++++++-------- .../edu/jhuapl/tinkerpop/AccumuloGraph.java | 28 +----- .../edu/jhuapl/tinkerpop/GlobalInstances.java | 15 ++++ .../edu/jhuapl/tinkerpop/PropertyCache.java | 6 ++ 4 files changed, 73 insertions(+), 62 deletions(-) diff --git a/src/main/java/edu/jhuapl/tinkerpop/AccumuloElement.java b/src/main/java/edu/jhuapl/tinkerpop/AccumuloElement.java index c3c244a..06ee0f5 100644 --- a/src/main/java/edu/jhuapl/tinkerpop/AccumuloElement.java +++ b/src/main/java/edu/jhuapl/tinkerpop/AccumuloElement.java @@ -16,9 +16,6 @@ package edu.jhuapl.tinkerpop; import java.util.Map; import java.util.Set; - -import org.apache.accumulo.core.util.Pair; - import com.tinkerpop.blueprints.Element; public abstract class AccumuloElement implements Element { @@ -30,57 +27,66 @@ public abstract class AccumuloElement implements Element { private PropertyCache propertyCache; - protected AccumuloElement(GlobalInstances globals, String id, Class type) { + protected AccumuloElement(GlobalInstances globals, + String id, Class type) { this.globals = globals; this.id = id; this.type = type; } - @Override - public T getProperty(String key) { + /** + * Create properties cache if it doesn't exist, + * and preload any properties. + */ + private void makeCache() { if (propertyCache == null) { - // Lazily create the properties cache. - // We will create it here just in case the parent does not actually - // pre-load any data. Note it also may be created in the - // cacheProperty method, as well, in the event a class pre-loads - // data before a call is made to obtain it. propertyCache = new PropertyCache(globals.getConfig()); - globals.getGraph().preloadProperties(this, type); - } - - T val = propertyCache.get(key); - if (val != null) { - return val; - } else { - Pair pair = globals.getGraph().getProperty(type, this, key); - if (pair.getFirst() != null) { - cacheProperty(key, pair.getSecond()); + // Preload any keys, if needed. + String[] preloadKeys = globals.getConfig().getPreloadedProperties(); + if (preloadKeys != null) { + propertyCache.putAll(globals.getElementWrapper(type) + .readProperties(this, preloadKeys)); } - return pair.getSecond(); } } + @Override + public T getProperty(String key) { + makeCache(); + + // Get from property cache. + T value = propertyCache.get(key); + + // If not cached, get it from the backing table. + if (value == null) { + value = globals.getElementWrapper(type).readProperty(this, key); + } + + // Cache the new value. + if (value != null) { + propertyCache.put(key, value); + } + + return value; + } + + @Override public Set getPropertyKeys() { - return globals.getGraph().getPropertyKeys(type, this); + return globals.getElementWrapper(type).readPropertyKeys(this); } @Override public void setProperty(String key, Object value) { + makeCache(); globals.getGraph().setProperty(type, this, key, value); - cacheProperty(key, value); + propertyCache.put(key, value); } @Override public T removeProperty(String key) { - if (propertyCache != null) { - // we have the cached value but we still need to pass this on to the - // parent so it can actually remove the data from the backing store. - // Since we have to do that anyway, we will use the parent's value - // instead of the cache value to to be as up-to-date as possible. - // Of course we still need to clear out the cached value... - propertyCache.remove(key); - } + makeCache(); + propertyCache.remove(key); return globals.getGraph().removeProperty(type, this, key); } @@ -98,21 +104,29 @@ public abstract class AccumuloElement implements Element { } else if (!obj.getClass().equals(getClass())) { return false; } else { - return this.id.equals(((AccumuloElement) obj).id); + return id.equals(((AccumuloElement) obj).id); } } + @Override public int hashCode() { return getClass().hashCode() ^ id.hashCode(); } + /** + * @deprecated This is used in {@link AccumuloGraph} but needs to go away. + * @param key + * @param value + */ void cacheProperty(String key, Object value) { - if (propertyCache == null) { - propertyCache = new PropertyCache(globals.getConfig()); - } + makeCache(); propertyCache.put(key, value); } + /** + * @deprecated This is used in {@link AccumuloGraph} but needs to go away. + * @param props + */ void cacheAllProperties(Map props) { for (String key : props.keySet()) { cacheProperty(key, props.get(key)); diff --git a/src/main/java/edu/jhuapl/tinkerpop/AccumuloGraph.java b/src/main/java/edu/jhuapl/tinkerpop/AccumuloGraph.java index ac4d98d..68d9ba8 100644 --- a/src/main/java/edu/jhuapl/tinkerpop/AccumuloGraph.java +++ b/src/main/java/edu/jhuapl/tinkerpop/AccumuloGraph.java @@ -42,7 +42,6 @@ import org.apache.accumulo.core.data.Mutation; import org.apache.accumulo.core.data.Range; import org.apache.accumulo.core.data.Value; import org.apache.accumulo.core.iterators.user.RegExFilter; -import org.apache.accumulo.core.util.Pair; import org.apache.accumulo.core.util.PeekingIterator; import org.apache.commons.configuration.Configuration; import org.apache.hadoop.io.Text; @@ -848,12 +847,6 @@ public class AccumuloGraph implements Graph, KeyIndexableGraph, IndexableGraph { // methods used by AccumuloElement, AccumuloVertex, AccumuloEdge to interact // with the backing Accumulo data store... - Pair getProperty(Class type, - Element element, String key) { - T value = getElementTableWrapper(type).readProperty(element, key); - return new Pair(config.getPropertyCacheTimeout(key), value); - } - void preloadProperties(AccumuloElement element, Class type) { String[] toPreload = config.getPreloadedProperties(); if (toPreload == null) { @@ -884,10 +877,6 @@ public class AccumuloGraph implements Graph, KeyIndexableGraph, IndexableGraph { s.close(); } - Set getPropertyKeys(Class type, Element element) { - return getElementTableWrapper(type).readPropertyKeys(element); - } - /** * Sets the property. Requires a round-trip to Accumulo to see if the property exists * iff the provided key has an index. Therefore, for best performance, if at @@ -906,7 +895,7 @@ public class AccumuloGraph implements Graph, KeyIndexableGraph, IndexableGraph { if (config.getAutoIndex() || getIndexedKeys(type).contains(key)) { BatchWriter bw = getIndexBatchWriter(type); - Object old = getProperty(type, element, key).getSecond(); + Object old = element.getProperty(key); if (old != null) { byte[] oldByteVal = AccumuloByteSerializer.serialize(old); m = new Mutation(oldByteVal); @@ -942,7 +931,7 @@ public class AccumuloGraph implements Graph, KeyIndexableGraph, IndexableGraph { throw new AccumuloGraphException("Cannot remove the " + StringFactory.LABEL + " property."); } - T obj = (T) getProperty(type, element, key).getSecond(); + T obj = element.getProperty(key); try { if (obj != null) { getElementTableWrapper(type).clearProperty(element, key); @@ -959,19 +948,6 @@ public class AccumuloGraph implements Graph, KeyIndexableGraph, IndexableGraph { return obj; } - private void applyRegexValueFilter(Scanner scan, String... labels) { - StringBuilder regex = new StringBuilder(); - for (String lab : labels) { - if (regex.length() != 0) - regex.append("|"); - regex.append(".*_\\Q").append(lab).append("\\E$"); - } - - IteratorSetting is = new IteratorSetting(10, "getEdgeFilter", RegExFilter.class); - RegExFilter.setRegexs(is, null, null, null, regex.toString(), false); - scan.addScanIterator(is); - } - Vertex getEdgeVertex(String edgeId, Direction direction) { Scanner s = getElementScanner(Edge.class); try { diff --git a/src/main/java/edu/jhuapl/tinkerpop/GlobalInstances.java b/src/main/java/edu/jhuapl/tinkerpop/GlobalInstances.java index 99bb1c3..68e49c7 100644 --- a/src/main/java/edu/jhuapl/tinkerpop/GlobalInstances.java +++ b/src/main/java/edu/jhuapl/tinkerpop/GlobalInstances.java @@ -13,7 +13,12 @@ package edu.jhuapl.tinkerpop; import org.apache.accumulo.core.client.MultiTableBatchWriter; +import com.tinkerpop.blueprints.Edge; +import com.tinkerpop.blueprints.Element; +import com.tinkerpop.blueprints.Vertex; + import edu.jhuapl.tinkerpop.tables.EdgeTableWrapper; +import edu.jhuapl.tinkerpop.tables.ElementTableWrapper; import edu.jhuapl.tinkerpop.tables.VertexTableWrapper; /** @@ -58,6 +63,16 @@ public class GlobalInstances { return edgeWrapper; } + public ElementTableWrapper getElementWrapper(Class clazz) { + if (Vertex.class.equals(clazz)) { + return vertexWrapper; + } else if (Edge.class.equals(clazz)) { + return edgeWrapper; + } else { + throw new AccumuloGraphException("Unrecognized class: "+clazz); + } + } + public ElementCaches getCaches() { return caches; } diff --git a/src/main/java/edu/jhuapl/tinkerpop/PropertyCache.java b/src/main/java/edu/jhuapl/tinkerpop/PropertyCache.java index 645c956..e34ae0f 100644 --- a/src/main/java/edu/jhuapl/tinkerpop/PropertyCache.java +++ b/src/main/java/edu/jhuapl/tinkerpop/PropertyCache.java @@ -42,6 +42,12 @@ public class PropertyCache { timeout != null ? System.currentTimeMillis() + timeout : null)); } + public void putAll(Map entries) { + for (String key : entries.keySet()) { + put(key, entries.get(key)); + } + } + public T get(String key) { long now = System.currentTimeMillis();