Skip to content

Instantly share code, notes, and snippets.

@geeknam
Created December 14, 2017 03:09
Show Gist options
  • Select an option

  • Save geeknam/e77f4fb47b38e136bfe93cfa42e91339 to your computer and use it in GitHub Desktop.

Select an option

Save geeknam/e77f4fb47b38e136bfe93cfa42e91339 to your computer and use it in GitHub Desktop.

Revisions

  1. geeknam created this gist Dec 14, 2017.
    117 changes: 117 additions & 0 deletions janus-index.groovy
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,117 @@
    // for more debug logging, add this to ./conf/log4j-console.properties
    // log4j.logger.com.thinkaurelius.titan.graphdb.database.management=DEBUG

    // Open the graph
    graph = TitanFactory.build().set('storage.backend','inmemory').set('schema.default','none').set('query.force-index',true).open();
    g = graph.traversal()

    // Create an index on new property key. Index created on new property is ENABLED immediately.
    if (graph.getOpenTransactions()) graph.tx().rollback()
    mgmt = graph.openManagement()
    name = mgmt.makePropertyKey('name').dataType(String.class).cardinality(SINGLE).make()
    //nameIndex = mgmt.buildIndex('nameIndex', Vertex.class).addKey(name).buildCompositeIndex()
    //nameIndexStatus = nameIndex.getIndexStatus(name)
    mgmt.commit()

    // add some data, making sure to complete the transaction, otherwise index transitions will be blocked.
    maxnodes = 999
    (0..maxnodes).each{ graph.addVertex('name','person'+it) }; null;
    graph.tx().commit()

    // Create an index on existing property key. Index on existing property is INSTALLED initially.
    if (graph.getOpenTransactions()) graph.tx().rollback()
    mgmt = graph.openManagement()
    name = mgmt.getPropertyKey('name')
    nameIndex = mgmt.buildIndex('nameIndex', Vertex.class).addKey(name).unique().buildCompositeIndex()
    nameIndexStatus = nameIndex.getIndexStatus(name) // must be INSTALLED
    // don't seem to need to register index explicitly, but it is safe to do anyway
    if (nameIndexStatus == SchemaStatus.INSTALLED) mgmt.updateIndex(nameIndex, SchemaAction.REGISTER_INDEX)
    mgmt.commit()

    // Wait for index status to go from INSTALLED to REGISTERED
    // This transition will not happen if there are open transactions.
    if (nameIndexStatus == SchemaStatus.INSTALLED) mgmt.awaitGraphIndexStatus(graph, 'nameIndex').status(SchemaStatus.REGISTERED).call()

    // Verify index status is REGISTERED, then ENABLE it
    if (graph.getOpenTransactions()) graph.tx().rollback()
    mgmt = graph.openManagement()
    name = mgmt.getPropertyKey('name')
    nameIndex = mgmt.getGraphIndex('nameIndex')
    nameIndexStatus = nameIndex.getIndexStatus(name) // must be REGISTERED
    if (nameIndexStatus == SchemaStatus.REGISTERED) mgmt.updateIndex(nameIndex, SchemaAction.ENABLE_INDEX)
    mgmt.commit()

    // Wait for index status to go from REGISTERED to ENABLED
    if (nameIndexStatus == SchemaStatus.REGISTERED) mgmt.awaitGraphIndexStatus(graph, 'nameIndex').status(SchemaStatus.ENABLED).call()

    // Verify index status is ENABLED
    if (graph.getOpenTransactions()) graph.tx().rollback()
    mgmt = graph.openManagement()
    name = mgmt.getPropertyKey('name')
    nameIndex = mgmt.getGraphIndex('nameIndex') // should be ENABLED
    nameIndexStatus = nameIndex.getIndexStatus(name)
    mgmt.commit()

    // Since the data existed before the index was created, this will not return a result.
    g.V().has('name','person0').hasNext()
    g.V().has('name','person'+maxnodes).hasNext()
    graph.tx().rollback()

    // Rebuild the index by using REINDEX
    future = null
    if (graph.getOpenTransactions()) graph.tx().rollback()
    mgmt = graph.openManagement()
    name = mgmt.getPropertyKey('name')
    nameIndex = mgmt.getGraphIndex('nameIndex')
    nameIndexStatus = nameIndex.getIndexStatus(name) // must be ENABLED or REGISTERED
    if (nameIndexStatus == SchemaStatus.ENABLED) future = mgmt.updateIndex(nameIndex, SchemaAction.REINDEX)
    mgmt.commit()

    // Block until reindexing is complete, then report the metrics
    t = System.currentTimeMillis(); metrics = future.get(); 'reindexed in '+(System.currentTimeMillis()-t)+' ms'
    m = [:]; ['adds', 'doc-updates', 'success-tx', 'failed-tx'].each{ m[it] = metrics.getCustom(it) }; m

    // After reindexing, this should now return a result
    g.V().has('name','person0').properties()
    g.V().has('name','person'+maxnodes).properties()
    graph.tx().rollback()

    // Disable the index. Once the able is DISABLED, it cannot be re-enabled again!
    // Instead, you could build a new index with the same properties.
    future = null
    if (graph.getOpenTransactions()) graph.tx().rollback()
    mgmt = graph.openManagement()
    name = mgmt.getPropertyKey('name')
    nameIndex = mgmt.getGraphIndex('nameIndex')
    nameIndexStatus = nameIndex.getIndexStatus(name) // must be ENABLED, INSTALLED, or REGISTERED
    if (nameIndexStatus == SchemaStatus.INSTALLED || nameIndexStatus == SchemaStatus.ENABLED) future = mgmt.updateIndex(nameIndex, SchemaAction.DISABLE_INDEX)
    nameIndexStatus = nameIndex.getIndexStatus(name) // should be INSTALLED here
    mgmt.commit()

    // Block until disabling index is complete (ENABLED -> INSTALLED -> DISABLED), no metrics are reported (null)
    if (graph.getOpenTransactions()) graph.tx().rollback()
    t = System.currentTimeMillis(); metrics = future.get(); 'disabled in '+(System.currentTimeMillis()-t)+' ms'
    if (nameIndexStatus == SchemaStatus.ENABLED) mgmt.awaitGraphIndexStatus(graph, 'nameIndex').status(SchemaStatus.INSTALLED).call()
    if (nameIndexStatus == SchemaStatus.INSTALLED) mgmt.awaitGraphIndexStatus(graph, 'nameIndex').status(SchemaStatus.DISABLED).call()

    // Delete the index
    future = null
    if (graph.getOpenTransactions()) graph.tx().rollback()
    mgmt = graph.openManagement()
    name = mgmt.getPropertyKey('name')
    nameIndex = mgmt.getGraphIndex('nameIndex')
    nameIndexStatus = nameIndex.getIndexStatus(name) // must be DISABLED
    if (nameIndexStatus == SchemaStatus.DISABLED) future = mgmt.updateIndex(nameIndex, SchemaAction.REMOVE_INDEX)
    mgmt.commit()

    // Block until removing index is complete, then report the metrics
    t = System.currentTimeMillis(); metrics = future.get(); 'deleted in '+(System.currentTimeMillis()-t)+' ms'
    m = [:]; ['adds', 'doc-updates', 'success-tx', 'failed-tx'].each{ m[it] = metrics.getCustom(it) }; m

    // Verify index status is still DISABLED
    if (graph.getOpenTransactions()) graph.tx().rollback()
    mgmt = graph.openManagement()
    name = mgmt.getPropertyKey('name')
    nameIndex = mgmt.getGraphIndex('nameIndex')
    nameIndexStatus = nameIndex.getIndexStatus(name)
    mgmt.commit()