use of com.thinkaurelius.titan.core.schema.TitanGraphIndex in project titan by thinkaurelius.
the class AbstractIndexManagementIT method testRepairGraphIndex.
@Test
public void testRepairGraphIndex() throws InterruptedException, BackendException, ExecutionException {
tx.commit();
mgmt.commit();
// Load the "Graph of the Gods" sample data (WITHOUT mixed index coverage)
GraphOfTheGodsFactory.loadWithoutMixedIndex(graph, true);
// Create and enable a graph index on age
TitanManagement m = graph.openManagement();
PropertyKey age = m.getPropertyKey("age");
m.buildIndex("verticesByAge", Vertex.class).addKey(age).buildCompositeIndex();
m.commit();
graph.tx().commit();
// Block until the SchemaStatus transitions to REGISTERED
assertTrue(ManagementSystem.awaitGraphIndexStatus(graph, "verticesByAge").status(SchemaStatus.REGISTERED).call().getSucceeded());
m = graph.openManagement();
TitanGraphIndex index = m.getGraphIndex("verticesByAge");
m.updateIndex(index, SchemaAction.ENABLE_INDEX);
m.commit();
graph.tx().commit();
// Block until the SchemaStatus transitions to ENABLED
assertTrue(ManagementSystem.awaitGraphIndexStatus(graph, "verticesByAge").status(SchemaStatus.ENABLED).call().getSucceeded());
// Run a query that hits the index but erroneously returns nothing because we haven't repaired yet
assertFalse(graph.query().has("age", 10000).vertices().iterator().hasNext());
// Repair
MapReduceIndexManagement mri = new MapReduceIndexManagement(graph);
m = graph.openManagement();
index = m.getGraphIndex("verticesByAge");
ScanMetrics metrics = mri.updateIndex(index, SchemaAction.REINDEX).get();
assertEquals(6, metrics.getCustom(IndexRepairJob.ADDED_RECORDS_COUNT));
// Test the index
Iterable<TitanVertex> hits = graph.query().has("age", 4500).vertices();
assertNotNull(hits);
assertEquals(1, Iterables.size(hits));
TitanVertex v = Iterables.getOnlyElement(hits);
assertNotNull(v);
assertEquals("neptune", v.value("name"));
}
use of com.thinkaurelius.titan.core.schema.TitanGraphIndex in project titan by thinkaurelius.
the class GraphOfTheGodsFactory method load.
public static void load(final TitanGraph graph, String mixedIndexName, boolean uniqueNameCompositeIndex) {
//Create Schema
TitanManagement mgmt = graph.openManagement();
final PropertyKey name = mgmt.makePropertyKey("name").dataType(String.class).make();
TitanManagement.IndexBuilder nameIndexBuilder = mgmt.buildIndex("name", Vertex.class).addKey(name);
if (uniqueNameCompositeIndex)
nameIndexBuilder.unique();
TitanGraphIndex namei = nameIndexBuilder.buildCompositeIndex();
mgmt.setConsistency(namei, ConsistencyModifier.LOCK);
final PropertyKey age = mgmt.makePropertyKey("age").dataType(Integer.class).make();
if (null != mixedIndexName)
mgmt.buildIndex("vertices", Vertex.class).addKey(age).buildMixedIndex(mixedIndexName);
final PropertyKey time = mgmt.makePropertyKey("time").dataType(Integer.class).make();
final PropertyKey reason = mgmt.makePropertyKey("reason").dataType(String.class).make();
final PropertyKey place = mgmt.makePropertyKey("place").dataType(Geoshape.class).make();
if (null != mixedIndexName)
mgmt.buildIndex("edges", Edge.class).addKey(reason).addKey(place).buildMixedIndex(mixedIndexName);
mgmt.makeEdgeLabel("father").multiplicity(Multiplicity.MANY2ONE).make();
mgmt.makeEdgeLabel("mother").multiplicity(Multiplicity.MANY2ONE).make();
EdgeLabel battled = mgmt.makeEdgeLabel("battled").signature(time).make();
mgmt.buildEdgeIndex(battled, "battlesByTime", Direction.BOTH, Order.decr, time);
mgmt.makeEdgeLabel("lives").signature(reason).make();
mgmt.makeEdgeLabel("pet").make();
mgmt.makeEdgeLabel("brother").make();
mgmt.makeVertexLabel("titan").make();
mgmt.makeVertexLabel("location").make();
mgmt.makeVertexLabel("god").make();
mgmt.makeVertexLabel("demigod").make();
mgmt.makeVertexLabel("human").make();
mgmt.makeVertexLabel("monster").make();
mgmt.commit();
TitanTransaction tx = graph.newTransaction();
// vertices
Vertex saturn = tx.addVertex(T.label, "titan", "name", "saturn", "age", 10000);
Vertex sky = tx.addVertex(T.label, "location", "name", "sky");
Vertex sea = tx.addVertex(T.label, "location", "name", "sea");
Vertex jupiter = tx.addVertex(T.label, "god", "name", "jupiter", "age", 5000);
Vertex neptune = tx.addVertex(T.label, "god", "name", "neptune", "age", 4500);
Vertex hercules = tx.addVertex(T.label, "demigod", "name", "hercules", "age", 30);
Vertex alcmene = tx.addVertex(T.label, "human", "name", "alcmene", "age", 45);
Vertex pluto = tx.addVertex(T.label, "god", "name", "pluto", "age", 4000);
Vertex nemean = tx.addVertex(T.label, "monster", "name", "nemean");
Vertex hydra = tx.addVertex(T.label, "monster", "name", "hydra");
Vertex cerberus = tx.addVertex(T.label, "monster", "name", "cerberus");
Vertex tartarus = tx.addVertex(T.label, "location", "name", "tartarus");
// edges
jupiter.addEdge("father", saturn);
jupiter.addEdge("lives", sky, "reason", "loves fresh breezes");
jupiter.addEdge("brother", neptune);
jupiter.addEdge("brother", pluto);
neptune.addEdge("lives", sea).property("reason", "loves waves");
neptune.addEdge("brother", jupiter);
neptune.addEdge("brother", pluto);
hercules.addEdge("father", jupiter);
hercules.addEdge("mother", alcmene);
hercules.addEdge("battled", nemean, "time", 1, "place", Geoshape.point(38.1f, 23.7f));
hercules.addEdge("battled", hydra, "time", 2, "place", Geoshape.point(37.7f, 23.9f));
hercules.addEdge("battled", cerberus, "time", 12, "place", Geoshape.point(39f, 22f));
pluto.addEdge("brother", jupiter);
pluto.addEdge("brother", neptune);
pluto.addEdge("lives", tartarus, "reason", "no fear of death");
pluto.addEdge("pet", cerberus);
cerberus.addEdge("lives", tartarus);
// commit the transaction to disk
tx.commit();
}
use of com.thinkaurelius.titan.core.schema.TitanGraphIndex in project titan by thinkaurelius.
the class GraphIndexStatusWatcher method call.
@Override
public GraphIndexStatusReport call() throws InterruptedException {
Preconditions.checkNotNull(g, "Graph instance must not be null");
Preconditions.checkNotNull(graphIndexName, "Index name must not be null");
Preconditions.checkNotNull(status, "Target status must not be null");
Map<String, SchemaStatus> notConverged = new HashMap<>();
Map<String, SchemaStatus> converged = new HashMap<>();
TitanGraphIndex idx;
Timer t = new Timer(TimestampProviders.MILLI).start();
boolean timedOut;
while (true) {
TitanManagement mgmt = null;
try {
mgmt = g.openManagement();
idx = mgmt.getGraphIndex(graphIndexName);
for (PropertyKey pk : idx.getFieldKeys()) {
SchemaStatus s = idx.getIndexStatus(pk);
LOGGER.debug("Key {} has status {}", pk, s);
if (!status.equals(s))
notConverged.put(pk.toString(), s);
else
converged.put(pk.toString(), s);
}
} finally {
if (null != mgmt)
// Let an exception here propagate up the stack
mgmt.rollback();
}
String waitingOn = Joiner.on(",").withKeyValueSeparator("=").join(notConverged);
if (!notConverged.isEmpty()) {
LOGGER.info("Some key(s) on index {} do not currently have status {}: {}", graphIndexName, status, waitingOn);
} else {
LOGGER.info("All {} key(s) on index {} have status {}", converged.size(), graphIndexName, status);
return new GraphIndexStatusReport(true, graphIndexName, status, notConverged, converged, t.elapsed());
}
timedOut = null != timeout && 0 < t.elapsed().compareTo(timeout);
if (timedOut) {
LOGGER.info("Timed out ({}) while waiting for index {} to converge on status {}", timeout, graphIndexName, status);
return new GraphIndexStatusReport(false, graphIndexName, status, notConverged, converged, t.elapsed());
}
notConverged.clear();
converged.clear();
Thread.sleep(poll.toMillis());
}
}
use of com.thinkaurelius.titan.core.schema.TitanGraphIndex in project titan by thinkaurelius.
the class ManagementSystem method setConsistency.
/**
* Sets the consistency level for those schema elements that support it (types and internal indexes)
* </p>
* Note, that it is possible to have a race condition here if two threads simultaneously try to change the
* consistency level. However, this is resolved when the consistency level is being read by taking the
* first one and deleting all existing attached consistency levels upon modification.
*
* @param element
* @param consistency
*/
@Override
public void setConsistency(TitanSchemaElement element, ConsistencyModifier consistency) {
if (element instanceof RelationType) {
RelationTypeVertex rv = (RelationTypeVertex) element;
Preconditions.checkArgument(consistency != ConsistencyModifier.FORK || !rv.multiplicity().isConstrained(), "Cannot apply FORK consistency mode to constraint relation type: %s", rv.name());
} else if (element instanceof TitanGraphIndex) {
IndexType index = ((TitanGraphIndexWrapper) element).getBaseIndex();
if (index.isMixedIndex())
throw new IllegalArgumentException("Cannot change consistency on mixed index: " + element);
} else
throw new IllegalArgumentException("Cannot change consistency of schema element: " + element);
setTypeModifier(element, ModifierType.CONSISTENCY, consistency);
}
use of com.thinkaurelius.titan.core.schema.TitanGraphIndex in project titan by thinkaurelius.
the class ManagementSystem method updateIndex.
/* --------------
Schema Update
--------------- */
@Override
public IndexJobFuture updateIndex(TitanIndex index, SchemaAction updateAction) {
Preconditions.checkArgument(index != null, "Need to provide an index");
Preconditions.checkArgument(updateAction != null, "Need to provide update action");
TitanSchemaVertex schemaVertex = getSchemaVertex(index);
Set<TitanSchemaVertex> dependentTypes;
Set<PropertyKeyVertex> keySubset = ImmutableSet.of();
if (index instanceof RelationTypeIndex) {
dependentTypes = ImmutableSet.of((TitanSchemaVertex) ((InternalRelationType) schemaVertex).getBaseType());
if (!updateAction.isApplicableStatus(schemaVertex.getStatus()))
return null;
} else if (index instanceof TitanGraphIndex) {
IndexType indexType = schemaVertex.asIndexType();
dependentTypes = Sets.newHashSet();
if (indexType.isCompositeIndex()) {
if (!updateAction.isApplicableStatus(schemaVertex.getStatus()))
return null;
for (PropertyKey key : ((TitanGraphIndex) index).getFieldKeys()) {
dependentTypes.add((PropertyKeyVertex) key);
}
} else {
keySubset = Sets.newHashSet();
MixedIndexType cindexType = (MixedIndexType) indexType;
Set<SchemaStatus> applicableStatus = updateAction.getApplicableStatus();
for (ParameterIndexField field : cindexType.getFieldKeys()) {
if (applicableStatus.contains(field.getStatus()))
keySubset.add((PropertyKeyVertex) field.getFieldKey());
}
if (keySubset.isEmpty())
return null;
dependentTypes.addAll(keySubset);
}
} else
throw new UnsupportedOperationException("Updates not supported for index: " + index);
IndexIdentifier indexId = new IndexIdentifier(index);
StandardScanner.Builder builder;
IndexJobFuture future;
switch(updateAction) {
case REGISTER_INDEX:
setStatus(schemaVertex, SchemaStatus.INSTALLED, keySubset);
updatedTypes.add(schemaVertex);
updatedTypes.addAll(dependentTypes);
setUpdateTrigger(new UpdateStatusTrigger(graph, schemaVertex, SchemaStatus.REGISTERED, keySubset));
future = new EmptyIndexJobFuture();
break;
case REINDEX:
builder = graph.getBackend().buildEdgeScanJob();
builder.setFinishJob(indexId.getIndexJobFinisher(graph, SchemaAction.ENABLE_INDEX));
builder.setJobId(indexId);
builder.setJob(VertexJobConverter.convert(graph, new IndexRepairJob(indexId.indexName, indexId.relationTypeName)));
try {
future = builder.execute();
} catch (BackendException e) {
throw new TitanException(e);
}
break;
case ENABLE_INDEX:
setStatus(schemaVertex, SchemaStatus.ENABLED, keySubset);
updatedTypes.add(schemaVertex);
if (!keySubset.isEmpty())
updatedTypes.addAll(dependentTypes);
future = new EmptyIndexJobFuture();
break;
case DISABLE_INDEX:
setStatus(schemaVertex, SchemaStatus.INSTALLED, keySubset);
updatedTypes.add(schemaVertex);
if (!keySubset.isEmpty())
updatedTypes.addAll(dependentTypes);
setUpdateTrigger(new UpdateStatusTrigger(graph, schemaVertex, SchemaStatus.DISABLED, keySubset));
future = new EmptyIndexJobFuture();
break;
case REMOVE_INDEX:
if (index instanceof RelationTypeIndex) {
builder = graph.getBackend().buildEdgeScanJob();
} else {
TitanGraphIndex gindex = (TitanGraphIndex) index;
if (gindex.isMixedIndex())
throw new UnsupportedOperationException("External mixed indexes must be removed in the indexing system directly.");
builder = graph.getBackend().buildGraphIndexScanJob();
}
builder.setFinishJob(indexId.getIndexJobFinisher());
builder.setJobId(indexId);
builder.setJob(new IndexRemoveJob(graph, indexId.indexName, indexId.relationTypeName));
try {
future = builder.execute();
} catch (BackendException e) {
throw new TitanException(e);
}
break;
default:
throw new UnsupportedOperationException("Update action not supported: " + updateAction);
}
return future;
}
Aggregations