Search in sources :

Example 1 with JanusGraphSchemaVertex

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();
        }
    }
}
Also used : ReadBuffer(org.janusgraph.diskstorage.ReadBuffer) Log(org.janusgraph.diskstorage.log.Log) StandardJanusGraphTx(org.janusgraph.graphdb.transaction.StandardJanusGraphTx) MessageReader(org.janusgraph.diskstorage.log.MessageReader) BackendOperation(org.janusgraph.diskstorage.util.BackendOperation) LoggerFactory(org.slf4j.LoggerFactory) JanusGraphTransaction(org.janusgraph.core.JanusGraphTransaction) Future(java.util.concurrent.Future) HashMultimap(com.google.common.collect.HashMultimap) Serializer(org.janusgraph.graphdb.database.serialize.Serializer) IndexEntry(org.janusgraph.diskstorage.indexing.IndexEntry) Duration(java.time.Duration) Map(java.util.Map) StaticBuffer(org.janusgraph.diskstorage.StaticBuffer) MixedIndexType(org.janusgraph.graphdb.types.MixedIndexType) IndexType(org.janusgraph.graphdb.types.IndexType) LogTxStatus(org.janusgraph.graphdb.database.log.LogTxStatus) TransactionRecovery(org.janusgraph.core.log.TransactionRecovery) RelationType(org.janusgraph.core.RelationType) TimestampProvider(org.janusgraph.diskstorage.util.time.TimestampProvider) StandardJanusGraph(org.janusgraph.graphdb.database.StandardJanusGraph) JanusGraphSchemaVertex(org.janusgraph.graphdb.types.vertices.JanusGraphSchemaVertex) LogTxMeta(org.janusgraph.graphdb.database.log.LogTxMeta) Instant(java.time.Instant) Objects(java.util.Objects) List(java.util.List) RelationIdentifier(org.janusgraph.graphdb.relations.RelationIdentifier) Predicate(com.google.common.base.Predicate) CacheBuilder(com.google.common.cache.CacheBuilder) InternalRelationType(org.janusgraph.graphdb.internal.InternalRelationType) Iterables(com.google.common.collect.Iterables) SchemaSource(org.janusgraph.graphdb.types.SchemaSource) BackgroundThread(org.janusgraph.util.system.BackgroundThread) IndexTransaction(org.janusgraph.diskstorage.indexing.IndexTransaction) BackendTransaction(org.janusgraph.diskstorage.BackendTransaction) Callable(java.util.concurrent.Callable) IndexTypeWrapper(org.janusgraph.graphdb.types.indextype.IndexTypeWrapper) Predicates(com.google.common.base.Predicates) JanusGraphException(org.janusgraph.core.JanusGraphException) Message(org.janusgraph.diskstorage.log.Message) JanusGraphElement(org.janusgraph.core.JanusGraphElement) TransactionLogHeader(org.janusgraph.graphdb.database.log.TransactionLogHeader) Logger(org.slf4j.Logger) Maps(com.google.common.collect.Maps) SetMultimap(com.google.common.collect.SetMultimap) ElementCategory(org.janusgraph.graphdb.internal.ElementCategory) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) AtomicLong(java.util.concurrent.atomic.AtomicLong) RemovalCause(com.google.common.cache.RemovalCause) GraphDatabaseConfiguration(org.janusgraph.graphdb.configuration.GraphDatabaseConfiguration) Preconditions(com.google.common.base.Preconditions) RemovalListener(com.google.common.cache.RemovalListener) Cache(com.google.common.cache.Cache) ReadMarker(org.janusgraph.diskstorage.log.ReadMarker) Collections(java.util.Collections) MixedIndexType(org.janusgraph.graphdb.types.MixedIndexType) IndexTransaction(org.janusgraph.diskstorage.indexing.IndexTransaction) RelationIdentifier(org.janusgraph.graphdb.relations.RelationIdentifier) JanusGraphException(org.janusgraph.core.JanusGraphException) ExecutionException(java.util.concurrent.ExecutionException) JanusGraphElement(org.janusgraph.core.JanusGraphElement) StandardJanusGraphTx(org.janusgraph.graphdb.transaction.StandardJanusGraphTx) RelationType(org.janusgraph.core.RelationType) InternalRelationType(org.janusgraph.graphdb.internal.InternalRelationType) JanusGraphSchemaVertex(org.janusgraph.graphdb.types.vertices.JanusGraphSchemaVertex) List(java.util.List) Map(java.util.Map) BackendTransaction(org.janusgraph.diskstorage.BackendTransaction)

Example 2 with JanusGraphSchemaVertex

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);
}
Also used : CompositeIndexType(org.janusgraph.graphdb.types.CompositeIndexType) JanusGraphSchemaVertex(org.janusgraph.graphdb.types.vertices.JanusGraphSchemaVertex) JanusGraphIndex(org.janusgraph.core.schema.JanusGraphIndex) RelationTypeIndex(org.janusgraph.core.schema.RelationTypeIndex) SchemaStatus(org.janusgraph.core.schema.SchemaStatus)

Example 3 with JanusGraphSchemaVertex

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);
        }
    }
}
Also used : HashMap(java.util.HashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) InternalRelation(org.janusgraph.graphdb.internal.InternalRelation) PartitionAssignment(org.janusgraph.graphdb.database.idassigner.placement.PartitionAssignment) InternalVertex(org.janusgraph.graphdb.internal.InternalVertex) JanusGraphSchemaVertex(org.janusgraph.graphdb.types.vertices.JanusGraphSchemaVertex) HashMap(java.util.HashMap) ConcurrentMap(java.util.concurrent.ConcurrentMap) Map(java.util.Map) EnumMap(java.util.EnumMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap)

Example 4 with JanusGraphSchemaVertex

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");
}
Also used : ReassignableRelation(org.janusgraph.graphdb.relations.ReassignableRelation) JanusGraphVertex(org.janusgraph.core.JanusGraphVertex) InternalVertex(org.janusgraph.graphdb.internal.InternalVertex) JanusGraphSchemaVertex(org.janusgraph.graphdb.types.vertices.JanusGraphSchemaVertex) InternalRelationType(org.janusgraph.graphdb.internal.InternalRelationType) InternalRelation(org.janusgraph.graphdb.internal.InternalRelation)

Example 5 with JanusGraphSchemaVertex

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);
}
Also used : TypeDefinitionCategory(org.janusgraph.graphdb.types.TypeDefinitionCategory) IndexTypeWrapper(org.janusgraph.graphdb.types.indextype.IndexTypeWrapper) JanusGraphEdge(org.janusgraph.core.JanusGraphEdge) JanusGraphSchemaVertex(org.janusgraph.graphdb.types.vertices.JanusGraphSchemaVertex) JanusGraphIndex(org.janusgraph.core.schema.JanusGraphIndex) IndexType(org.janusgraph.graphdb.types.IndexType) CompositeIndexType(org.janusgraph.graphdb.types.CompositeIndexType) MixedIndexType(org.janusgraph.graphdb.types.MixedIndexType) SchemaSource(org.janusgraph.graphdb.types.SchemaSource) TypeDefinitionMap(org.janusgraph.graphdb.types.TypeDefinitionMap)

Aggregations

JanusGraphSchemaVertex (org.janusgraph.graphdb.types.vertices.JanusGraphSchemaVertex)17 JanusGraphIndex (org.janusgraph.core.schema.JanusGraphIndex)6 CompositeIndexType (org.janusgraph.graphdb.types.CompositeIndexType)6 IndexType (org.janusgraph.graphdb.types.IndexType)6 MixedIndexType (org.janusgraph.graphdb.types.MixedIndexType)5 TypeDefinitionMap (org.janusgraph.graphdb.types.TypeDefinitionMap)5 JanusGraphException (org.janusgraph.core.JanusGraphException)4 PropertyKey (org.janusgraph.core.PropertyKey)4 RelationTypeIndex (org.janusgraph.core.schema.RelationTypeIndex)4 HashMap (java.util.HashMap)3 Map (java.util.Map)3 InternalRelationType (org.janusgraph.graphdb.internal.InternalRelationType)3 InternalVertex (org.janusgraph.graphdb.internal.InternalVertex)3 IndexTypeWrapper (org.janusgraph.graphdb.types.indextype.IndexTypeWrapper)3 PropertyKeyVertex (org.janusgraph.graphdb.types.vertices.PropertyKeyVertex)3 HashSet (java.util.HashSet)2 Set (java.util.Set)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 ConcurrentMap (java.util.concurrent.ConcurrentMap)2 JanusGraphVertex (org.janusgraph.core.JanusGraphVertex)2