diff --git a/hugegraph-api/src/main/java/com/baidu/hugegraph/core/GraphManager.java b/hugegraph-api/src/main/java/com/baidu/hugegraph/core/GraphManager.java
index 90ef5426d4..090eb4c591 100644
--- a/hugegraph-api/src/main/java/com/baidu/hugegraph/core/GraphManager.java
+++ b/hugegraph-api/src/main/java/com/baidu/hugegraph/core/GraphManager.java
@@ -42,7 +42,6 @@
import com.baidu.hugegraph.backend.cache.Cache;
import com.baidu.hugegraph.backend.cache.CacheManager;
import com.baidu.hugegraph.backend.store.BackendStoreSystemInfo;
-import com.baidu.hugegraph.backend.store.memory.InMemoryDBStoreProvider;
import com.baidu.hugegraph.config.HugeConfig;
import com.baidu.hugegraph.config.ServerOptions;
import com.baidu.hugegraph.exception.NotSupportException;
@@ -189,7 +188,9 @@ private void loadGraph(String name, String path) {
private void checkBackendVersionOrExit() {
for (String graph : this.graphs()) {
HugeGraph hugegraph = this.graph(graph);
- if (InMemoryDBStoreProvider.matchType(hugegraph.backend())) {
+ boolean persistence = hugegraph.graphTransaction().store()
+ .features().supportsPersistence();
+ if (!persistence) {
hugegraph.initBackend();
}
BackendStoreSystemInfo info = new BackendStoreSystemInfo(hugegraph);
diff --git a/hugegraph-cassandra/src/main/java/com/baidu/hugegraph/backend/store/cassandra/CassandraSessionPool.java b/hugegraph-cassandra/src/main/java/com/baidu/hugegraph/backend/store/cassandra/CassandraSessionPool.java
index 5a2d8457de..c4351b3657 100644
--- a/hugegraph-cassandra/src/main/java/com/baidu/hugegraph/backend/store/cassandra/CassandraSessionPool.java
+++ b/hugegraph-cassandra/src/main/java/com/baidu/hugegraph/backend/store/cassandra/CassandraSessionPool.java
@@ -104,12 +104,12 @@ public final synchronized Cluster cluster() {
}
@Override
- public final synchronized Session session() {
+ public final Session session() {
return (Session) super.getOrNewSession();
}
@Override
- protected final synchronized Session newSession() {
+ protected Session newSession() {
E.checkState(this.cluster != null,
"Cassandra cluster has not been initialized");
return new Session();
@@ -157,7 +157,7 @@ public BatchStatement add(Statement statement) {
}
@Override
- public void clear() {
+ public void rollback() {
this.batch.clear();
}
diff --git a/hugegraph-cassandra/src/main/java/com/baidu/hugegraph/backend/store/cassandra/CassandraStore.java b/hugegraph-cassandra/src/main/java/com/baidu/hugegraph/backend/store/cassandra/CassandraStore.java
index fdb8e86725..e7af77dfe8 100644
--- a/hugegraph-cassandra/src/main/java/com/baidu/hugegraph/backend/store/cassandra/CassandraStore.java
+++ b/hugegraph-cassandra/src/main/java/com/baidu/hugegraph/backend/store/cassandra/CassandraStore.java
@@ -356,7 +356,7 @@ public void rollbackTx() {
session.txState(TxState.ROLLBACKING);
try {
- session.clear();
+ session.rollback();
} finally {
// Assume batch commit would auto rollback
session.txState(TxState.CLEAN);
diff --git a/hugegraph-core/pom.xml b/hugegraph-core/pom.xml
index 01ec1f1520..a1d53b1847 100644
--- a/hugegraph-core/pom.xml
+++ b/hugegraph-core/pom.xml
@@ -19,7 +19,7 @@
com.baidu.hugegraph
hugegraph-common
- 1.5.6
+ 1.5.8
diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/HugeGraph.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/HugeGraph.java
index 7a4d96ada5..7143cc452e 100644
--- a/hugegraph-core/src/main/java/com/baidu/hugegraph/HugeGraph.java
+++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/HugeGraph.java
@@ -385,10 +385,6 @@ public Iterator vertices(Query query) {
return this.graphTransaction().queryVertices(query);
}
- public Iterator adjacentVertices(Iterator edges) {
- return this.graphTransaction().queryAdjacentVertices(edges);
- }
-
@Override
public Iterator edges(Object... objects) {
if (objects.length == 0) {
@@ -401,6 +397,14 @@ public Iterator edges(Query query) {
return this.graphTransaction().queryEdges(query);
}
+ public Iterator adjacentVertices(Iterator edges) {
+ return this.graphTransaction().queryAdjacentVertices(edges);
+ }
+
+ public Iterator adjacentEdges(Id vertexId) {
+ return this.graphTransaction().queryEdgesByVertex(vertexId);
+ }
+
public PropertyKey propertyKey(Id id) {
PropertyKey pk = this.schemaTransaction().getPropertyKey(id);
E.checkArgument(pk != null, "Undefined property key id: '%s'", id);
diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/cache/CachedGraphTransaction.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/cache/CachedGraphTransaction.java
index 1cca6bc2a3..e8e21942a3 100644
--- a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/cache/CachedGraphTransaction.java
+++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/cache/CachedGraphTransaction.java
@@ -40,7 +40,7 @@
import com.baidu.hugegraph.type.HugeType;
import com.google.common.collect.ImmutableList;
-public class CachedGraphTransaction extends GraphTransaction {
+public final class CachedGraphTransaction extends GraphTransaction {
private final static int MAX_CACHE_EDGES_PER_QUERY = 100;
diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/cache/CachedSchemaTransaction.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/cache/CachedSchemaTransaction.java
index 9dc6467487..357f6b8f5f 100644
--- a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/cache/CachedSchemaTransaction.java
+++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/cache/CachedSchemaTransaction.java
@@ -24,7 +24,6 @@
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.Function;
import com.baidu.hugegraph.HugeGraph;
import com.baidu.hugegraph.backend.id.Id;
@@ -40,7 +39,7 @@
import com.baidu.hugegraph.util.Events;
import com.google.common.collect.ImmutableSet;
-public class CachedSchemaTransaction extends SchemaTransaction {
+public final class CachedSchemaTransaction extends SchemaTransaction {
private final Cache idCache;
private final Cache nameCache;
@@ -153,12 +152,26 @@ private static Id generateId(HugeType type, String name) {
return IdGenerator.of(type.string() + "-" + name);
}
- private Object getOrFetch(HugeType type, Id id,
- Function fetcher) {
+ @Override
+ protected void addSchema(SchemaElement schema) {
+ super.addSchema(schema);
+
+ this.resetCachedAllIfReachedCapacity();
+
+ Id prefixedId = generateId(schema.type(), schema.id());
+ this.idCache.update(prefixedId, schema);
+
+ Id prefixedName = generateId(schema.type(), schema.name());
+ this.nameCache.update(prefixedName, schema);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ protected T getSchema(HugeType type, Id id) {
Id prefixedId = generateId(type, id);
Object value = this.idCache.get(prefixedId);
if (value == null) {
- value = fetcher.apply(id);
+ value = super.getSchema(type, id);
if (value != null) {
this.resetCachedAllIfReachedCapacity();
@@ -169,15 +182,17 @@ private Object getOrFetch(HugeType type, Id id,
this.nameCache.update(prefixedName, schema);
}
}
- return value;
+ return (T) value;
}
- private Object getOrFetch(HugeType type, String name,
- Function fetcher) {
+ @Override
+ @SuppressWarnings("unchecked")
+ protected T getSchema(HugeType type,
+ String name) {
Id prefixedName = generateId(type, name);
Object value = this.nameCache.get(prefixedName);
if (value == null) {
- value = fetcher.apply(name);
+ value = super.getSchema(type, name);
if (value != null) {
this.resetCachedAllIfReachedCapacity();
@@ -188,36 +203,6 @@ private Object getOrFetch(HugeType type, String name,
this.idCache.update(prefixedId, schema);
}
}
- return value;
- }
-
- @Override
- protected void addSchema(SchemaElement schema) {
- super.addSchema(schema);
-
- this.resetCachedAllIfReachedCapacity();
-
- Id prefixedId = generateId(schema.type(), schema.id());
- this.idCache.update(prefixedId, schema);
-
- Id prefixedName = generateId(schema.type(), schema.name());
- this.nameCache.update(prefixedName, schema);
- }
-
- @Override
- @SuppressWarnings("unchecked")
- protected T getSchema(HugeType type, Id id) {
- Object value = this.getOrFetch(type, id,
- k -> super.getSchema(type, id));
- return (T) value;
- }
-
- @Override
- @SuppressWarnings("unchecked")
- protected T getSchema(HugeType type,
- String name) {
- Object value = this.getOrFetch(type, name,
- k -> super.getSchema(type, name));
return (T) value;
}
diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/cache/RamCache.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/cache/RamCache.java
index 9b86d3327d..02dac63271 100644
--- a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/cache/RamCache.java
+++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/cache/RamCache.java
@@ -51,6 +51,7 @@ public class RamCache implements Cache {
// NOTE: the count in number of items, not in bytes
private final int capacity;
+ private final int halfCapacity;
// Implement LRU cache
private final ConcurrentMap> map;
@@ -63,14 +64,14 @@ public RamCache() {
}
public RamCache(int capacity) {
- this.keyLock = new KeyLock();
-
- if (capacity < 1) {
- capacity = 1;
+ if (capacity < 0) {
+ capacity = 0;
}
+ this.keyLock = new KeyLock();
this.capacity = capacity;
+ this.halfCapacity = this.capacity >> 1;
- int initialCapacity = capacity >> 3;
+ int initialCapacity = capacity >= MB ? capacity >> 10 : 256;
if (initialCapacity > MAX_INIT_CAP) {
initialCapacity = MAX_INIT_CAP;
}
@@ -80,9 +81,18 @@ public RamCache(int capacity) {
}
@Watched(prefix = "ramcache")
- private Object access(Id id) {
+ private final Object access(Id id) {
assert id != null;
+ if (this.map.size() <= this.halfCapacity) {
+ LinkNode node = this.map.get(id);
+ if (node == null) {
+ return null;
+ }
+ assert id.equals(node.key());
+ return node.value();
+ }
+
final Lock lock = this.keyLock.lock(id);
try {
LinkNode node = this.map.get(id);
@@ -91,7 +101,7 @@ private Object access(Id id) {
}
// NOTE: update the queue only if the size > capacity/2
- if (this.map.size() > this.capacity >> 1) {
+ if (this.map.size() > this.halfCapacity) {
// Move the node from mid to tail
if (this.queue.remove(node) == null) {
// The node may be removed by others through dequeue()
@@ -100,13 +110,6 @@ private Object access(Id id) {
this.queue.enqueue(node);
}
- // Ignore concurrent write for hits
- ++this.hits;
- if (LOG.isDebugEnabled()) {
- LOG.debug("RamCache cached '{}' (hits={}, miss={})",
- id, this.hits, this.miss);
- }
-
assert id.equals(node.key());
return node.value();
} finally {
@@ -115,7 +118,7 @@ private Object access(Id id) {
}
@Watched(prefix = "ramcache")
- private void write(Id id, Object value) {
+ private final void write(Id id, Object value) {
assert id != null;
assert this.capacity > 0;
@@ -163,14 +166,13 @@ private void write(Id id, Object value) {
// Add the new item to tail of the queue, then map it
this.map.put(id, this.queue.enqueue(id, value));
-
} finally {
lock.unlock();
}
}
@Watched(prefix = "ramcache")
- private void remove(Id id) {
+ private final void remove(Id id) {
assert id != null;
final Lock lock = this.keyLock.lock(id);
@@ -192,16 +194,23 @@ private void remove(Id id) {
@Override
public Object get(Id id) {
Object value = null;
- if (this.map.containsKey(id)) {
+ if (this.map.size() <= this.halfCapacity || this.map.containsKey(id)) {
// Maybe the id removed by other threads and returned null value
value = this.access(id);
}
+
if (value == null) {
++this.miss;
if (LOG.isDebugEnabled()) {
LOG.debug("RamCache missed '{}' (miss={}, hits={})",
id, this.miss, this.hits);
}
+ } else {
+ ++this.hits;
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("RamCache cached '{}' (hits={}, miss={})",
+ id, this.hits, this.miss);
+ }
}
return value;
}
@@ -210,10 +219,11 @@ public Object get(Id id) {
@Override
public Object getOrFetch(Id id, Function fetcher) {
Object value = null;
- if (this.map.containsKey(id)) {
+ if (this.map.size() <= this.halfCapacity || this.map.containsKey(id)) {
// Maybe the id removed by other threads and returned null value
value = this.access(id);
}
+
if (value == null) {
++this.miss;
if (LOG.isDebugEnabled()) {
@@ -223,6 +233,12 @@ public Object getOrFetch(Id id, Function fetcher) {
// Do fetch and update the cache
value = fetcher.apply(id);
this.update(id, value);
+ } else {
+ ++this.hits;
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("RamCache cached '{}' (hits={}, miss={})",
+ id, this.hits, this.miss);
+ }
}
return value;
}
diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/id/IdGenerator.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/id/IdGenerator.java
index 20ac48c1a5..1f1fa042e7 100644
--- a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/id/IdGenerator.java
+++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/id/IdGenerator.java
@@ -28,15 +28,15 @@ public abstract class IdGenerator {
public abstract Id generate(HugeVertex vertex);
- public static Id of(String id) {
+ public final static Id of(String id) {
return new StringId(id);
}
- public static Id of(long id) {
+ public final static Id of(long id) {
return new LongId(id);
}
- public static Id of(byte[] bytes, boolean number) {
+ public final static Id of(byte[] bytes, boolean number) {
return number ? new LongId(bytes) : new StringId(bytes);
}
@@ -45,7 +45,7 @@ public static Id of(byte[] bytes, boolean number) {
* @param id original string id value
* @return wrapped id object
*/
- public Id generate(String id) {
+ public final Id generate(String id) {
return of(id);
}
@@ -54,7 +54,7 @@ public Id generate(String id) {
* @param id original long id value
* @return wrapped id object
*/
- public Id generate(long id) {
+ public final Id generate(long id) {
return of(id);
}
diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/query/Condition.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/query/Condition.java
index 06edca2924..f1456bcd59 100644
--- a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/query/Condition.java
+++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/query/Condition.java
@@ -397,12 +397,6 @@ public boolean test(HugeElement element) {
public Condition copy() {
return new And(this.left().copy(), this.right().copy());
}
-
- @Override
- public boolean isFlattened() {
- // If this is flattened, its sub-condition should not be nested
- return this.left().isRelation() && this.right().isRelation();
- }
}
public static class Or extends BinCondition {
@@ -442,6 +436,10 @@ public abstract static class Relation extends Condition {
// The value serialized(code/string) by backend store.
protected Object serialValue;
+ protected Set UNFLATTEN_RELATION_TYPES = ImmutableSet.of(
+ RelationType.IN, RelationType.NOT_IN,
+ RelationType.TEXT_CONTAINS_ANY);
+
@Override
public ConditionType type() {
return ConditionType.RELATION;
@@ -476,6 +474,11 @@ public boolean test(Object value) {
return this.relation.test(value, this.value);
}
+ @Override
+ public boolean isFlattened() {
+ return !this.UNFLATTEN_RELATION_TYPES.contains(this.relation);
+ }
+
@Override
public List extends Relation> relations() {
return ImmutableList.of(this);
diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/query/ConditionQuery.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/query/ConditionQuery.java
index a83a755659..8d7600eb7a 100644
--- a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/query/ConditionQuery.java
+++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/query/ConditionQuery.java
@@ -38,7 +38,7 @@
import com.baidu.hugegraph.util.E;
import com.google.common.base.Function;
-public class ConditionQuery extends IdQuery {
+public final class ConditionQuery extends IdQuery {
// Conditions will be concated with `and` by default
private Set conditions = new LinkedHashSet<>();
@@ -136,8 +136,7 @@ public List relations() {
return relations;
}
- public Object condition(Object key) {
- this.checkFlattened();
+ public T condition(Object key) {
List