use of org.janusgraph.graphdb.types.vertices.JanusGraphSchemaVertex in project janusgraph by JanusGraph.
the class StandardTransactionLogProcessor method restoreExternalIndexes.
private void restoreExternalIndexes(Predicate<String> isFailedIndex, TransactionLogHeader.Entry entry) {
// 1) Collect all elements (vertices and relations) and the indexes for which they need to be restored
SetMultimap<String, IndexRestore> indexRestores = HashMultimap.create();
BackendOperation.execute(() -> {
final StandardJanusGraphTx tx = (StandardJanusGraphTx) graph.newTransaction();
try {
entry.getContentAsModifications(serializer).stream().map(m -> ModificationDeserializer.parseRelation(m, tx)).forEach(rel -> {
// Collect affected vertex indexes
for (final MixedIndexType index : getMixedIndexes(rel.getType())) {
if (index.getElement() == ElementCategory.VERTEX && isFailedIndex.apply(index.getBackingIndexName())) {
assert rel.isProperty();
indexRestores.put(index.getBackingIndexName(), new IndexRestore(rel.getVertex(0).longId(), ElementCategory.VERTEX, getIndexId(index)));
}
}
// See if relation itself is affected
for (final RelationType relType : rel.getPropertyKeysDirect()) {
for (final MixedIndexType index : getMixedIndexes(relType)) {
if (index.getElement().isInstance(rel) && isFailedIndex.apply(index.getBackingIndexName())) {
assert rel.id() instanceof RelationIdentifier;
indexRestores.put(index.getBackingIndexName(), new IndexRestore(rel.id(), ElementCategory.getByClazz(rel.getClass()), getIndexId(index)));
}
}
}
});
} finally {
if (tx.isOpen())
tx.rollback();
}
return true;
}, readTime);
// 2) Restore elements per backing index
for (final String indexName : indexRestores.keySet()) {
final StandardJanusGraphTx tx = (StandardJanusGraphTx) graph.newTransaction();
try {
BackendTransaction btx = tx.getTxHandle();
final IndexTransaction indexTx = btx.getIndexTransaction(indexName);
BackendOperation.execute(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
Map<String, Map<String, List<IndexEntry>>> restoredDocs = Maps.newHashMap();
indexRestores.get(indexName).forEach(restore -> {
JanusGraphSchemaVertex indexV = (JanusGraphSchemaVertex) tx.getVertex(restore.indexId);
MixedIndexType index = (MixedIndexType) indexV.asIndexType();
JanusGraphElement element = restore.retrieve(tx);
if (element != null) {
graph.getIndexSerializer().reindexElement(element, index, restoredDocs);
} else {
// Element is deleted
graph.getIndexSerializer().removeElement(restore.elementId, index, restoredDocs);
}
});
indexTx.restore(restoredDocs);
indexTx.commit();
return true;
}
@Override
public String toString() {
return "IndexMutation";
}
}, persistenceTime);
} finally {
if (tx.isOpen())
tx.rollback();
}
}
}
use of org.janusgraph.graphdb.types.vertices.JanusGraphSchemaVertex in project janusgraph by JanusGraph.
the class IndexRemoveJob method validateIndexStatus.
@Override
protected void validateIndexStatus() {
if (!(index instanceof RelationTypeIndex || index instanceof JanusGraphIndex)) {
throw new UnsupportedOperationException("Unsupported index found: " + index);
}
if (index instanceof JanusGraphIndex) {
JanusGraphIndex graphIndex = (JanusGraphIndex) index;
if (graphIndex.isMixedIndex())
throw new UnsupportedOperationException("Cannot remove mixed indexes through JanusGraph. This can " + "only be accomplished in the indexing system directly.");
CompositeIndexType indexType = (CompositeIndexType) managementSystem.getSchemaVertex(index).asIndexType();
graphIndexId = indexType.getID();
}
// Must be a relation type index or a composite graph index
JanusGraphSchemaVertex schemaVertex = managementSystem.getSchemaVertex(index);
SchemaStatus actualStatus = schemaVertex.getStatus();
Preconditions.checkArgument(actualStatus == SchemaStatus.DISABLED, "The index [%s] must be disabled before it can be removed", indexName);
}
use of org.janusgraph.graphdb.types.vertices.JanusGraphSchemaVertex in project janusgraph by JanusGraph.
the class VertexIDAssigner method assignIDs.
public void assignIDs(Iterable<InternalRelation> addedRelations) {
if (!placementStrategy.supportsBulkPlacement()) {
for (InternalRelation relation : addedRelations) {
for (int i = 0; i < relation.getArity(); i++) {
InternalVertex vertex = relation.getVertex(i);
if (!vertex.hasId()) {
assignID(vertex, getVertexIDType(vertex));
}
}
assignID(relation);
}
} else {
// 2) only assign ids to (user) vertices
Map<InternalVertex, PartitionAssignment> assignments = new HashMap<>();
for (InternalRelation relation : addedRelations) {
for (int i = 0; i < relation.getArity(); i++) {
InternalVertex vertex = relation.getVertex(i);
if (!vertex.hasId()) {
// Those are assigned ids immediately in the transaction
assert !(vertex instanceof JanusGraphSchemaVertex);
if (vertex.vertexLabel().isPartitioned())
// Assign partitioned vertex ids immediately
assignID(vertex, getVertexIDType(vertex));
else
assignments.put(vertex, PartitionAssignment.EMPTY);
}
}
}
log.trace("Bulk id assignment for {} vertices", assignments.size());
for (int attempt = 0; attempt < MAX_PARTITION_RENEW_ATTEMPTS && (assignments != null && !assignments.isEmpty()); attempt++) {
placementStrategy.getPartitions(assignments);
Map<InternalVertex, PartitionAssignment> leftOvers = null;
Iterator<Map.Entry<InternalVertex, PartitionAssignment>> iterator = assignments.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<InternalVertex, PartitionAssignment> entry = iterator.next();
try {
assignID(entry.getKey(), entry.getValue().getPartitionID(), getVertexIDType(entry.getKey()));
Preconditions.checkArgument(entry.getKey().hasId());
} catch (IDPoolExhaustedException e) {
if (leftOvers == null)
leftOvers = new HashMap<>();
leftOvers.put(entry.getKey(), PartitionAssignment.EMPTY);
break;
}
}
if (leftOvers != null) {
while (iterator.hasNext()) leftOvers.put(iterator.next().getKey(), PartitionAssignment.EMPTY);
log.debug("Exhausted ID Pool in bulk assignment. Left-over vertices {}", leftOvers.size());
}
assignments = leftOvers;
}
if (assignments != null && !assignments.isEmpty())
throw new IDPoolExhaustedException("Could not find non-exhausted partition ID Pool after " + MAX_PARTITION_RENEW_ATTEMPTS + " attempts");
// 3) assign ids to relations
for (InternalRelation relation : addedRelations) {
assignID(relation);
}
}
}
use of org.janusgraph.graphdb.types.vertices.JanusGraphSchemaVertex in project janusgraph by JanusGraph.
the class VertexIDAssigner method assignID.
private void assignID(InternalElement element, IDManager.VertexIDType vertexIDType) {
for (int attempt = 0; attempt < MAX_PARTITION_RENEW_ATTEMPTS; attempt++) {
long partitionID = -1;
if (element instanceof JanusGraphSchemaVertex) {
partitionID = IDManager.SCHEMA_PARTITION;
} else if (element instanceof JanusGraphVertex) {
if (vertexIDType == IDManager.VertexIDType.PartitionedVertex)
partitionID = IDManager.PARTITIONED_VERTEX_PARTITION;
else
partitionID = placementStrategy.getPartition(element);
} else if (element instanceof InternalRelation) {
InternalRelation relation = (InternalRelation) element;
if (attempt < relation.getLen()) {
// On the first attempts, try to use partition of incident vertices
InternalVertex incident = relation.getVertex(attempt);
Preconditions.checkArgument(incident.hasId());
if (!IDManager.VertexIDType.PartitionedVertex.is(incident.longId()) || relation.isProperty()) {
partitionID = getPartitionID(incident);
} else {
continue;
}
} else {
partitionID = placementStrategy.getPartition(element);
}
}
try {
assignID(element, partitionID, vertexIDType);
} catch (IDPoolExhaustedException e) {
// try again on a different partition
continue;
}
assert element.hasId();
// Check if we should assign a different representative of a potential partitioned vertex
if (element instanceof InternalRelation) {
InternalRelation relation = (InternalRelation) element;
if (relation.isProperty() && isPartitionedAt(relation, 0)) {
// Always assign properties to the canonical representative of a partitioned vertex
InternalVertex vertex = relation.getVertex(0);
((ReassignableRelation) relation).setVertexAt(0, vertex.tx().getInternalVertex(idManager.getCanonicalVertexId(vertex.longId())));
} else if (relation.isEdge()) {
for (int pos = 0; pos < relation.getArity(); pos++) {
if (isPartitionedAt(relation, pos)) {
InternalVertex incident = relation.getVertex(pos);
long newPartition;
int otherPosition = (pos + 1) % 2;
if (((InternalRelationType) relation.getType()).multiplicity().isUnique(EdgeDirection.fromPosition(pos))) {
// If the relation is unique in the direction, we assign it to the canonical vertex...
newPartition = idManager.getPartitionId(idManager.getCanonicalVertexId(incident.longId()));
} else if (!isPartitionedAt(relation, otherPosition)) {
// ...else, we assign it to the partition of the non-partitioned vertex...
newPartition = getPartitionID(relation.getVertex(otherPosition));
} else {
// ...and if such does not exists (i.e. both end vertices are partitioned) we use the hash of the relation id
newPartition = idManager.getPartitionHashForId(relation.longId());
}
if (idManager.getPartitionId(incident.longId()) != newPartition) {
((ReassignableRelation) relation).setVertexAt(pos, incident.tx().getOtherPartitionVertex(incident, newPartition));
}
}
}
}
}
return;
}
throw new IDPoolExhaustedException("Could not find non-exhausted partition ID Pool after " + MAX_PARTITION_RENEW_ATTEMPTS + " attempts");
}
use of org.janusgraph.graphdb.types.vertices.JanusGraphSchemaVertex in project janusgraph by JanusGraph.
the class ManagementSystem method setTypeModifier.
private void setTypeModifier(final JanusGraphSchemaElement 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 %s", cat.getDataType());
}
JanusGraphSchemaVertex typeVertex;
if (element instanceof JanusGraphSchemaVertex) {
typeVertex = (JanusGraphSchemaVertex) element;
} else if (element instanceof JanusGraphIndex) {
IndexType index = ((JanusGraphIndexWrapper) element).getBaseIndex();
assert index instanceof IndexTypeWrapper;
SchemaSource base = ((IndexTypeWrapper) index).getSchemaBase();
typeVertex = (JanusGraphSchemaVertex) 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 (JanusGraphEdge e : typeVertex.getEdges(TypeDefinitionCategory.TYPE_MODIFIER, Direction.OUT)) {
JanusGraphSchemaVertex v = (JanusGraphSchemaVertex) 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);
JanusGraphSchemaVertex cVertex = transaction.makeSchemaVertex(JanusGraphSchemaCategory.TYPE_MODIFIER, null, def);
addSchemaEdge(typeVertex, cVertex, TypeDefinitionCategory.TYPE_MODIFIER, null);
}
updateSchemaVertex(typeVertex);
updatedTypes.add(typeVertex);
}
Aggregations