All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.signalcollect.triplerush.vertices.blocking.TripleAdditionSynchronizationVertex.scala Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2015 Cotiviti Labs ([email protected])
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.signalcollect.triplerush.vertices.blocking

import com.signalcollect.GraphEditor
import com.signalcollect.triplerush.TriplePattern
import com.signalcollect.triplerush.vertices.BaseVertex
import scala.concurrent.Promise
import com.signalcollect.triplerush.vertices.query.TicketSynchronization
import com.signalcollect.triplerush.BlockingIndexVertexEdge
import com.signalcollect.triplerush.EfficientIndexPattern
import com.signalcollect.triplerush.IndexStructure
import com.signalcollect.triplerush.OperationIds
import scala.util.Try
import scala.util.Failure
import scala.util.Success
import com.signalcollect.triplerush.IndexType
import com.signalcollect.triplerush.EfficientIndexPattern._

class TripleAdditionSynchronizationVertex(
    is: IndexStructure,
    triples: Iterator[TriplePattern],
    operationCompletedPromise: Promise[Unit],
    batchSize: Int = 10000) extends BaseVertex[Option[TicketSynchronization]] {

  val operationId = OperationIds.nextId
  val id = OperationIds.embedInLong(operationId)

  /**
   * Propagates an error in the passed code block to `operationCompletedPromise`.
   */
  private[this] def propagateError(graphEditor: GraphEditor[Long, Any])(f: => Unit): Unit = {
    val operationAttempt = Try(f)
    operationAttempt match {
      case Failure(f) =>
        operationCompletedPromise.tryFailure(f)
        graphEditor.removeVertex(id)
      case Success(()) =>
    }
  }

  def dispatchTripleAdditionBatch(graphEditor: GraphEditor[Long, Any]): Unit = {
    var dispatchedTriples = 0L
    while (triples.hasNext && dispatchedTriples < batchSize) {
      dispatchedTriples += 1
      val t = triples.next
      val parentIds = is.parentIds(t)
      for (indexId <- parentIds) {
        val indexType = IndexType(indexId)
        val delta = t.parentIdDelta(indexId.toTriplePattern)
        graphEditor.addEdge(indexId, new BlockingIndexVertexEdge(delta, is.ticketsForIndexOperation(indexType), operationId))
      }
    }
    val expectedTickets = dispatchedTriples * is.ticketsForTripleOperation
    val synchronization = new TicketSynchronization("BlockingTripleAdditionsVertex", expectedTickets)
    synchronization.onSuccess {
      propagateError(graphEditor) {
        if (triples.hasNext) {
          dispatchTripleAdditionBatch(graphEditor)
        } else {
          operationCompletedPromise.trySuccess(())
          graphEditor.removeVertex(id)
        }
      }
    }
    setState(Some(synchronization))
    synchronization.receive(0) // Immediately complete synchronization if the iterator was empty.
  }

  override def afterInitialization(graphEditor: GraphEditor[Long, Any]): Unit = {
    propagateError(graphEditor) {
      dispatchTripleAdditionBatch(graphEditor)
    }
  }

  override def deliverSignalWithoutSourceId(signal: Any, graphEditor: GraphEditor[Long, Any]): Boolean = {
    propagateError(graphEditor) {
      signal match {
        case deliveredTickets: Long =>
          state match {
            case None =>
              val msg = s"Blocking triple addition vertex received tickets when there was no ongoing synchronization."
              throw new Error(msg)
            case Some(s) =>
              s.receive(deliveredTickets)
          }
        case other @ _ =>
          throw new UnsupportedOperationException(
            s"Blocking triple addition vertex received an unsupported message $signal of type ${signal.getClass.getSimpleName}.")
      }
    }
    true
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy