use of org.janusgraph.core.schema.JanusGraphIndex in project janusgraph by JanusGraph.
the class ConfigurationManagementGraph method createIndexIfDoesNotExist.
private void createIndexIfDoesNotExist(String indexName, String propertyKeyName, Class dataType, boolean unique) {
graph.tx().rollback();
JanusGraphManagement management = graph.openManagement();
if (null == management.getGraphIndex(indexName)) {
final PropertyKey key;
boolean propertyKeyAlreadyExisted = false;
if (null == management.getPropertyKey(propertyKeyName)) {
key = management.makePropertyKey(propertyKeyName).dataType(dataType).make();
} else {
key = management.getPropertyKey(propertyKeyName);
propertyKeyAlreadyExisted = true;
}
final JanusGraphIndex index;
if (unique)
index = management.buildIndex(indexName, Vertex.class).addKey(key).unique().buildCompositeIndex();
else
index = management.buildIndex(indexName, Vertex.class).addKey(key).buildCompositeIndex();
try {
if (index.getIndexStatus(key) == INSTALLED) {
management.commit();
ManagementSystem.awaitGraphIndexStatus(graph, indexName).call();
management = graph.openManagement();
if (propertyKeyAlreadyExisted) {
management.updateIndex(management.getGraphIndex(indexName), REINDEX).get();
} else {
management.updateIndex(management.getGraphIndex(indexName), ENABLE_INDEX).get();
}
} else if (index.getIndexStatus(key) == REGISTERED) {
if (propertyKeyAlreadyExisted) {
management.updateIndex(management.getGraphIndex(indexName), REINDEX).get();
} else {
management.updateIndex(management.getGraphIndex(indexName), ENABLE_INDEX).get();
}
}
} catch (InterruptedException | ExecutionException e) {
log.warn("Failed to create index {} for ConfigurationManagementGraph with exception: {}", indexName, e);
management.rollback();
graph.tx().rollback();
}
management.commit();
graph.tx().commit();
} else {
management.rollback();
graph.tx().rollback();
}
}
use of org.janusgraph.core.schema.JanusGraphIndex in project janusgraph by JanusGraph.
the class JanusGraphTest method testConcurrentConsistencyEnforcement.
/**
* Execute multiple identical transactions concurrently. Note that since these transactions are running in the same process,
* {@link org.janusgraph.diskstorage.locking.LocalLockMediator} is used to resolve lock contentions. If there is only
* one lock needed in the whole transaction, exactly one transaction shall succeed and others shall fail due to local
* lock contention. If there is more than one lock needed in the transaction, at most one transaction shall succeed
* and others shall fail due to local lock contention.
* @throws Exception
*/
@Test
public void testConcurrentConsistencyEnforcement() throws Exception {
PropertyKey name = mgmt.makePropertyKey("name").dataType(String.class).cardinality(Cardinality.SINGLE).make();
JanusGraphIndex nameIndex = mgmt.buildIndex("name", Vertex.class).addKey(name).unique().buildCompositeIndex();
mgmt.setConsistency(nameIndex, ConsistencyModifier.LOCK);
EdgeLabel married = mgmt.makeEdgeLabel("married").multiplicity(Multiplicity.ONE2ONE).make();
mgmt.setConsistency(married, ConsistencyModifier.LOCK);
mgmt.makeEdgeLabel("friend").multiplicity(Multiplicity.MULTI).make();
finishSchema();
JanusGraphVertex baseV = tx.addVertex("name", "base");
newTx();
final long baseVid = getId(baseV);
final String nameA = "a", nameB = "b";
final int parallelThreads = 4;
// Only one lock is needed
int[] results = executeParallelTransactions(tx -> {
final JanusGraphVertex a = tx.addVertex();
final JanusGraphVertex base = getV(tx, baseVid);
base.addEdge("married", a);
}, parallelThreads);
int numOfSuccess = results[0];
int numOfLockContentions = results[1];
assertEquals(1, numOfSuccess);
assertEquals(parallelThreads - 1, numOfLockContentions);
// Two locks are needed. Note that the order of adding/modifying/deleting elements might not be consistent with
// the order of real mutations during commit. Thus, it can be the case that one thread gets one lock and another
// thread gets another, and both fail because they are unable to get the other lock.
results = executeParallelTransactions(tx -> {
tx.addVertex("name", nameA);
final JanusGraphVertex b = tx.addVertex("name", nameB);
b.addEdge("friend", b);
}, parallelThreads);
numOfSuccess = results[0];
numOfLockContentions = results[1];
assertTrue(numOfSuccess <= 1);
assertEquals(parallelThreads - numOfSuccess, numOfLockContentions);
newTx();
final long numA = Iterables.size(tx.query().has("name", nameA).vertices());
final long numB = Iterables.size(tx.query().has("name", nameB).vertices());
assertTrue(numA <= 1);
assertTrue(numB <= 1);
}
use of org.janusgraph.core.schema.JanusGraphIndex in project janusgraph by JanusGraph.
the class JanusGraphTest method testIndexUpdatesWithReindexAndRemove.
@Test
public void testIndexUpdatesWithReindexAndRemove() throws InterruptedException, ExecutionException {
clopen(option(LOG_SEND_DELAY, MANAGEMENT_LOG), Duration.ofMillis(0), option(KCVSLog.LOG_READ_LAG_TIME, MANAGEMENT_LOG), Duration.ofMillis(50), option(LOG_READ_INTERVAL, MANAGEMENT_LOG), Duration.ofMillis(250));
// Types without index
PropertyKey time = mgmt.makePropertyKey("time").dataType(Integer.class).make();
PropertyKey name = mgmt.makePropertyKey("name").dataType(String.class).cardinality(Cardinality.SET).make();
EdgeLabel friend = mgmt.makeEdgeLabel("friend").multiplicity(Multiplicity.MULTI).make();
PropertyKey sensor = mgmt.makePropertyKey("sensor").dataType(Double.class).cardinality(Cardinality.LIST).make();
finishSchema();
// Add some sensor & friend data
JanusGraphVertex v = tx.addVertex();
for (int i = 0; i < 10; i++) {
v.property("sensor", i, "time", i);
v.property("name", "v" + i);
JanusGraphVertex o = tx.addVertex();
v.addEdge("friend", o, "time", i);
}
newTx();
// Indexes should not yet be in use
v = getV(tx, v);
evaluateQuery(v.query().keys("sensor").interval("time", 1, 5).orderBy("time", desc), PROPERTY, 4, 1, new boolean[] { false, false }, tx.getPropertyKey("time"), Order.DESC);
evaluateQuery(v.query().keys("sensor").interval("time", 101, 105).orderBy("time", desc), PROPERTY, 0, 1, new boolean[] { false, false }, tx.getPropertyKey("time"), Order.DESC);
evaluateQuery(v.query().labels("friend").direction(OUT).interval("time", 1, 5).orderBy("time", desc), EDGE, 4, 1, new boolean[] { false, false }, tx.getPropertyKey("time"), Order.DESC);
evaluateQuery(v.query().labels("friend").direction(OUT).interval("time", 101, 105).orderBy("time", desc), EDGE, 0, 1, new boolean[] { false, false }, tx.getPropertyKey("time"), Order.DESC);
evaluateQuery(tx.query().has("name", "v5"), ElementCategory.VERTEX, 1, new boolean[] { false, true });
evaluateQuery(tx.query().has("name", "v105"), ElementCategory.VERTEX, 0, new boolean[] { false, true });
newTx();
// Create indexes after the fact
finishSchema();
sensor = mgmt.getPropertyKey("sensor");
time = mgmt.getPropertyKey("time");
name = mgmt.getPropertyKey("name");
friend = mgmt.getEdgeLabel("friend");
mgmt.buildPropertyIndex(sensor, "byTime", desc, time);
mgmt.buildEdgeIndex(friend, "byTime", Direction.OUT, desc, time);
mgmt.buildIndex("bySensorReading", Vertex.class).addKey(name).buildCompositeIndex();
finishSchema();
newTx();
// Add some sensor & friend data that should already be indexed even though index is not yet enabled
v = getV(tx, v);
for (int i = 100; i < 110; i++) {
v.property("sensor", i, "time", i);
v.property("name", "v" + i);
JanusGraphVertex o = tx.addVertex();
v.addEdge("friend", o, "time", i);
}
tx.commit();
// Should not yet be able to enable since not yet registered
final RelationTypeIndex pindex = mgmt.getRelationIndex(mgmt.getRelationType("sensor"), "byTime");
final RelationTypeIndex eindex = mgmt.getRelationIndex(mgmt.getRelationType("friend"), "byTime");
final JanusGraphIndex graphIndex = mgmt.getGraphIndex("bySensorReading");
assertThrows(IllegalArgumentException.class, () -> mgmt.updateIndex(pindex, SchemaAction.ENABLE_INDEX));
assertThrows(IllegalArgumentException.class, () -> mgmt.updateIndex(eindex, SchemaAction.ENABLE_INDEX));
assertThrows(IllegalArgumentException.class, () -> mgmt.updateIndex(graphIndex, SchemaAction.ENABLE_INDEX));
mgmt.commit();
ManagementUtil.awaitVertexIndexUpdate(graph, "byTime", "sensor", 10, ChronoUnit.SECONDS);
ManagementUtil.awaitGraphIndexUpdate(graph, "bySensorReading", 5, ChronoUnit.SECONDS);
finishSchema();
// Verify new status
RelationTypeIndex pindex2 = mgmt.getRelationIndex(mgmt.getRelationType("sensor"), "byTime");
RelationTypeIndex eindex2 = mgmt.getRelationIndex(mgmt.getRelationType("friend"), "byTime");
JanusGraphIndex graphIndex2 = mgmt.getGraphIndex("bySensorReading");
assertEquals(SchemaStatus.REGISTERED, pindex2.getIndexStatus());
assertEquals(SchemaStatus.REGISTERED, eindex2.getIndexStatus());
assertEquals(SchemaStatus.REGISTERED, graphIndex2.getIndexStatus(graphIndex2.getFieldKeys()[0]));
finishSchema();
// Simply enable without reindex
eindex2 = mgmt.getRelationIndex(mgmt.getRelationType("friend"), "byTime");
mgmt.updateIndex(eindex2, SchemaAction.ENABLE_INDEX);
finishSchema();
assertTrue(ManagementSystem.awaitRelationIndexStatus(graph, "byTime", "friend").status(SchemaStatus.ENABLED).timeout(10L, ChronoUnit.SECONDS).call().getSucceeded());
// Reindex the other two
pindex2 = mgmt.getRelationIndex(mgmt.getRelationType("sensor"), "byTime");
ScanMetrics reindexSensorByTime = mgmt.updateIndex(pindex2, SchemaAction.REINDEX).get();
finishSchema();
graphIndex2 = mgmt.getGraphIndex("bySensorReading");
ScanMetrics reindexBySensorReading = mgmt.updateIndex(graphIndex2, SchemaAction.REINDEX).get();
finishSchema();
assertNotEquals(0, reindexSensorByTime.getCustom(IndexRepairJob.ADDED_RECORDS_COUNT));
assertNotEquals(0, reindexBySensorReading.getCustom(IndexRepairJob.ADDED_RECORDS_COUNT));
// Every index should now be enabled
pindex2 = mgmt.getRelationIndex(mgmt.getRelationType("sensor"), "byTime");
eindex2 = mgmt.getRelationIndex(mgmt.getRelationType("friend"), "byTime");
graphIndex2 = mgmt.getGraphIndex("bySensorReading");
assertEquals(SchemaStatus.ENABLED, eindex2.getIndexStatus());
assertEquals(SchemaStatus.ENABLED, pindex2.getIndexStatus());
assertEquals(SchemaStatus.ENABLED, graphIndex2.getIndexStatus(graphIndex2.getFieldKeys()[0]));
// Add some more sensor & friend data
newTx();
v = getV(tx, v);
for (int i = 200; i < 210; i++) {
v.property("sensor", i, "time", i);
v.property("name", "v" + i);
JanusGraphVertex o = tx.addVertex();
v.addEdge("friend", o, "time", i);
}
newTx();
// Use indexes now but only see new data for property and graph index
v = getV(tx, v);
evaluateQuery(v.query().keys("sensor").interval("time", 1, 5).orderBy("time", desc), PROPERTY, 4, 1, new boolean[] { true, true }, tx.getPropertyKey("time"), Order.DESC);
evaluateQuery(v.query().keys("sensor").interval("time", 101, 105).orderBy("time", desc), PROPERTY, 4, 1, new boolean[] { true, true }, tx.getPropertyKey("time"), Order.DESC);
evaluateQuery(v.query().keys("sensor").interval("time", 201, 205).orderBy("time", desc), PROPERTY, 4, 1, new boolean[] { true, true }, tx.getPropertyKey("time"), Order.DESC);
evaluateQuery(v.query().labels("friend").direction(OUT).interval("time", 1, 5).orderBy("time", desc), EDGE, 0, 1, new boolean[] { true, true }, tx.getPropertyKey("time"), Order.DESC);
evaluateQuery(v.query().labels("friend").direction(OUT).interval("time", 101, 105).orderBy("time", desc), EDGE, 4, 1, new boolean[] { true, true }, tx.getPropertyKey("time"), Order.DESC);
evaluateQuery(v.query().labels("friend").direction(OUT).interval("time", 201, 205).orderBy("time", desc), EDGE, 4, 1, new boolean[] { true, true }, tx.getPropertyKey("time"), Order.DESC);
evaluateQuery(tx.query().has("name", "v5"), ElementCategory.VERTEX, 1, new boolean[] { true, true }, "bySensorReading");
evaluateQuery(tx.query().has("name", "v105"), ElementCategory.VERTEX, 1, new boolean[] { true, true }, "bySensorReading");
evaluateQuery(tx.query().has("name", "v205"), ElementCategory.VERTEX, 1, new boolean[] { true, true }, "bySensorReading");
finishSchema();
eindex2 = mgmt.getRelationIndex(mgmt.getRelationType("friend"), "byTime");
ScanMetrics reindexFriendByTime = mgmt.updateIndex(eindex2, SchemaAction.REINDEX).get();
finishSchema();
assertNotEquals(0, reindexFriendByTime.getCustom(IndexRepairJob.ADDED_RECORDS_COUNT));
finishSchema();
newTx();
// It should now have all the answers
v = getV(tx, v);
evaluateQuery(v.query().labels("friend").direction(OUT).interval("time", 1, 5).orderBy("time", desc), EDGE, 4, 1, new boolean[] { true, true }, tx.getPropertyKey("time"), Order.DESC);
evaluateQuery(v.query().labels("friend").direction(OUT).interval("time", 101, 105).orderBy("time", desc), EDGE, 4, 1, new boolean[] { true, true }, tx.getPropertyKey("time"), Order.DESC);
evaluateQuery(v.query().labels("friend").direction(OUT).interval("time", 201, 205).orderBy("time", desc), EDGE, 4, 1, new boolean[] { true, true }, tx.getPropertyKey("time"), Order.DESC);
pindex2 = mgmt.getRelationIndex(mgmt.getRelationType("sensor"), "byTime");
graphIndex2 = mgmt.getGraphIndex("bySensorReading");
mgmt.updateIndex(pindex2, SchemaAction.DISABLE_INDEX);
mgmt.updateIndex(graphIndex2, SchemaAction.DISABLE_INDEX);
mgmt.commit();
tx.commit();
ManagementUtil.awaitVertexIndexUpdate(graph, "byTime", "sensor", 10, ChronoUnit.SECONDS);
ManagementUtil.awaitGraphIndexUpdate(graph, "bySensorReading", 5, ChronoUnit.SECONDS);
finishSchema();
pindex2 = mgmt.getRelationIndex(mgmt.getRelationType("sensor"), "byTime");
graphIndex2 = mgmt.getGraphIndex("bySensorReading");
assertEquals(SchemaStatus.DISABLED, pindex2.getIndexStatus());
assertEquals(SchemaStatus.DISABLED, graphIndex2.getIndexStatus(graphIndex2.getFieldKeys()[0]));
finishSchema();
newTx();
// The two disabled indexes should force full scans
v = getV(tx, v);
evaluateQuery(v.query().keys("sensor").interval("time", 1, 5).orderBy("time", desc), PROPERTY, 4, 1, new boolean[] { false, false }, tx.getPropertyKey("time"), Order.DESC);
evaluateQuery(v.query().keys("sensor").interval("time", 101, 105).orderBy("time", desc), PROPERTY, 4, 1, new boolean[] { false, false }, tx.getPropertyKey("time"), Order.DESC);
evaluateQuery(v.query().keys("sensor").interval("time", 201, 205).orderBy("time", desc), PROPERTY, 4, 1, new boolean[] { false, false }, tx.getPropertyKey("time"), Order.DESC);
evaluateQuery(v.query().labels("friend").direction(OUT).interval("time", 1, 5).orderBy("time", desc), EDGE, 4, 1, new boolean[] { true, true }, tx.getPropertyKey("time"), Order.DESC);
evaluateQuery(v.query().labels("friend").direction(OUT).interval("time", 101, 105).orderBy("time", desc), EDGE, 4, 1, new boolean[] { true, true }, tx.getPropertyKey("time"), Order.DESC);
evaluateQuery(v.query().labels("friend").direction(OUT).interval("time", 201, 205).orderBy("time", desc), EDGE, 4, 1, new boolean[] { true, true }, tx.getPropertyKey("time"), Order.DESC);
evaluateQuery(tx.query().has("name", "v5"), ElementCategory.VERTEX, 1, new boolean[] { false, true });
evaluateQuery(tx.query().has("name", "v105"), ElementCategory.VERTEX, 1, new boolean[] { false, true });
evaluateQuery(tx.query().has("name", "v205"), ElementCategory.VERTEX, 1, new boolean[] { false, true });
tx.commit();
finishSchema();
pindex2 = mgmt.getRelationIndex(mgmt.getRelationType("sensor"), "byTime");
graphIndex2 = mgmt.getGraphIndex("bySensorReading");
ScanMetrics pmetrics = mgmt.updateIndex(pindex2, SchemaAction.REMOVE_INDEX).get();
ScanMetrics graphIndexMetrics = mgmt.updateIndex(graphIndex2, SchemaAction.REMOVE_INDEX).get();
finishSchema();
assertEquals(30, pmetrics.getCustom(IndexRemoveJob.DELETED_RECORDS_COUNT));
assertEquals(30, graphIndexMetrics.getCustom(IndexRemoveJob.DELETED_RECORDS_COUNT));
}
use of org.janusgraph.core.schema.JanusGraphIndex in project janusgraph by JanusGraph.
the class JanusGraphTest method testPropertyTTLTiming.
@Test
@Tag(TestCategory.BRITTLE_TESTS)
@FeatureFlag(feature = JanusGraphFeature.CellTtl)
public void testPropertyTTLTiming() throws Exception {
PropertyKey name = mgmt.makePropertyKey("name").dataType(String.class).make();
PropertyKey place = mgmt.makePropertyKey("place").dataType(String.class).make();
mgmt.setTTL(name, Duration.ofSeconds(42));
mgmt.setTTL(place, Duration.ofSeconds(1));
final JanusGraphIndex index1 = mgmt.buildIndex("index1", Vertex.class).addKey(name).buildCompositeIndex();
final JanusGraphIndex index2 = mgmt.buildIndex("index2", Vertex.class).addKey(name).addKey(place).buildCompositeIndex();
VertexLabel label1 = mgmt.makeVertexLabel("event").setStatic().make();
mgmt.setTTL(label1, Duration.ofSeconds(2));
assertEquals(Duration.ofSeconds(42), mgmt.getTTL(name));
assertEquals(Duration.ofSeconds(1), mgmt.getTTL(place));
assertEquals(Duration.ofSeconds(2), mgmt.getTTL(label1));
mgmt.commit();
JanusGraphVertex v1 = tx.addVertex(T.label, "event", "name", "some event", "place", "somewhere");
tx.commit();
Object id = v1.id();
v1 = getV(graph, id);
assertNotNull(v1);
assertNotEmpty(graph.query().has("name", "some event").has("place", "somewhere").vertices());
assertNotEmpty(graph.query().has("name", "some event").vertices());
Thread.sleep(1001);
graph.tx().rollback();
// short-lived property expires first
v1 = getV(graph, id);
assertNotNull(v1);
assertEmpty(graph.query().has("name", "some event").has("place", "somewhere").vertices());
assertNotEmpty(graph.query().has("name", "some event").vertices());
Thread.sleep(1001);
graph.tx().rollback();
// vertex expires before defined TTL of the long-lived property
assertEmpty(graph.query().has("name", "some event").has("place", "somewhere").vertices());
assertEmpty(graph.query().has("name", "some event").vertices());
v1 = getV(graph, id);
assertNull(v1);
}
use of org.janusgraph.core.schema.JanusGraphIndex in project janusgraph by JanusGraph.
the class JanusGraphTest method testIndexQueryWithLabelsAndContainsIN.
@Test
public void testIndexQueryWithLabelsAndContainsIN() {
// This test is based on the steps to reproduce #882
String labelName = "labelName";
VertexLabel label = mgmt.makeVertexLabel(labelName).make();
PropertyKey uid = mgmt.makePropertyKey("uid").dataType(String.class).make();
JanusGraphIndex uidCompositeIndex = mgmt.buildIndex("uidIndex", Vertex.class).indexOnly(label).addKey(uid).unique().buildCompositeIndex();
mgmt.setConsistency(uidCompositeIndex, ConsistencyModifier.LOCK);
finishSchema();
JanusGraphVertex foo = graph.addVertex(labelName);
JanusGraphVertex bar = graph.addVertex(labelName);
foo.property("uid", "foo");
bar.property("uid", "bar");
graph.tx().commit();
Iterable<JanusGraphVertex> vertexes = graph.query().has("uid", Contain.IN, ImmutableList.of("foo", "bar")).has(LABEL_NAME, labelName).vertices();
assertEquals(2, Iterables.size(vertexes));
for (JanusGraphVertex v : vertexes) {
assertEquals(labelName, v.vertexLabel().name());
}
}
Aggregations