use of com.baidu.hugegraph.backend.cache.CachedBackendStore.QueryId in project incubator-hugegraph by apache.
the class CachedGraphTransaction method queryEdgesFromBackend.
@Override
@Watched(prefix = "graphcache")
protected final Iterator<HugeEdge> queryEdgesFromBackend(Query query) {
RamTable ramtable = this.params().ramtable();
if (ramtable != null && ramtable.matched(query)) {
return ramtable.query(query);
}
if (!this.enableCacheEdge() || query.empty() || query.paging() || query.bigCapacity()) {
// Query all edges or query edges in paging, don't cache it
return super.queryEdgesFromBackend(query);
}
Id cacheKey = new QueryId(query);
Object value = this.edgesCache.get(cacheKey);
@SuppressWarnings("unchecked") Collection<HugeEdge> edges = (Collection<HugeEdge>) value;
if (value != null) {
for (HugeEdge edge : edges) {
if (edge.expired()) {
this.edgesCache.invalidate(cacheKey);
value = null;
}
}
}
if (value != null) {
// Not cached or the cache expired
return edges.iterator();
}
Iterator<HugeEdge> rs = super.queryEdgesFromBackend(query);
/*
* Iterator can't be cached, caching list instead
* there may be super node and too many edges in a query,
* try fetch a few of the head results and determine whether to cache.
*/
final int tryMax = 1 + MAX_CACHE_EDGES_PER_QUERY;
assert tryMax > MAX_CACHE_EDGES_PER_QUERY;
edges = new ArrayList<>(tryMax);
for (int i = 0; rs.hasNext() && i < tryMax; i++) {
edges.add(rs.next());
}
if (edges.size() == 0) {
this.edgesCache.update(cacheKey, Collections.emptyList());
} else if (edges.size() <= MAX_CACHE_EDGES_PER_QUERY) {
this.edgesCache.update(cacheKey, edges);
}
return new ExtendableIterator<>(edges.iterator(), rs);
}
use of com.baidu.hugegraph.backend.cache.CachedBackendStore.QueryId in project incubator-hugegraph by apache.
the class CachedGraphTransaction method listenChanges.
private void listenChanges() {
// Listen store event: "store.init", "store.clear", ...
Set<String> storeEvents = ImmutableSet.of(Events.STORE_INIT, Events.STORE_CLEAR, Events.STORE_TRUNCATE);
this.storeEventListener = event -> {
if (storeEvents.contains(event.name())) {
LOG.debug("Graph {} clear graph cache on event '{}'", this.graph(), event.name());
this.clearCache(null, true);
return true;
}
return false;
};
this.store().provider().listen(this.storeEventListener);
// Listen cache event: "cache"(invalid cache item)
this.cacheEventListener = event -> {
LOG.debug("Graph {} received graph cache event: {}", this.graph(), event);
Object[] args = event.args();
E.checkArgument(args.length > 0 && args[0] instanceof String, "Expect event action argument");
if (Cache.ACTION_INVALID.equals(args[0])) {
event.checkArgs(String.class, HugeType.class, Object.class);
HugeType type = (HugeType) args[1];
if (type.isVertex()) {
// Invalidate vertex cache
Object arg2 = args[2];
if (arg2 instanceof Id) {
Id id = (Id) arg2;
this.verticesCache.invalidate(id);
} else if (arg2 != null && arg2.getClass().isArray()) {
int size = Array.getLength(arg2);
for (int i = 0; i < size; i++) {
Object id = Array.get(arg2, i);
E.checkArgument(id instanceof Id, "Expect instance of Id in array, " + "but got '%s'", id.getClass());
this.verticesCache.invalidate((Id) id);
}
} else {
E.checkArgument(false, "Expect Id or Id[], but got: %s", arg2);
}
} else if (type.isEdge()) {
/*
* Invalidate edge cache via clear instead of invalidate
* because of the cacheKey is QueryId not EdgeId
*/
// this.edgesCache.invalidate(id);
this.edgesCache.clear();
}
return true;
} else if (Cache.ACTION_CLEAR.equals(args[0])) {
event.checkArgs(String.class, HugeType.class);
HugeType type = (HugeType) args[1];
this.clearCache(type, false);
return true;
}
return false;
};
EventHub graphEventHub = this.params().graphEventHub();
if (!graphEventHub.containsListener(Events.CACHE)) {
graphEventHub.listen(Events.CACHE, this.cacheEventListener);
}
}
Aggregations