Search in sources :

Example 1 with ScanJobFuture

use of org.janusgraph.diskstorage.keycolumnvalue.scan.ScanJobFuture in project janusgraph by JanusGraph.

the class JanusGraphTest method testMgmtRemoveGhostVertices.

/**
 * In this test, we deliberately create ghost vertices and use ManagementSystem to purge them
 * We use two concurrent transactions and let one transaction removes a vertex and another transaction
 * updates the same vertex. When the storage backend does not have locking support, both transactions
 * will succeed, and then the vertex becomes a ghost vertex.
 *
 * @throws ExecutionException
 * @throws InterruptedException
 */
@Test
public void testMgmtRemoveGhostVertices() throws ExecutionException, InterruptedException {
    if (features.hasLocking())
        return;
    final int numOfVertices = 100;
    final int numOfGhostVertices = 80;
    final int numOfRestVertices = numOfVertices - numOfGhostVertices;
    List<Vertex> vertices = new ArrayList<>(numOfVertices);
    for (int i = 0; i < numOfVertices; i++) {
        vertices.add(tx.traversal().addV("test").next());
    }
    tx.commit();
    JanusGraphTransaction tx1 = graph.newTransaction();
    for (int i = 0; i < numOfVertices; i++) {
        tx1.traversal().V(vertices.get(i)).property("prop", "val").next();
    }
    JanusGraphTransaction tx2 = graph.newTransaction();
    for (int i = 0; i < numOfGhostVertices; i++) {
        tx2.traversal().V(vertices.get(i)).next().remove();
    }
    tx2.commit();
    tx1.commit();
    JanusGraphManagement mgmt = graph.openManagement();
    ScanJobFuture future = mgmt.removeGhostVertices();
    assertEquals(numOfGhostVertices, future.get().getCustom(GhostVertexRemover.REMOVED_VERTEX_COUNT));
    assertEquals(numOfRestVertices, graph.traversal().V().count().next());
    assertEquals(numOfRestVertices, graph.traversal().V().hasLabel("test").count().next());
    assertEquals(numOfRestVertices, graph.traversal().V().has("prop", "val").count().next());
    assertEquals(numOfRestVertices, graph.traversal().V().hasLabel("test").has("prop", "val").count().next());
    // running it again, no vertex is removed
    assertEquals(0, mgmt.removeGhostVertices().get().getCustom(GhostVertexRemover.REMOVED_VERTEX_COUNT));
}
Also used : JanusGraphManagement(org.janusgraph.core.schema.JanusGraphManagement) CacheVertex(org.janusgraph.graphdb.vertices.CacheVertex) JanusGraphVertex(org.janusgraph.core.JanusGraphVertex) Vertex(org.apache.tinkerpop.gremlin.structure.Vertex) JanusGraphTransaction(org.janusgraph.core.JanusGraphTransaction) ArrayList(java.util.ArrayList) ScanJobFuture(org.janusgraph.diskstorage.keycolumnvalue.scan.ScanJobFuture) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) Test(org.junit.jupiter.api.Test)

Example 2 with ScanJobFuture

use of org.janusgraph.diskstorage.keycolumnvalue.scan.ScanJobFuture in project janusgraph by JanusGraph.

the class ManagementSystem method removeGhostVertices.

@Override
public ScanJobFuture removeGhostVertices(int numOfThreads) {
    StandardScanner.Builder builder = graph.getBackend().buildEdgeScanJob();
    builder.setJob(new GhostVertexRemover(graph));
    builder.setNumProcessingThreads(numOfThreads);
    ScanJobFuture future;
    try {
        future = builder.execute();
    } catch (BackendException e) {
        throw new JanusGraphException(e);
    }
    return future;
}
Also used : GhostVertexRemover(org.janusgraph.graphdb.olap.job.GhostVertexRemover) StandardScanner(org.janusgraph.diskstorage.keycolumnvalue.scan.StandardScanner) JanusGraphException(org.janusgraph.core.JanusGraphException) EmptyScanJobFuture(org.janusgraph.diskstorage.keycolumnvalue.scan.EmptyScanJobFuture) ScanJobFuture(org.janusgraph.diskstorage.keycolumnvalue.scan.ScanJobFuture) BackendException(org.janusgraph.diskstorage.BackendException)

Example 3 with ScanJobFuture

use of org.janusgraph.diskstorage.keycolumnvalue.scan.ScanJobFuture in project janusgraph by JanusGraph.

the class ManagementSystem method updateIndex.

@Override
public ScanJobFuture updateIndex(Index index, SchemaAction updateAction, int numOfThreads) {
    Preconditions.checkArgument(index != null, "Need to provide an index");
    Preconditions.checkArgument(updateAction != null, "Need to provide update action");
    JanusGraphSchemaVertex schemaVertex = getSchemaVertex(index);
    Set<JanusGraphSchemaVertex> dependentTypes;
    Set<PropertyKeyVertex> keySubset = Collections.emptySet();
    if (index instanceof RelationTypeIndex) {
        dependentTypes = Collections.singleton((JanusGraphSchemaVertex) ((InternalRelationType) schemaVertex).getBaseType());
        if (!updateAction.isApplicableStatus(schemaVertex.getStatus()))
            return null;
    } else if (index instanceof JanusGraphIndex) {
        IndexType indexType = schemaVertex.asIndexType();
        dependentTypes = new HashSet<>();
        if (indexType.isCompositeIndex()) {
            if (!updateAction.isApplicableStatus(schemaVertex.getStatus()))
                return null;
            for (PropertyKey key : ((JanusGraphIndex) index).getFieldKeys()) {
                dependentTypes.add((PropertyKeyVertex) key);
            }
        } else {
            keySubset = new HashSet<>();
            MixedIndexType mixedIndexType = (MixedIndexType) indexType;
            Set<SchemaStatus> applicableStatus = updateAction.getApplicableStatus();
            for (ParameterIndexField field : mixedIndexType.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;
    ScanJobFuture 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 EmptyScanJobFuture();
            break;
        case REINDEX:
            builder = graph.getBackend().buildEdgeScanJob();
            builder.setFinishJob(indexId.getIndexJobFinisher(graph, SchemaAction.ENABLE_INDEX));
            builder.setJobId(indexId);
            builder.setNumProcessingThreads(numOfThreads);
            builder.setJob(VertexJobConverter.convert(graph, new IndexRepairJob(indexId.indexName, indexId.relationTypeName)));
            try {
                future = builder.execute();
            } catch (BackendException e) {
                throw new JanusGraphException(e);
            }
            break;
        case ENABLE_INDEX:
            setStatus(schemaVertex, SchemaStatus.ENABLED, keySubset);
            updatedTypes.add(schemaVertex);
            if (!keySubset.isEmpty())
                updatedTypes.addAll(dependentTypes);
            future = new EmptyScanJobFuture();
            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 EmptyScanJobFuture();
            break;
        case REMOVE_INDEX:
            if (index instanceof RelationTypeIndex) {
                builder = graph.getBackend().buildEdgeScanJob();
            } else {
                JanusGraphIndex graphIndex = (JanusGraphIndex) index;
                if (graphIndex.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.setNumProcessingThreads(numOfThreads);
            builder.setJob(new IndexRemoveJob(graph, indexId.indexName, indexId.relationTypeName));
            try {
                future = builder.execute();
            } catch (BackendException e) {
                throw new JanusGraphException(e);
            }
            break;
        default:
            throw new UnsupportedOperationException("Update action not supported: " + updateAction);
    }
    return future;
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) MixedIndexType(org.janusgraph.graphdb.types.MixedIndexType) JanusGraphException(org.janusgraph.core.JanusGraphException) IndexRepairJob(org.janusgraph.graphdb.olap.job.IndexRepairJob) ParameterIndexField(org.janusgraph.graphdb.types.ParameterIndexField) RelationTypeIndex(org.janusgraph.core.schema.RelationTypeIndex) EmptyScanJobFuture(org.janusgraph.diskstorage.keycolumnvalue.scan.EmptyScanJobFuture) ScanJobFuture(org.janusgraph.diskstorage.keycolumnvalue.scan.ScanJobFuture) BackendException(org.janusgraph.diskstorage.BackendException) StandardScanner(org.janusgraph.diskstorage.keycolumnvalue.scan.StandardScanner) EmptyScanJobFuture(org.janusgraph.diskstorage.keycolumnvalue.scan.EmptyScanJobFuture) JanusGraphSchemaVertex(org.janusgraph.graphdb.types.vertices.JanusGraphSchemaVertex) PropertyKeyVertex(org.janusgraph.graphdb.types.vertices.PropertyKeyVertex) JanusGraphIndex(org.janusgraph.core.schema.JanusGraphIndex) IndexType(org.janusgraph.graphdb.types.IndexType) CompositeIndexType(org.janusgraph.graphdb.types.CompositeIndexType) MixedIndexType(org.janusgraph.graphdb.types.MixedIndexType) PropertyKey(org.janusgraph.core.PropertyKey) HashSet(java.util.HashSet) IndexRemoveJob(org.janusgraph.graphdb.olap.job.IndexRemoveJob)

Example 4 with ScanJobFuture

use of org.janusgraph.diskstorage.keycolumnvalue.scan.ScanJobFuture in project janusgraph by JanusGraph.

the class JanusGraphTest method testGotGIndexRemoval.

@Test
public void testGotGIndexRemoval() throws InterruptedException, ExecutionException {
    clopen(option(LOG_SEND_DELAY, MANAGEMENT_LOG), Duration.ZERO, option(KCVSLog.LOG_READ_LAG_TIME, MANAGEMENT_LOG), Duration.ofMillis(50), option(LOG_READ_INTERVAL, MANAGEMENT_LOG), Duration.ofMillis(250));
    final String name = "name";
    // Load Graph of the Gods
    GraphOfTheGodsFactory.loadWithoutMixedIndex(graph, // True makes the index on names unique.  Test fails when this is true.
    true);
    // Change to false and test will pass.
    newTx();
    finishSchema();
    JanusGraphIndex graphIndex = mgmt.getGraphIndex(name);
    // Sanity checks on the index that we assume GraphOfTheGodsFactory created
    assertNotNull(graphIndex);
    assertEquals(1, graphIndex.getFieldKeys().length);
    assertEquals(name, graphIndex.getFieldKeys()[0].name());
    assertEquals("internalindex", graphIndex.getBackingIndex());
    assertEquals(SchemaStatus.ENABLED, graphIndex.getIndexStatus(graphIndex.getFieldKeys()[0]));
    finishSchema();
    // Disable name index
    graphIndex = mgmt.getGraphIndex(name);
    mgmt.updateIndex(graphIndex, SchemaAction.DISABLE_INDEX);
    mgmt.commit();
    tx.commit();
    ManagementUtil.awaitGraphIndexUpdate(graph, name, 5, ChronoUnit.SECONDS);
    finishSchema();
    // Remove name index
    graphIndex = mgmt.getGraphIndex(name);
    mgmt.updateIndex(graphIndex, SchemaAction.REMOVE_INDEX);
    ScanJobFuture graphMetrics = mgmt.getIndexJobStatus(graphIndex);
    finishSchema();
    // Should have deleted at least one record
    assertNotEquals(0, graphMetrics.get().getCustom(IndexRemoveJob.DELETED_RECORDS_COUNT));
}
Also used : JanusGraphIndex(org.janusgraph.core.schema.JanusGraphIndex) ScanJobFuture(org.janusgraph.diskstorage.keycolumnvalue.scan.ScanJobFuture) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) Test(org.junit.jupiter.api.Test)

Aggregations

ScanJobFuture (org.janusgraph.diskstorage.keycolumnvalue.scan.ScanJobFuture)4 JanusGraphException (org.janusgraph.core.JanusGraphException)2 JanusGraphIndex (org.janusgraph.core.schema.JanusGraphIndex)2 BackendException (org.janusgraph.diskstorage.BackendException)2 EmptyScanJobFuture (org.janusgraph.diskstorage.keycolumnvalue.scan.EmptyScanJobFuture)2 StandardScanner (org.janusgraph.diskstorage.keycolumnvalue.scan.StandardScanner)2 Test (org.junit.jupiter.api.Test)2 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)2 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 Set (java.util.Set)1 Vertex (org.apache.tinkerpop.gremlin.structure.Vertex)1 JanusGraphTransaction (org.janusgraph.core.JanusGraphTransaction)1 JanusGraphVertex (org.janusgraph.core.JanusGraphVertex)1 PropertyKey (org.janusgraph.core.PropertyKey)1 JanusGraphManagement (org.janusgraph.core.schema.JanusGraphManagement)1 RelationTypeIndex (org.janusgraph.core.schema.RelationTypeIndex)1 GhostVertexRemover (org.janusgraph.graphdb.olap.job.GhostVertexRemover)1 IndexRemoveJob (org.janusgraph.graphdb.olap.job.IndexRemoveJob)1 IndexRepairJob (org.janusgraph.graphdb.olap.job.IndexRepairJob)1