use of com.thinkaurelius.titan.graphdb.types.IndexType in project titan by thinkaurelius.
the class ManagementSystem method addIndexKey.
@Override
public void addIndexKey(final TitanGraphIndex index, final PropertyKey key, Parameter... parameters) {
Preconditions.checkArgument(index != null && key != null && index instanceof TitanGraphIndexWrapper && !(key instanceof BaseKey), "Need to provide valid index and key");
if (parameters == null)
parameters = new Parameter[0];
IndexType indexType = ((TitanGraphIndexWrapper) index).getBaseIndex();
Preconditions.checkArgument(indexType instanceof MixedIndexType, "Can only add keys to an external index, not %s", index.name());
Preconditions.checkArgument(indexType instanceof IndexTypeWrapper && key instanceof TitanSchemaVertex && ((IndexTypeWrapper) indexType).getSchemaBase() instanceof TitanSchemaVertex);
TitanSchemaVertex indexVertex = (TitanSchemaVertex) ((IndexTypeWrapper) indexType).getSchemaBase();
for (IndexField field : indexType.getFieldKeys()) Preconditions.checkArgument(!field.getFieldKey().equals(key), "Key [%s] has already been added to index %s", key.name(), index.name());
//Assemble parameters
boolean addMappingParameter = !ParameterType.MAPPED_NAME.hasParameter(parameters);
Parameter[] extendedParas = new Parameter[parameters.length + 1 + (addMappingParameter ? 1 : 0)];
System.arraycopy(parameters, 0, extendedParas, 0, parameters.length);
int arrPosition = parameters.length;
if (addMappingParameter)
extendedParas[arrPosition++] = ParameterType.MAPPED_NAME.getParameter(graph.getIndexSerializer().getDefaultFieldName(key, parameters, indexType.getBackingIndexName()));
extendedParas[arrPosition++] = ParameterType.STATUS.getParameter(key.isNew() ? SchemaStatus.ENABLED : SchemaStatus.INSTALLED);
addSchemaEdge(indexVertex, key, TypeDefinitionCategory.INDEX_FIELD, extendedParas);
updateSchemaVertex(indexVertex);
indexType.resetCache();
//Check to see if the index supports this
if (!graph.getIndexSerializer().supports((MixedIndexType) indexType, ParameterIndexField.of(key, parameters))) {
throw new TitanException("Could not register new index field '" + key.name() + "' with index backend as the data type, cardinality or parameter combination is not supported.");
}
try {
IndexSerializer.register((MixedIndexType) indexType, key, transaction.getTxHandle());
} catch (BackendException e) {
throw new TitanException("Could not register new index field with index backend", e);
}
if (!indexVertex.isNew())
updatedTypes.add(indexVertex);
if (!key.isNew())
updateIndex(index, SchemaAction.REGISTER_INDEX);
}
use of com.thinkaurelius.titan.graphdb.types.IndexType in project titan by thinkaurelius.
the class TitanOperationCountingTest method testReadOperations.
public void testReadOperations(boolean cache) {
metricsPrefix = "testReadOperations" + cache;
resetEdgeCacheCounts();
makeVertexIndexedUniqueKey("uid", Integer.class);
mgmt.setConsistency(mgmt.getGraphIndex("uid"), ConsistencyModifier.LOCK);
finishSchema();
if (cache)
clopen(option(DB_CACHE), true, option(DB_CACHE_CLEAN_WAIT), 0, option(DB_CACHE_TIME), 0);
else
clopen();
TitanTransaction tx = graph.buildTransaction().groupName(metricsPrefix).start();
tx.makePropertyKey("name").dataType(String.class).make();
tx.makeEdgeLabel("knows").make();
tx.makeVertexLabel("person").make();
tx.commit();
verifyStoreMetrics(EDGESTORE_NAME);
verifyLockingOverwrite(INDEXSTORE_NAME, 3);
verifyStoreMetrics(METRICS_STOREMANAGER_NAME, ImmutableMap.of(M_MUTATE, 1l));
resetMetrics();
metricsPrefix = GraphDatabaseConfiguration.METRICS_SCHEMA_PREFIX_DEFAULT;
resetMetrics();
//Test schema caching
for (int t = 0; t < 10; t++) {
tx = graph.buildTransaction().groupName(metricsPrefix).start();
//Retrieve name by index (one backend call each)
assertTrue(tx.containsRelationType("name"));
assertTrue(tx.containsRelationType("knows"));
assertTrue(tx.containsVertexLabel("person"));
PropertyKey name = tx.getPropertyKey("name");
EdgeLabel knows = tx.getEdgeLabel("knows");
VertexLabel person = tx.getVertexLabel("person");
PropertyKey uid = tx.getPropertyKey("uid");
//Retrieve name as property (one backend call each)
assertEquals("name", name.name());
assertEquals("knows", knows.name());
assertEquals("person", person.name());
assertEquals("uid", uid.name());
//Looking up the definition (one backend call each)
assertEquals(Cardinality.SINGLE, name.cardinality());
assertEquals(Multiplicity.MULTI, knows.multiplicity());
assertFalse(person.isPartitioned());
assertEquals(Integer.class, uid.dataType());
//Retrieving in and out relations for the relation types...
InternalRelationType namei = (InternalRelationType) name;
InternalRelationType knowsi = (InternalRelationType) knows;
InternalRelationType uidi = (InternalRelationType) uid;
assertNull(namei.getBaseType());
assertNull(knowsi.getBaseType());
IndexType index = Iterables.getOnlyElement(uidi.getKeyIndexes());
assertEquals(1, index.getFieldKeys().length);
assertEquals(ElementCategory.VERTEX, index.getElement());
assertEquals(ConsistencyModifier.LOCK, ((CompositeIndexType) index).getConsistencyModifier());
assertEquals(1, Iterables.size(uidi.getRelationIndexes()));
assertEquals(1, Iterables.size(namei.getRelationIndexes()));
assertEquals(namei, Iterables.getOnlyElement(namei.getRelationIndexes()));
assertEquals(knowsi, Iterables.getOnlyElement(knowsi.getRelationIndexes()));
//.. and vertex labels
assertEquals(0, ((InternalVertexLabel) person).getTTL());
tx.commit();
//Needs to read on first iteration, after that it doesn't change anymore
verifyStoreMetrics(EDGESTORE_NAME, ImmutableMap.of(M_GET_SLICE, 19l));
verifyStoreMetrics(INDEXSTORE_NAME, ImmutableMap.of(M_GET_SLICE, 4l, /* name, knows, person, uid */
M_ACQUIRE_LOCK, 0l));
}
//Create some graph data
metricsPrefix = "add" + cache;
tx = graph.buildTransaction().groupName(metricsPrefix).start();
TitanVertex v = tx.addVertex(), u = tx.addVertex("person");
v.property(VertexProperty.Cardinality.single, "uid", 1);
u.property(VertexProperty.Cardinality.single, "name", "juju");
Edge e = v.addEdge("knows", u);
e.property("name", "edge");
tx.commit();
verifyStoreMetrics(EDGESTORE_NAME);
verifyLockingOverwrite(INDEXSTORE_NAME, 1);
for (int i = 1; i <= 30; i++) {
metricsPrefix = "op" + i + cache;
tx = graph.buildTransaction().groupName(metricsPrefix).start();
v = getOnlyElement(tx.query().has("uid", 1).vertices());
assertEquals(1, v.<Integer>value("uid").intValue());
u = getOnlyElement(v.query().direction(Direction.BOTH).labels("knows").vertices());
e = getOnlyElement(u.query().direction(Direction.IN).labels("knows").edges());
assertEquals("juju", u.value("name"));
assertEquals("edge", e.value("name"));
tx.commit();
if (!cache || i == 0) {
verifyStoreMetrics(EDGESTORE_NAME, ImmutableMap.of(M_GET_SLICE, 4l));
verifyStoreMetrics(INDEXSTORE_NAME, ImmutableMap.of(M_GET_SLICE, 1l));
} else if (cache && i > 20) {
//Needs a couple of iterations for cache to be cleaned
verifyStoreMetrics(EDGESTORE_NAME);
verifyStoreMetrics(INDEXSTORE_NAME);
}
}
}
use of com.thinkaurelius.titan.graphdb.types.IndexType 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.graphdb.types.IndexType 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;
}
use of com.thinkaurelius.titan.graphdb.types.IndexType in project titan by thinkaurelius.
the class ManagementSystem method setTypeModifier.
private void setTypeModifier(final TitanSchemaElement element, final ModifierType modifierType, final Object value) {
Preconditions.checkArgument(element != null, "null schema element");
TypeDefinitionCategory cat = modifierType.getCategory();
if (cat.hasDataType() && null != value) {
Preconditions.checkArgument(cat.getDataType().equals(value.getClass()), "modifier value is not of expected type " + cat.getDataType());
}
TitanSchemaVertex typeVertex;
if (element instanceof TitanSchemaVertex) {
typeVertex = (TitanSchemaVertex) element;
} else if (element instanceof TitanGraphIndex) {
IndexType index = ((TitanGraphIndexWrapper) element).getBaseIndex();
assert index instanceof IndexTypeWrapper;
SchemaSource base = ((IndexTypeWrapper) index).getSchemaBase();
typeVertex = (TitanSchemaVertex) base;
} else
throw new IllegalArgumentException("Invalid schema element: " + element);
// remove any pre-existing value for the modifier, or return if an identical value has already been set
for (TitanEdge e : typeVertex.getEdges(TypeDefinitionCategory.TYPE_MODIFIER, Direction.OUT)) {
TitanSchemaVertex v = (TitanSchemaVertex) e.vertex(Direction.IN);
TypeDefinitionMap def = v.getDefinition();
Object existingValue = def.getValue(modifierType.getCategory());
if (null != existingValue) {
if (existingValue.equals(value)) {
//Already has the right value, don't need to do anything
return;
} else {
e.remove();
v.remove();
}
}
}
if (null != value) {
TypeDefinitionMap def = new TypeDefinitionMap();
def.setValue(cat, value);
TitanSchemaVertex cVertex = transaction.makeSchemaVertex(TitanSchemaCategory.TYPE_MODIFIER, null, def);
addSchemaEdge(typeVertex, cVertex, TypeDefinitionCategory.TYPE_MODIFIER, null);
}
updateSchemaVertex(typeVertex);
updatedTypes.add(typeVertex);
}
Aggregations