Search in sources :

Example 1 with ImplicitKey

use of org.janusgraph.graphdb.types.system.ImplicitKey in project janusgraph by JanusGraph.

the class EdgeSerializer method writeRelation.

public StaticArrayEntry writeRelation(InternalRelation relation, InternalRelationType type, int position, TypeInspector tx) {
    assert type == relation.getType() || (type.getBaseType() != null && type.getBaseType().equals(relation.getType()));
    Direction dir = EdgeDirection.fromPosition(position);
    Preconditions.checkArgument(type.isUnidirected(Direction.BOTH) || type.isUnidirected(dir));
    long typeId = type.longId();
    DirectionID dirID = getDirID(dir, relation.isProperty() ? RelationCategory.PROPERTY : RelationCategory.EDGE);
    DataOutput out = serializer.getDataOutput(DEFAULT_CAPACITY);
    int valuePosition;
    IDHandler.writeRelationType(out, typeId, dirID, type.isInvisibleType());
    Multiplicity multiplicity = type.multiplicity();
    long[] sortKey = type.getSortKey();
    assert !multiplicity.isConstrained() || sortKey.length == 0 : type.name();
    int keyStartPos = out.getPosition();
    if (!multiplicity.isConstrained()) {
        writeInlineTypes(sortKey, relation, out, tx, InlineType.KEY);
    }
    int keyEndPos = out.getPosition();
    long relationId = relation.longId();
    // How multiplicity is handled for edges and properties is slightly different
    if (relation.isEdge()) {
        long otherVertexId = relation.getVertex((position + 1) % 2).longId();
        if (multiplicity.isConstrained()) {
            if (multiplicity.isUnique(dir)) {
                valuePosition = out.getPosition();
                VariableLong.writePositive(out, otherVertexId);
            } else {
                VariableLong.writePositiveBackward(out, otherVertexId);
                valuePosition = out.getPosition();
            }
            VariableLong.writePositive(out, relationId);
        } else {
            VariableLong.writePositiveBackward(out, otherVertexId);
            VariableLong.writePositiveBackward(out, relationId);
            valuePosition = out.getPosition();
        }
    } else {
        Preconditions.checkArgument(relation.isProperty(), "Given relation is not property");
        Object value = ((JanusGraphVertexProperty) relation).value();
        Preconditions.checkNotNull(value);
        PropertyKey key = (PropertyKey) type;
        assert key.dataType().isInstance(value);
        if (multiplicity.isConstrained()) {
            if (multiplicity.isUnique(dir)) {
                // Cardinality=SINGLE
                valuePosition = out.getPosition();
                writePropertyValue(out, key, value);
            } else {
                // Cardinality=SET
                writePropertyValue(out, key, value);
                valuePosition = out.getPosition();
            }
            VariableLong.writePositive(out, relationId);
        } else {
            assert multiplicity.getCardinality() == Cardinality.LIST;
            VariableLong.writePositiveBackward(out, relationId);
            valuePosition = out.getPosition();
            writePropertyValue(out, key, value);
        }
    }
    // Write signature
    long[] signature = type.getSignature();
    writeInlineTypes(signature, relation, out, tx, InlineType.SIGNATURE);
    // Write remaining properties
    LongSet writtenTypes = new LongHashSet(sortKey.length + signature.length);
    if (sortKey.length > 0 || signature.length > 0) {
        for (long id : sortKey) writtenTypes.add(id);
        for (long id : signature) writtenTypes.add(id);
    }
    LongArrayList remainingTypes = new LongArrayList(8);
    for (PropertyKey t : relation.getPropertyKeysDirect()) {
        if (!(t instanceof ImplicitKey) && !writtenTypes.contains(t.longId())) {
            remainingTypes.add(t.longId());
        }
    }
    // Sort types before writing to ensure that value is always written the same way
    long[] remaining = remainingTypes.toArray();
    Arrays.sort(remaining);
    for (long tid : remaining) {
        PropertyKey t = tx.getExistingPropertyKey(tid);
        writeInline(out, t, relation.getValueDirect(t), InlineType.NORMAL);
    }
    assert valuePosition > 0;
    return new StaticArrayEntry(type.getSortOrder() == Order.DESC ? out.getStaticBufferFlipBytes(keyStartPos, keyEndPos) : out.getStaticBuffer(), valuePosition);
}
Also used : DataOutput(org.janusgraph.graphdb.database.serialize.DataOutput) LongArrayList(com.carrotsearch.hppc.LongArrayList) LongSet(com.carrotsearch.hppc.LongSet) EdgeDirection(org.janusgraph.graphdb.relations.EdgeDirection) Direction(org.apache.tinkerpop.gremlin.structure.Direction) JanusGraphVertexProperty(org.janusgraph.core.JanusGraphVertexProperty) StaticArrayEntry(org.janusgraph.diskstorage.util.StaticArrayEntry) LongHashSet(com.carrotsearch.hppc.LongHashSet) Multiplicity(org.janusgraph.core.Multiplicity) ImplicitKey(org.janusgraph.graphdb.types.system.ImplicitKey) PropertyKey(org.janusgraph.core.PropertyKey) DirectionID(org.janusgraph.graphdb.database.idhandling.IDHandler.DirectionID)

Example 2 with ImplicitKey

use of org.janusgraph.graphdb.types.system.ImplicitKey in project janusgraph by JanusGraph.

the class StandardJanusGraphTx method addProperty.

public JanusGraphVertexProperty addProperty(VertexProperty.Cardinality cardinality, JanusGraphVertex vertex, PropertyKey key, Object value, Long id) {
    if (key.cardinality().convert() != cardinality && cardinality != VertexProperty.Cardinality.single)
        throw new SchemaViolationException("Key is defined for %s cardinality which conflicts with specified: %s", key.cardinality(), cardinality);
    verifyWriteAccess(vertex);
    Preconditions.checkArgument(!(key instanceof ImplicitKey), "Cannot create a property of implicit type: %s", key.name());
    vertex = ((InternalVertex) vertex).it();
    Preconditions.checkNotNull(key);
    checkPropertyConstraintForVertexOrCreatePropertyConstraint(vertex, key);
    final Object normalizedValue = verifyAttribute(key, value);
    Cardinality keyCardinality = key.cardinality();
    // Determine unique indexes
    final List<IndexLockTuple> uniqueIndexTuples = new ArrayList<>();
    for (CompositeIndexType index : TypeUtil.getUniqueIndexes(key)) {
        IndexSerializer.IndexRecords matches = IndexSerializer.indexMatches(vertex, index, key, normalizedValue);
        for (Object[] match : matches.getRecordValues()) uniqueIndexTuples.add(new IndexLockTuple(index, match));
    }
    TransactionLock uniqueLock = getUniquenessLock(vertex, (InternalRelationType) key, normalizedValue);
    // Add locks for unique indexes
    for (IndexLockTuple lockTuple : uniqueIndexTuples) uniqueLock = new CombinerLock(uniqueLock, getLock(lockTuple), times);
    uniqueLock.lock(LOCK_TIMEOUT);
    try {
        // //Check vertex-centric uniqueness -> this doesn't really make sense to check
        // if (config.hasVerifyUniqueness()) {
        // if (cardinality == Cardinality.SINGLE) {
        // if (!Iterables.isEmpty(query(vertex).type(key).properties()))
        // throw new SchemaViolationException("A property with the given key [%s] already exists on the vertex [%s] and the property key is defined as single-valued", key.name(), vertex);
        // }
        // if (cardinality == Cardinality.SET) {
        // if (!Iterables.isEmpty(Iterables.filter(query(vertex).type(key).properties(), new Predicate<JanusGraphVertexProperty>() {
        // @Override
        // public boolean apply(@Nullable JanusGraphVertexProperty janusgraphProperty) {
        // return normalizedValue.equals(janusgraphProperty.value());
        // }
        // })))
        // throw new SchemaViolationException("A property with the given key [%s] and value [%s] already exists on the vertex and the property key is defined as set-valued", key.name(), normalizedValue);
        // }
        // }
        long propId = id == null ? IDManager.getTemporaryRelationID(temporaryIds.nextID()) : id;
        StandardVertexProperty prop = new StandardVertexProperty(propId, key, (InternalVertex) vertex, normalizedValue, ElementLifeCycle.New);
        if (config.hasAssignIDsImmediately() && id == null)
            graph.assignID(prop);
        // Delete properties if the cardinality is restricted
        if (cardinality == VertexProperty.Cardinality.single || cardinality == VertexProperty.Cardinality.set) {
            Consumer<JanusGraphVertexProperty> propertyRemover = JanusGraphVertexProperty.getRemover(cardinality, normalizedValue);
            if ((!config.hasVerifyUniqueness() || ((InternalRelationType) key).getConsistencyModifier() != ConsistencyModifier.LOCK) && !TypeUtil.hasAnyIndex(key) && cardinality == keyCardinality.convert()) {
                // Only delete in-memory so as to not trigger a read from the database which isn't necessary because we will overwrite blindly
                // We need to label the new property as "upsert", so that in case property deletion happens, we not only delete this new
                // in-memory property, but also read from database to delete the old value (if exists)
                ((InternalVertex) vertex).getAddedRelations(p -> p.getType().equals(key)).forEach(p -> propertyRemover.accept((JanusGraphVertexProperty) p));
                prop.setUpsert(true);
            } else {
                ((InternalVertex) vertex).query().types(key).properties().forEach(propertyRemover);
            }
        }
        // Check index uniqueness
        if (config.hasVerifyUniqueness()) {
            // Check all unique indexes
            for (IndexLockTuple lockTuple : uniqueIndexTuples) {
                if (!Iterables.isEmpty(IndexHelper.getQueryResults(lockTuple.getIndex(), lockTuple.getAll(), this)))
                    throw new SchemaViolationException("Adding this property for key [%s] and value [%s] violates a uniqueness constraint [%s]", key.name(), normalizedValue, lockTuple.getIndex());
            }
        }
        connectRelation(prop);
        return prop;
    } finally {
        uniqueLock.unlock();
    }
}
Also used : InternalVertex(org.janusgraph.graphdb.internal.InternalVertex) PredicateCondition(org.janusgraph.graphdb.query.condition.PredicateCondition) CacheVertex(org.janusgraph.graphdb.vertices.CacheVertex) JanusGraphVertex(org.janusgraph.core.JanusGraphVertex) EdgeLabelVertex(org.janusgraph.graphdb.types.vertices.EdgeLabelVertex) StringUtils(org.apache.commons.lang3.StringUtils) AddedRelationsContainer(org.janusgraph.graphdb.transaction.addedrelations.AddedRelationsContainer) CombinerLock(org.janusgraph.graphdb.transaction.lock.CombinerLock) MixedIndexCountQuery(org.janusgraph.core.MixedIndexCountQuery) SystemTypeManager(org.janusgraph.graphdb.types.system.SystemTypeManager) Cardinality(org.janusgraph.core.Cardinality) TypeDefinitionCategory(org.janusgraph.graphdb.types.TypeDefinitionCategory) StandardVertex(org.janusgraph.graphdb.vertices.StandardVertex) InternalRelation(org.janusgraph.graphdb.internal.InternalRelation) Duration(java.time.Duration) Map(java.util.Map) IndexType(org.janusgraph.graphdb.types.IndexType) ConcurrentIndexCache(org.janusgraph.graphdb.transaction.indexcache.ConcurrentIndexCache) TransactionLock(org.janusgraph.graphdb.transaction.lock.TransactionLock) And(org.janusgraph.graphdb.query.condition.And) StandardVertexProperty(org.janusgraph.graphdb.relations.StandardVertexProperty) PropertyKey(org.janusgraph.core.PropertyKey) TimestampProvider(org.janusgraph.diskstorage.util.time.TimestampProvider) StandardJanusGraph(org.janusgraph.graphdb.database.StandardJanusGraph) BaseLabel(org.janusgraph.graphdb.types.system.BaseLabel) Set(java.util.Set) EdgeSerializer(org.janusgraph.graphdb.database.EdgeSerializer) EdgeLabel(org.janusgraph.core.EdgeLabel) JanusGraphVertexProperty(org.janusgraph.core.JanusGraphVertexProperty) EdgeLabelMaker(org.janusgraph.core.schema.EdgeLabelMaker) IndexCache(org.janusgraph.graphdb.transaction.indexcache.IndexCache) ProfiledIterator(org.janusgraph.graphdb.util.ProfiledIterator) IndexQueryBuilder(org.janusgraph.graphdb.query.graph.IndexQueryBuilder) JanusGraphRelation(org.janusgraph.core.JanusGraphRelation) FakeLock(org.janusgraph.graphdb.transaction.lock.FakeLock) LongArrayList(com.carrotsearch.hppc.LongArrayList) Iterables(com.google.common.collect.Iterables) IndexSerializer(org.janusgraph.graphdb.database.IndexSerializer) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) JanusGraphIndexQuery(org.janusgraph.core.JanusGraphIndexQuery) NonBlockingHashMap(org.jctools.maps.NonBlockingHashMap) SchemaInspector(org.janusgraph.core.schema.SchemaInspector) VertexCentricQueryBuilder(org.janusgraph.graphdb.query.vertex.VertexCentricQueryBuilder) Cmp(org.janusgraph.core.attribute.Cmp) ConsistencyModifier(org.janusgraph.core.schema.ConsistencyModifier) EntryList(org.janusgraph.diskstorage.EntryList) JanusGraphException(org.janusgraph.core.JanusGraphException) StandardEdgeLabelMaker(org.janusgraph.graphdb.types.StandardEdgeLabelMaker) EmptySubqueryCache(org.janusgraph.graphdb.transaction.subquerycache.EmptySubqueryCache) Nullable(javax.annotation.Nullable) JanusGraphElement(org.janusgraph.core.JanusGraphElement) IDPool(org.janusgraph.graphdb.database.idassigner.IDPool) QueryUtil(org.janusgraph.graphdb.query.QueryUtil) PropertyKeyVertex(org.janusgraph.graphdb.types.vertices.PropertyKeyVertex) JanusGraphMultiVertexQuery(org.janusgraph.core.JanusGraphMultiVertexQuery) SimpleAddedRelations(org.janusgraph.graphdb.transaction.addedrelations.SimpleAddedRelations) RelationIdentifierUtils(org.janusgraph.graphdb.relations.RelationIdentifierUtils) CompositeIndexType(org.janusgraph.graphdb.types.CompositeIndexType) JanusGraphSchemaCategory(org.janusgraph.graphdb.internal.JanusGraphSchemaCategory) RelationComparator(org.janusgraph.graphdb.relations.RelationComparator) TypeDefinitionDescription(org.janusgraph.graphdb.types.TypeDefinitionDescription) EmptyAddedRelations(org.janusgraph.graphdb.transaction.addedrelations.EmptyAddedRelations) SimpleIndexCache(org.janusgraph.graphdb.transaction.indexcache.SimpleIndexCache) AtomicLong(java.util.concurrent.atomic.AtomicLong) Direction(org.apache.tinkerpop.gremlin.structure.Direction) Retriever(org.janusgraph.util.datastructures.Retriever) InternalVertexLabel(org.janusgraph.graphdb.internal.InternalVertexLabel) ConcurrentAddedRelations(org.janusgraph.graphdb.transaction.addedrelations.ConcurrentAddedRelations) SubqueryIterator(org.janusgraph.graphdb.util.SubqueryIterator) LockTuple(org.janusgraph.graphdb.transaction.lock.LockTuple) Preconditions(com.google.common.base.Preconditions) VertexLabel(org.janusgraph.core.VertexLabel) GraphCentricQuery(org.janusgraph.graphdb.query.graph.GraphCentricQuery) VertexCentricQuery(org.janusgraph.graphdb.query.vertex.VertexCentricQuery) BaseKey(org.janusgraph.graphdb.types.system.BaseKey) TypeDefinitionMap(org.janusgraph.graphdb.types.TypeDefinitionMap) LoggerFactory(org.slf4j.LoggerFactory) VertexLabelMaker(org.janusgraph.core.schema.VertexLabelMaker) QueryExecutor(org.janusgraph.graphdb.query.QueryExecutor) MetricManager(org.janusgraph.util.stats.MetricManager) JanusGraphEdge(org.janusgraph.core.JanusGraphEdge) MixedIndexCountQueryBuilder(org.janusgraph.graphdb.query.graph.MixedIndexCountQueryBuilder) SystemRelationType(org.janusgraph.graphdb.types.system.SystemRelationType) JanusGraphSchemaElement(org.janusgraph.core.schema.JanusGraphSchemaElement) MetricsQueryExecutor(org.janusgraph.graphdb.query.MetricsQueryExecutor) ReentrantTransactionLock(org.janusgraph.graphdb.transaction.lock.ReentrantTransactionLock) AttributeHandler(org.janusgraph.graphdb.database.serialize.AttributeHandler) TypeInspector(org.janusgraph.graphdb.types.TypeInspector) Multiplicity(org.janusgraph.core.Multiplicity) RelationType(org.janusgraph.core.RelationType) Property(org.apache.tinkerpop.gremlin.structure.Property) ElementLifeCycle(org.janusgraph.graphdb.internal.ElementLifeCycle) SchemaViolationException(org.janusgraph.core.SchemaViolationException) VertexCache(org.janusgraph.graphdb.transaction.vertexcache.VertexCache) ImmutableMap(com.google.common.collect.ImmutableMap) PropertyKeyMaker(org.janusgraph.core.schema.PropertyKeyMaker) Collection(java.util.Collection) SliceQuery(org.janusgraph.diskstorage.keycolumnvalue.SliceQuery) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Connection(org.janusgraph.core.Connection) JanusGraphSchemaVertex(org.janusgraph.graphdb.types.vertices.JanusGraphSchemaVertex) StandardPropertyKeyMaker(org.janusgraph.graphdb.types.StandardPropertyKeyMaker) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) List(java.util.List) RelationIdentifier(org.janusgraph.graphdb.relations.RelationIdentifier) ImplicitKey(org.janusgraph.graphdb.types.system.ImplicitKey) GraphCentricQueryBuilder(org.janusgraph.graphdb.query.graph.GraphCentricQueryBuilder) InternalRelationType(org.janusgraph.graphdb.internal.InternalRelationType) IndexHelper(org.janusgraph.graphdb.util.IndexHelper) ConditionUtil(org.janusgraph.graphdb.query.condition.ConditionUtil) JointIndexQuery(org.janusgraph.graphdb.query.graph.JointIndexQuery) Condition(org.janusgraph.graphdb.query.condition.Condition) VertexCentricEdgeIterable(org.janusgraph.graphdb.util.VertexCentricEdgeIterable) IndexTransaction(org.janusgraph.diskstorage.indexing.IndexTransaction) BackendTransaction(org.janusgraph.diskstorage.BackendTransaction) IDManager(org.janusgraph.graphdb.idmanagement.IDManager) VertexLabelVertex(org.janusgraph.graphdb.types.VertexLabelVertex) PreloadedVertex(org.janusgraph.graphdb.vertices.PreloadedVertex) HashMap(java.util.HashMap) Function(java.util.function.Function) StandardEdge(org.janusgraph.graphdb.relations.StandardEdge) ConcurrentMap(java.util.concurrent.ConcurrentMap) VertexProperty(org.apache.tinkerpop.gremlin.structure.VertexProperty) StandardVertexLabelMaker(org.janusgraph.graphdb.types.StandardVertexLabelMaker) IndexLockTuple(org.janusgraph.graphdb.transaction.lock.IndexLockTuple) MultiVertexCentricQueryBuilder(org.janusgraph.graphdb.query.vertex.MultiVertexCentricQueryBuilder) RelationCategory(org.janusgraph.graphdb.internal.RelationCategory) IndexSelectionStrategy(org.janusgraph.graphdb.query.index.IndexSelectionStrategy) NoSuchElementException(java.util.NoSuchElementException) JanusGraphBlueprintsTransaction(org.janusgraph.graphdb.tinkerpop.JanusGraphBlueprintsTransaction) BackendException(org.janusgraph.diskstorage.BackendException) TypeUtil(org.janusgraph.graphdb.types.TypeUtil) EmptyVertexCache(org.janusgraph.graphdb.transaction.vertexcache.EmptyVertexCache) QueryProfiler(org.janusgraph.graphdb.query.profile.QueryProfiler) Logger(org.slf4j.Logger) Iterator(java.util.Iterator) Query(org.janusgraph.graphdb.query.Query) BaseVertexLabel(org.janusgraph.graphdb.types.system.BaseVertexLabel) SubqueryCache(org.janusgraph.graphdb.transaction.subquerycache.SubqueryCache) ElementCategory(org.janusgraph.graphdb.internal.ElementCategory) Consumer(java.util.function.Consumer) EmptyIndexCache(org.janusgraph.graphdb.transaction.indexcache.EmptyIndexCache) GuavaVertexCache(org.janusgraph.graphdb.transaction.vertexcache.GuavaVertexCache) Collections(java.util.Collections) GuavaSubqueryCache(org.janusgraph.graphdb.transaction.subquerycache.GuavaSubqueryCache) ReadOnlyTransactionException(org.janusgraph.core.ReadOnlyTransactionException) Cardinality(org.janusgraph.core.Cardinality) IndexSerializer(org.janusgraph.graphdb.database.IndexSerializer) LongArrayList(com.carrotsearch.hppc.LongArrayList) ArrayList(java.util.ArrayList) StandardVertexProperty(org.janusgraph.graphdb.relations.StandardVertexProperty) IndexLockTuple(org.janusgraph.graphdb.transaction.lock.IndexLockTuple) JanusGraphVertexProperty(org.janusgraph.core.JanusGraphVertexProperty) CombinerLock(org.janusgraph.graphdb.transaction.lock.CombinerLock) CompositeIndexType(org.janusgraph.graphdb.types.CompositeIndexType) SchemaViolationException(org.janusgraph.core.SchemaViolationException) ImplicitKey(org.janusgraph.graphdb.types.system.ImplicitKey) TransactionLock(org.janusgraph.graphdb.transaction.lock.TransactionLock) ReentrantTransactionLock(org.janusgraph.graphdb.transaction.lock.ReentrantTransactionLock)

Example 3 with ImplicitKey

use of org.janusgraph.graphdb.types.system.ImplicitKey in project janusgraph by JanusGraph.

the class EdgeSerializer method parseRelation.

@Override
public RelationCache parseRelation(Entry data, boolean excludeProperties, TypeInspector tx) {
    ReadBuffer in = data.asReadBuffer();
    RelationTypeParse typeAndDir = IDHandler.readRelationType(in);
    long typeId = typeAndDir.typeId;
    Direction dir = typeAndDir.dirID.getDirection();
    RelationType relationType = tx.getExistingRelationType(typeId);
    InternalRelationType def = (InternalRelationType) relationType;
    Multiplicity multiplicity = def.multiplicity();
    long[] keySignature = def.getSortKey();
    long relationId;
    Object other;
    int startKeyPos = in.getPosition();
    int endKeyPos = 0;
    if (relationType.isEdgeLabel()) {
        long otherVertexId;
        if (multiplicity.isConstrained()) {
            if (multiplicity.isUnique(dir)) {
                otherVertexId = VariableLong.readPositive(in);
            } else {
                in.movePositionTo(data.getValuePosition());
                otherVertexId = VariableLong.readPositiveBackward(in);
                in.movePositionTo(data.getValuePosition());
            }
            relationId = VariableLong.readPositive(in);
        } else {
            in.movePositionTo(data.getValuePosition());
            relationId = VariableLong.readPositiveBackward(in);
            otherVertexId = VariableLong.readPositiveBackward(in);
            endKeyPos = in.getPosition();
            in.movePositionTo(data.getValuePosition());
        }
        other = otherVertexId;
    } else {
        assert relationType.isPropertyKey();
        PropertyKey key = (PropertyKey) relationType;
        if (multiplicity.isConstrained()) {
            other = readPropertyValue(in, key);
            relationId = VariableLong.readPositive(in);
        } else {
            in.movePositionTo(data.getValuePosition());
            relationId = VariableLong.readPositiveBackward(in);
            endKeyPos = in.getPosition();
            in.movePositionTo(data.getValuePosition());
            other = readPropertyValue(in, key);
        }
        Preconditions.checkNotNull(other, "Encountered error in deserializer [null value returned]. Check serializer compatibility.");
    }
    if (!excludeProperties) {
        LongObjectHashMap<Object> properties = new LongObjectHashMap<>(4);
        if (!multiplicity.isConstrained() && keySignature.length > 0) {
            int currentPos = in.getPosition();
            // Read sort key which only exists if type is not unique in this direction
            assert endKeyPos > startKeyPos;
            // after reading the ids, we are on the last byte of the key
            int keyLength = endKeyPos - startKeyPos;
            in.movePositionTo(startKeyPos);
            ReadBuffer inKey = in;
            if (def.getSortOrder() == Order.DESC)
                inKey = in.subrange(keyLength, true);
            readInlineTypes(keySignature, properties, inKey, tx, InlineType.KEY);
            in.movePositionTo(currentPos);
        }
        // read value signature
        readInlineTypes(def.getSignature(), properties, in, tx, InlineType.SIGNATURE);
        // Third: read rest
        while (in.hasRemaining()) {
            PropertyKey type = tx.getExistingPropertyKey(IDHandler.readInlineRelationType(in));
            Object propertyValue = readInline(in, type, InlineType.NORMAL);
            assert propertyValue != null;
            properties.put(type.longId(), propertyValue);
        }
        if (data.hasMetaData()) {
            for (Map.Entry<EntryMetaData, Object> metas : data.getMetaData().entrySet()) {
                ImplicitKey key = ImplicitKey.MetaData2ImplicitKey.get(metas.getKey());
                if (key != null) {
                    assert metas.getValue() != null;
                    properties.put(key.longId(), metas.getValue());
                }
            }
        }
        return new RelationCache(dir, typeId, relationId, other, properties);
    } else {
        return new RelationCache(dir, typeId, relationId, other);
    }
}
Also used : LongObjectHashMap(com.carrotsearch.hppc.LongObjectHashMap) RelationCache(org.janusgraph.graphdb.relations.RelationCache) EdgeDirection(org.janusgraph.graphdb.relations.EdgeDirection) Direction(org.apache.tinkerpop.gremlin.structure.Direction) EntryMetaData(org.janusgraph.diskstorage.EntryMetaData) ReadBuffer(org.janusgraph.diskstorage.ReadBuffer) RelationTypeParse(org.janusgraph.graphdb.database.idhandling.IDHandler.RelationTypeParse) Multiplicity(org.janusgraph.core.Multiplicity) RelationType(org.janusgraph.core.RelationType) InternalRelationType(org.janusgraph.graphdb.internal.InternalRelationType) InternalRelationType(org.janusgraph.graphdb.internal.InternalRelationType) Map(java.util.Map) LongObjectHashMap(com.carrotsearch.hppc.LongObjectHashMap) ImplicitKey(org.janusgraph.graphdb.types.system.ImplicitKey) PropertyKey(org.janusgraph.core.PropertyKey)

Example 4 with ImplicitKey

use of org.janusgraph.graphdb.types.system.ImplicitKey in project janusgraph by JanusGraph.

the class BasicVertexCentricQueryBuilder method constructQueryWithoutProfile.

protected BaseVertexCentricQuery constructQueryWithoutProfile(RelationCategory returnType) {
    assert returnType != null;
    Preconditions.checkArgument(adjacentVertex == null || returnType == RelationCategory.EDGE, "Vertex constraints only apply to edges");
    if (limit <= 0)
        return BaseVertexCentricQuery.emptyQuery();
    // Prepare direction
    if (returnType == RelationCategory.PROPERTY) {
        if (dir == Direction.IN)
            return BaseVertexCentricQuery.emptyQuery();
        dir = Direction.OUT;
    }
    // Prepare order
    orders.makeImmutable();
    assert orders.hasCommonOrder();
    // Prepare constraints
    And<JanusGraphRelation> conditions = QueryUtil.constraints2QNF(tx, constraints);
    if (conditions == null)
        return BaseVertexCentricQuery.emptyQuery();
    // Don't be smart with query limit adjustments - it just messes up the caching layer and
    // penalizes when appropriate limits are set by the user!
    int sliceLimit = limit;
    // Construct (optimal) SliceQueries
    EdgeSerializer serializer = tx.getEdgeSerializer();
    List<BackendQueryHolder<SliceQuery>> queries;
    if (!hasTypes()) {
        final BackendQueryHolder<SliceQuery> query = new BackendQueryHolder<>(serializer.getQuery(returnType, querySystem), (adjacentVertex == null && dir == Direction.BOTH || returnType == RelationCategory.PROPERTY && dir == Direction.OUT) && !conditions.hasChildren(), orders.isEmpty());
        if (sliceLimit != Query.NO_LIMIT && sliceLimit < Integer.MAX_VALUE / 3) {
            // half will be filtered
            if (dir != Direction.BOTH && (returnType == RelationCategory.EDGE || returnType == RelationCategory.RELATION)) {
                sliceLimit *= 2;
            }
        }
        query.getBackendQuery().setLimit(computeLimit(conditions.size(), sliceLimit));
        queries = ImmutableList.of(query);
        conditions.add(returnType);
        conditions.add(new VisibilityFilterCondition<>(// Need this to filter out newly created invisible relations in the transaction
        querySystem ? VisibilityFilterCondition.Visibility.SYSTEM : VisibilityFilterCondition.Visibility.NORMAL));
    } else {
        final Set<RelationType> ts = new HashSet<>(types.length);
        queries = new ArrayList<>(types.length + 2);
        final Map<RelationType, Interval> intervalConstraints = new HashMap<>(conditions.size());
        final boolean isIntervalFittedConditions = compileConstraints(conditions, intervalConstraints);
        for (Interval pint : intervalConstraints.values()) {
            // Check if one of the constraints leads to an empty result set
            if (pint.isEmpty())
                return BaseVertexCentricQuery.emptyQuery();
        }
        for (String typeName : types) {
            InternalRelationType type = QueryUtil.getType(tx, typeName);
            if (type == null)
                continue;
            Preconditions.checkArgument(!querySystem || (type instanceof SystemRelationType), "Can only query for system types: %s", type);
            if (type instanceof ImplicitKey) {
                throw new UnsupportedOperationException("Implicit types are not supported in complex queries: " + type);
            }
            ts.add(type);
            Direction typeDir = dir;
            if (type.isPropertyKey()) {
                Preconditions.checkArgument(returnType != RelationCategory.EDGE, "Querying for edges but including a property key: %s", type.name());
                returnType = RelationCategory.PROPERTY;
                typeDir = Direction.OUT;
            }
            if (type.isEdgeLabel()) {
                Preconditions.checkArgument(returnType != RelationCategory.PROPERTY, "Querying for properties but including an edge label: %s", type.name());
                returnType = RelationCategory.EDGE;
                if (!type.isUnidirected(Direction.BOTH)) {
                    // Make sure unidirectionality lines up
                    if (typeDir == Direction.BOTH) {
                        if (type.isUnidirected(Direction.OUT))
                            typeDir = Direction.OUT;
                        else
                            typeDir = Direction.IN;
                    } else // Directions are incompatible
                    if (!type.isUnidirected(typeDir))
                        continue;
                }
            }
            if (type.isEdgeLabel() && typeDir == Direction.BOTH && intervalConstraints.isEmpty() && orders.isEmpty()) {
                // TODO: This if-condition is a little too restrictive - we also want to include those cases where
                // there ARE intervalConstraints or orders but those cannot be covered by any sort-keys
                SliceQuery q = serializer.getQuery(type, typeDir, null);
                q.setLimit(sliceLimit);
                queries.add(new BackendQueryHolder<>(q, isIntervalFittedConditions, true));
            } else {
                // Optimize for each direction independently
                Direction[] dirs = { typeDir };
                if (typeDir == Direction.BOTH) {
                    if (type.isEdgeLabel())
                        dirs = new Direction[] { Direction.OUT, Direction.IN };
                    else
                        // property key
                        dirs = new Direction[] { Direction.OUT };
                }
                for (Direction direction : dirs) {
                    /*
                        Find best scoring relation type to answer this query with. We score each candidate by the number
                        of conditions that each sort-keys satisfy. Equality conditions score higher than interval
                        conditions since they are more restrictive. We assign additional points if the sort key
                        satisfies the order of this query.
                        */
                    InternalRelationType bestCandidate = null;
                    double bestScore = Double.NEGATIVE_INFINITY;
                    boolean bestCandidateSupportsOrder = false;
                    PropertyKey[] bestCandidateExtendedSortKey = null;
                    for (InternalRelationType candidate : type.getRelationIndexes()) {
                        // Filter out those that don't apply
                        if (!candidate.isUnidirected(Direction.BOTH) && !candidate.isUnidirected(direction)) {
                            continue;
                        }
                        if (!candidate.equals(type) && candidate.getStatus() != SchemaStatus.ENABLED)
                            continue;
                        boolean supportsOrder = orders.isEmpty() || orders.getCommonOrder() == candidate.getSortOrder();
                        int currentOrder = 0;
                        double score = 0.0;
                        PropertyKey[] extendedSortKey = getExtendedSortKey(candidate, direction, tx);
                        for (PropertyKey keyType : extendedSortKey) {
                            if (currentOrder < orders.size() && orders.getKey(currentOrder).equals(keyType))
                                currentOrder++;
                            Interval interval = intervalConstraints.get(keyType);
                            if (interval == null || !interval.isPoints()) {
                                if (interval != null)
                                    score += 1;
                                break;
                            } else {
                                assert interval.isPoints();
                                score += 5.0 / interval.getPoints().size();
                            }
                        }
                        if (supportsOrder && currentOrder == orders.size())
                            score += 3;
                        if (score > bestScore) {
                            bestScore = score;
                            bestCandidate = candidate;
                            bestCandidateSupportsOrder = supportsOrder && currentOrder == orders.size();
                            bestCandidateExtendedSortKey = extendedSortKey;
                        }
                    }
                    Preconditions.checkArgument(bestCandidate != null, "Current graph schema does not support the specified query constraints for type: %s", type.name());
                    // Construct sort key constraints for the best candidate and then serialize into a SliceQuery
                    // that is wrapped into a BackendQueryHolder
                    EdgeSerializer.TypedInterval[] sortKeyConstraints = new EdgeSerializer.TypedInterval[bestCandidateExtendedSortKey.length];
                    constructSliceQueries(bestCandidateExtendedSortKey, sortKeyConstraints, 0, bestCandidate, direction, intervalConstraints, sliceLimit, isIntervalFittedConditions, bestCandidateSupportsOrder, queries);
                }
            }
        }
        if (queries.isEmpty())
            return BaseVertexCentricQuery.emptyQuery();
        conditions.add(getTypeCondition(ts));
    }
    return new BaseVertexCentricQuery(QueryUtil.simplifyAnd(conditions), dir, queries, orders, limit);
}
Also used : HashMap(java.util.HashMap) Direction(org.apache.tinkerpop.gremlin.structure.Direction) SystemRelationType(org.janusgraph.graphdb.types.system.SystemRelationType) RelationType(org.janusgraph.core.RelationType) InternalRelationType(org.janusgraph.graphdb.internal.InternalRelationType) EdgeSerializer(org.janusgraph.graphdb.database.EdgeSerializer) ImplicitKey(org.janusgraph.graphdb.types.system.ImplicitKey) HashSet(java.util.HashSet) JanusGraphRelation(org.janusgraph.core.JanusGraphRelation) SliceQuery(org.janusgraph.diskstorage.keycolumnvalue.SliceQuery) SystemRelationType(org.janusgraph.graphdb.types.system.SystemRelationType) BackendQueryHolder(org.janusgraph.graphdb.query.BackendQueryHolder) InternalRelationType(org.janusgraph.graphdb.internal.InternalRelationType) PropertyKey(org.janusgraph.core.PropertyKey) PointInterval(org.janusgraph.util.datastructures.PointInterval) Interval(org.janusgraph.util.datastructures.Interval) RangeInterval(org.janusgraph.util.datastructures.RangeInterval)

Aggregations

Direction (org.apache.tinkerpop.gremlin.structure.Direction)4 PropertyKey (org.janusgraph.core.PropertyKey)4 ImplicitKey (org.janusgraph.graphdb.types.system.ImplicitKey)4 Multiplicity (org.janusgraph.core.Multiplicity)3 LongArrayList (com.carrotsearch.hppc.LongArrayList)2 HashMap (java.util.HashMap)2 Map (java.util.Map)2 JanusGraphVertexProperty (org.janusgraph.core.JanusGraphVertexProperty)2 RelationType (org.janusgraph.core.RelationType)2 InternalRelationType (org.janusgraph.graphdb.internal.InternalRelationType)2 LongHashSet (com.carrotsearch.hppc.LongHashSet)1 LongObjectHashMap (com.carrotsearch.hppc.LongObjectHashMap)1 LongSet (com.carrotsearch.hppc.LongSet)1 Preconditions (com.google.common.base.Preconditions)1 ImmutableMap (com.google.common.collect.ImmutableMap)1 Iterables (com.google.common.collect.Iterables)1 Sets (com.google.common.collect.Sets)1 Duration (java.time.Duration)1 ArrayList (java.util.ArrayList)1 Collection (java.util.Collection)1