Search in sources :

Example 1 with BackendTransaction

use of com.thinkaurelius.titan.diskstorage.BackendTransaction in project titan by thinkaurelius.

the class StandardTitanGraph method commit.

public void commit(final Collection<InternalRelation> addedRelations, final Collection<InternalRelation> deletedRelations, final StandardTitanTx tx) {
    // Setup
    log.debug("Saving transaction. Added {}, removed {}", addedRelations.size(), deletedRelations.size());
    final BackendTransaction mutator = tx.getTxHandle();
    final boolean acquireLocks = tx.getConfiguration().hasAcquireLocks();
    // 1. Assign TitanVertex IDs
    if (!tx.getConfiguration().hasAssignIDsImmediately())
        idAssigner.assignIDs(addedRelations);
    Callable<List<StaticBuffer>> persist = new Callable<List<StaticBuffer>>() {

        @Override
        public List<StaticBuffer> call() throws Exception {
            // 2. Collect deleted edges
            ListMultimap<InternalVertex, InternalRelation> mutations = ArrayListMultimap.create();
            if (deletedRelations != null && !deletedRelations.isEmpty()) {
                for (InternalRelation del : deletedRelations) {
                    Preconditions.checkArgument(del.isRemoved());
                    for (int pos = 0; pos < del.getLen(); pos++) {
                        InternalVertex vertex = del.getVertex(pos);
                        if (pos == 0 || !del.isLoop())
                            mutations.put(vertex, del);
                        Direction dir = EdgeDirection.fromPosition(pos);
                        if (acquireLocks && del.getType().isUnique(dir) && ((InternalType) del.getType()).uniqueLock(dir)) {
                            Entry entry = edgeSerializer.writeRelation(del, pos, tx);
                            mutator.acquireEdgeLock(IDHandler.getKey(vertex.getID()), entry.getColumn(), entry.getValue());
                        }
                    }
                    // Update Indexes
                    if (del.isProperty()) {
                        if (acquireLocks)
                            indexSerializer.lockKeyedProperty((TitanProperty) del, mutator);
                    }
                }
            }
            ListMultimap<InternalType, InternalRelation> otherEdgeTypes = ArrayListMultimap.create();
            // 3. Sort Added Edges
            for (InternalRelation relation : addedRelations) {
                Preconditions.checkArgument(relation.isNew());
                TitanType type = relation.getType();
                // Give special treatment to edge type definitions
                if (SystemTypeManager.prepersistedSystemTypes.contains(type)) {
                    InternalType itype = (InternalType) relation.getVertex(0);
                    otherEdgeTypes.put(itype, relation);
                } else {
                    // STANDARD TitanRelation
                    for (int pos = 0; pos < relation.getLen(); pos++) {
                        InternalVertex vertex = relation.getVertex(pos);
                        if (pos == 0 || !relation.isLoop())
                            mutations.put(vertex, relation);
                        Direction dir = EdgeDirection.fromPosition(pos);
                        if (acquireLocks && relation.getType().isUnique(dir) && !vertex.isNew() && ((InternalType) relation.getType()).uniqueLock(dir)) {
                            Entry entry = edgeSerializer.writeRelation(relation, pos, tx);
                            mutator.acquireEdgeLock(IDHandler.getKey(vertex.getID()), entry.getColumn(), null);
                        }
                    }
                }
                // Update Indexes
                if (relation.isProperty()) {
                    if (acquireLocks)
                        indexSerializer.lockKeyedProperty((TitanProperty) relation, mutator);
                }
            }
            // 3. Persist
            List<StaticBuffer> mutatedVertexKeys = new ArrayList<StaticBuffer>();
            if (!otherEdgeTypes.isEmpty()) {
                mutatedVertexKeys.addAll(persist(otherEdgeTypes, tx));
                mutator.flush();
                // Register new keys with indexprovider
                for (InternalType itype : otherEdgeTypes.keySet()) {
                    if (itype.isPropertyKey() && itype.isNew())
                        indexSerializer.newPropertyKey((TitanKey) itype, mutator);
                }
            }
            if (!mutations.isEmpty())
                mutatedVertexKeys.addAll(persist(mutations, tx));
            mutator.commit();
            return mutatedVertexKeys;
        }

        @Override
        public String toString() {
            return "PersistingTransaction";
        }
    };
    List<StaticBuffer> mutatedVertexKeys = BackendOperation.execute(persist, maxWriteRetryAttempts, retryStorageWaitTime);
    for (StaticBuffer vertexKey : mutatedVertexKeys) edgeStoreCache.invalidate(vertexKey);
}
Also used : LongArrayList(com.carrotsearch.hppc.LongArrayList) ArrayList(java.util.ArrayList) InternalRelation(com.thinkaurelius.titan.graphdb.internal.InternalRelation) EdgeDirection(com.thinkaurelius.titan.graphdb.relations.EdgeDirection) Direction(com.tinkerpop.blueprints.Direction) Callable(java.util.concurrent.Callable) InternalType(com.thinkaurelius.titan.graphdb.internal.InternalType) InternalVertex(com.thinkaurelius.titan.graphdb.internal.InternalVertex) LongArrayList(com.carrotsearch.hppc.LongArrayList) ArrayList(java.util.ArrayList) List(java.util.List) StaticBuffer(com.thinkaurelius.titan.diskstorage.StaticBuffer) BackendTransaction(com.thinkaurelius.titan.diskstorage.BackendTransaction)

Example 2 with BackendTransaction

use of com.thinkaurelius.titan.diskstorage.BackendTransaction in project titan by thinkaurelius.

the class IndexRemoveJob method process.

@Override
public void process(StaticBuffer key, Map<SliceQuery, EntryList> entries, ScanMetrics metrics) {
    //The queries are already tailored enough => everything should be removed
    try {
        BackendTransaction mutator = writeTx.getTxHandle();
        final List<Entry> deletions;
        if (entries.size() == 1)
            deletions = Iterables.getOnlyElement(entries.values());
        else {
            int size = IteratorUtils.stream(entries.values().iterator()).map(e -> e.size()).reduce(0, (x, y) -> x + y);
            deletions = new ArrayList<>(size);
            entries.values().forEach(e -> deletions.addAll(e));
        }
        metrics.incrementCustom(DELETED_RECORDS_COUNT, deletions.size());
        if (isRelationTypeIndex()) {
            mutator.mutateEdges(key, KCVSCache.NO_ADDITIONS, deletions);
        } else {
            mutator.mutateIndex(key, KCVSCache.NO_ADDITIONS, deletions);
        }
    } catch (final Exception e) {
        mgmt.rollback();
        writeTx.rollback();
        metrics.incrementCustom(FAILED_TX);
        throw new TitanException(e.getMessage(), e);
    }
}
Also used : VertexJobConverter(com.thinkaurelius.titan.graphdb.olap.VertexJobConverter) Configuration(com.thinkaurelius.titan.diskstorage.configuration.Configuration) Iterables(com.google.common.collect.Iterables) StandardTitanTx(com.thinkaurelius.titan.graphdb.transaction.StandardTitanTx) Entry(com.thinkaurelius.titan.diskstorage.Entry) TitanSchemaVertex(com.thinkaurelius.titan.graphdb.types.vertices.TitanSchemaVertex) IndexSerializer(com.thinkaurelius.titan.graphdb.database.IndexSerializer) ScanJob(com.thinkaurelius.titan.diskstorage.keycolumnvalue.scan.ScanJob) SchemaStatus(com.thinkaurelius.titan.core.schema.SchemaStatus) QueryContainer(com.thinkaurelius.titan.graphdb.olap.QueryContainer) TitanException(com.thinkaurelius.titan.core.TitanException) ManagementSystem(com.thinkaurelius.titan.graphdb.database.management.ManagementSystem) ArrayList(java.util.ArrayList) GraphDatabaseConfiguration(com.thinkaurelius.titan.graphdb.configuration.GraphDatabaseConfiguration) ImmutableList(com.google.common.collect.ImmutableList) EntryList(com.thinkaurelius.titan.diskstorage.EntryList) RelationTypeIndex(com.thinkaurelius.titan.core.schema.RelationTypeIndex) IDManager(com.thinkaurelius.titan.graphdb.idmanagement.IDManager) Map(java.util.Map) KCVSCache(com.thinkaurelius.titan.diskstorage.keycolumnvalue.cache.KCVSCache) IteratorUtils(org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils) StaticBuffer(com.thinkaurelius.titan.diskstorage.StaticBuffer) RelationTypeIndexWrapper(com.thinkaurelius.titan.graphdb.database.management.RelationTypeIndexWrapper) InternalRelationType(com.thinkaurelius.titan.graphdb.internal.InternalRelationType) BackendTransaction(com.thinkaurelius.titan.diskstorage.BackendTransaction) ConfigOption(com.thinkaurelius.titan.diskstorage.configuration.ConfigOption) Predicate(java.util.function.Predicate) TitanGraphIndex(com.thinkaurelius.titan.core.schema.TitanGraphIndex) CompositeIndexType(com.thinkaurelius.titan.graphdb.types.CompositeIndexType) SliceQuery(com.thinkaurelius.titan.diskstorage.keycolumnvalue.SliceQuery) Direction(org.apache.tinkerpop.gremlin.structure.Direction) List(java.util.List) IndexType(com.thinkaurelius.titan.graphdb.types.IndexType) ModifiableConfiguration(com.thinkaurelius.titan.diskstorage.configuration.ModifiableConfiguration) ConfigElement(com.thinkaurelius.titan.diskstorage.configuration.ConfigElement) ScanMetrics(com.thinkaurelius.titan.diskstorage.keycolumnvalue.scan.ScanMetrics) BufferUtil(com.thinkaurelius.titan.diskstorage.util.BufferUtil) Preconditions(com.google.common.base.Preconditions) StandardTitanGraph(com.thinkaurelius.titan.graphdb.database.StandardTitanGraph) TitanGraph(com.thinkaurelius.titan.core.TitanGraph) Entry(com.thinkaurelius.titan.diskstorage.Entry) TitanException(com.thinkaurelius.titan.core.TitanException) BackendTransaction(com.thinkaurelius.titan.diskstorage.BackendTransaction) TitanException(com.thinkaurelius.titan.core.TitanException)

Example 3 with BackendTransaction

use of com.thinkaurelius.titan.diskstorage.BackendTransaction in project titan by thinkaurelius.

the class IndexRepairJob method process.

@Override
public void process(TitanVertex vertex, ScanMetrics metrics) {
    try {
        BackendTransaction mutator = writeTx.getTxHandle();
        if (index instanceof RelationTypeIndex) {
            RelationTypeIndexWrapper wrapper = (RelationTypeIndexWrapper) index;
            InternalRelationType wrappedType = wrapper.getWrappedType();
            EdgeSerializer edgeSerializer = writeTx.getEdgeSerializer();
            List<Entry> additions = new ArrayList<>();
            for (TitanRelation relation : vertex.query().types(indexRelationTypeName).direction(Direction.OUT).relations()) {
                InternalRelation titanRelation = (InternalRelation) relation;
                for (int pos = 0; pos < titanRelation.getArity(); pos++) {
                    if (!wrappedType.isUnidirected(Direction.BOTH) && !wrappedType.isUnidirected(EdgeDirection.fromPosition(pos)))
                        //Directionality is not covered
                        continue;
                    Entry entry = edgeSerializer.writeRelation(titanRelation, wrappedType, pos, writeTx);
                    additions.add(entry);
                }
            }
            StaticBuffer vertexKey = writeTx.getIdInspector().getKey(vertex.longId());
            mutator.mutateEdges(vertexKey, additions, KCVSCache.NO_DELETIONS);
            metrics.incrementCustom(ADDED_RECORDS_COUNT, additions.size());
        } else if (index instanceof TitanGraphIndex) {
            IndexType indexType = mgmt.getSchemaVertex(index).asIndexType();
            assert indexType != null;
            IndexSerializer indexSerializer = graph.getIndexSerializer();
            //Gather elements to index
            List<TitanElement> elements;
            switch(indexType.getElement()) {
                case VERTEX:
                    elements = ImmutableList.of(vertex);
                    break;
                case PROPERTY:
                    elements = Lists.newArrayList();
                    for (TitanVertexProperty p : addIndexSchemaConstraint(vertex.query(), indexType).properties()) {
                        elements.add(p);
                    }
                    break;
                case EDGE:
                    elements = Lists.newArrayList();
                    for (TitanEdge e : addIndexSchemaConstraint(vertex.query().direction(Direction.OUT), indexType).edges()) {
                        elements.add(e);
                    }
                    break;
                default:
                    throw new AssertionError("Unexpected category: " + indexType.getElement());
            }
            if (indexType.isCompositeIndex()) {
                for (TitanElement element : elements) {
                    Set<IndexSerializer.IndexUpdate<StaticBuffer, Entry>> updates = indexSerializer.reindexElement(element, (CompositeIndexType) indexType);
                    for (IndexSerializer.IndexUpdate<StaticBuffer, Entry> update : updates) {
                        log.debug("Mutating index {}: {}", indexType, update.getEntry());
                        mutator.mutateIndex(update.getKey(), Lists.newArrayList(update.getEntry()), KCVSCache.NO_DELETIONS);
                        metrics.incrementCustom(ADDED_RECORDS_COUNT);
                    }
                }
            } else {
                assert indexType.isMixedIndex();
                Map<String, Map<String, List<IndexEntry>>> documentsPerStore = new HashMap<>();
                for (TitanElement element : elements) {
                    indexSerializer.reindexElement(element, (MixedIndexType) indexType, documentsPerStore);
                    metrics.incrementCustom(DOCUMENT_UPDATES_COUNT);
                }
                mutator.getIndexTransaction(indexType.getBackingIndexName()).restore(documentsPerStore);
            }
        } else
            throw new UnsupportedOperationException("Unsupported index found: " + index);
    } catch (final Exception e) {
        mgmt.rollback();
        writeTx.rollback();
        metrics.incrementCustom(FAILED_TX);
        throw new TitanException(e.getMessage(), e);
    }
}
Also used : InternalRelation(com.thinkaurelius.titan.graphdb.internal.InternalRelation) Entry(com.thinkaurelius.titan.diskstorage.Entry) IndexEntry(com.thinkaurelius.titan.diskstorage.indexing.IndexEntry) EdgeSerializer(com.thinkaurelius.titan.graphdb.database.EdgeSerializer) RelationTypeIndexWrapper(com.thinkaurelius.titan.graphdb.database.management.RelationTypeIndexWrapper) StaticBuffer(com.thinkaurelius.titan.diskstorage.StaticBuffer) ImmutableList(com.google.common.collect.ImmutableList) MixedIndexType(com.thinkaurelius.titan.graphdb.types.MixedIndexType) CompositeIndexType(com.thinkaurelius.titan.graphdb.types.CompositeIndexType) IndexType(com.thinkaurelius.titan.graphdb.types.IndexType) BackendTransaction(com.thinkaurelius.titan.diskstorage.BackendTransaction) MixedIndexType(com.thinkaurelius.titan.graphdb.types.MixedIndexType) IndexSerializer(com.thinkaurelius.titan.graphdb.database.IndexSerializer) CompositeIndexType(com.thinkaurelius.titan.graphdb.types.CompositeIndexType) InternalRelationType(com.thinkaurelius.titan.graphdb.internal.InternalRelationType)

Example 4 with BackendTransaction

use of com.thinkaurelius.titan.diskstorage.BackendTransaction in project titan by thinkaurelius.

the class StandardTitanGraph method persist.

private <V extends InternalVertex> List<StaticBuffer> persist(ListMultimap<V, InternalRelation> mutatedEdges, StandardTitanTx tx) throws StorageException {
    assert mutatedEdges != null && !mutatedEdges.isEmpty();
    Collection<V> vertices = mutatedEdges.keySet();
    BackendTransaction mutator = tx.getTxHandle();
    List<StaticBuffer> mutatedKeys = new ArrayList<StaticBuffer>(vertices.size());
    for (V vertex : vertices) {
        Preconditions.checkArgument(vertex.getID() > 0, "Vertex has no id: %s", vertex.getID());
        List<InternalRelation> edges = mutatedEdges.get(vertex);
        List<Entry> additions = new ArrayList<Entry>(edges.size());
        List<StaticBuffer> deletions = new ArrayList<StaticBuffer>(Math.max(10, edges.size() / 10));
        for (InternalRelation edge : edges) {
            for (int pos = 0; pos < edge.getLen(); pos++) {
                if (edge.getVertex(pos).equals(vertex)) {
                    if (edge.isRemoved()) {
                        deletions.add(edgeSerializer.writeRelation(edge, pos, tx).getColumn());
                    } else {
                        Preconditions.checkArgument(edge.isNew());
                        additions.add(edgeSerializer.writeRelation(edge, pos, tx));
                    }
                }
            }
        }
        StaticBuffer vertexKey = IDHandler.getKey(vertex.getID());
        mutator.mutateEdges(vertexKey, additions, deletions);
        if (!vertex.isNew())
            mutatedKeys.add(vertexKey);
        // Index Updates
        for (InternalRelation relation : edges) {
            if (relation.getVertex(0).equals(vertex)) {
                if (relation.isRemoved()) {
                    if (relation.isProperty()) {
                        indexSerializer.removeProperty((TitanProperty) relation, mutator);
                    } else if (relation.isEdge()) {
                        indexSerializer.removeEdge(relation, mutator);
                    }
                } else {
                    Preconditions.checkArgument(relation.isNew());
                    if (relation.isProperty()) {
                        indexSerializer.addProperty((TitanProperty) relation, mutator);
                    } else {
                        indexSerializer.addEdge(relation, mutator);
                    }
                }
            }
        }
    }
    return mutatedKeys;
}
Also used : LongArrayList(com.carrotsearch.hppc.LongArrayList) ArrayList(java.util.ArrayList) StaticBuffer(com.thinkaurelius.titan.diskstorage.StaticBuffer) InternalRelation(com.thinkaurelius.titan.graphdb.internal.InternalRelation) BackendTransaction(com.thinkaurelius.titan.diskstorage.BackendTransaction)

Aggregations

BackendTransaction (com.thinkaurelius.titan.diskstorage.BackendTransaction)4 StaticBuffer (com.thinkaurelius.titan.diskstorage.StaticBuffer)4 InternalRelation (com.thinkaurelius.titan.graphdb.internal.InternalRelation)3 ArrayList (java.util.ArrayList)3 LongArrayList (com.carrotsearch.hppc.LongArrayList)2 ImmutableList (com.google.common.collect.ImmutableList)2 Entry (com.thinkaurelius.titan.diskstorage.Entry)2 IndexSerializer (com.thinkaurelius.titan.graphdb.database.IndexSerializer)2 RelationTypeIndexWrapper (com.thinkaurelius.titan.graphdb.database.management.RelationTypeIndexWrapper)2 InternalRelationType (com.thinkaurelius.titan.graphdb.internal.InternalRelationType)2 CompositeIndexType (com.thinkaurelius.titan.graphdb.types.CompositeIndexType)2 IndexType (com.thinkaurelius.titan.graphdb.types.IndexType)2 Preconditions (com.google.common.base.Preconditions)1 Iterables (com.google.common.collect.Iterables)1 TitanException (com.thinkaurelius.titan.core.TitanException)1 TitanGraph (com.thinkaurelius.titan.core.TitanGraph)1 RelationTypeIndex (com.thinkaurelius.titan.core.schema.RelationTypeIndex)1 SchemaStatus (com.thinkaurelius.titan.core.schema.SchemaStatus)1 TitanGraphIndex (com.thinkaurelius.titan.core.schema.TitanGraphIndex)1 EntryList (com.thinkaurelius.titan.diskstorage.EntryList)1