private static int processDeltaResults(
      NodeCentricOperationContext connectionContext,
      Deltas deltas,
      boolean revisioned,
      boolean noRevisioned,
      Map<Long, NamedGraphRevision> idToGraphs)
      throws SQLException, AnzoException {
    long start = System.currentTimeMillis();

    ClosableIterator<SelectNamedGraphsResult> ngResults =
        ReplicationRdbWrapper.selectNamedGraphs(
            connectionContext.getStatementProvider(),
            connectionContext.getConnection(),
            connectionContext.getConfiguration().getSessionPrefix());
    for (SelectNamedGraphsResult ngResult : ngResults) {
      deltas.handleNamedGraph(
          ngResult.getNamedGraphid(),
          ngResult.getUuid(),
          ngResult.getRevision(),
          idToGraphs.get(ngResult.getNamedGraphid()));
    }
    int count = 0;

    if (noRevisioned) {
      ClosableIterator<SelectNewStatementsResult> resultSet =
          ReplicationRdbWrapper.selectNewStatements(
              connectionContext.getStatementProvider(),
              connectionContext.getConnection(),
              connectionContext.getConfiguration().getSessionPrefix());
      try {
        for (SelectNewStatementsResult result : resultSet) {
          deltas.handleStatement(
              true, result.getNamedGraphId(), result.getSubj(), result.getProp(), result.getObj());
          count++;
        }
      } finally {
        resultSet.close();
      }
      ClosableIterator<SelectNewStatementsNRResult> resultSet2 =
          ReplicationRdbWrapper.selectNewStatementsNR(
              connectionContext.getStatementProvider(),
              connectionContext.getConnection(),
              connectionContext.getConfiguration().getSessionPrefix());
      try {
        for (SelectNewStatementsNRResult result : resultSet2) {
          deltas.handleStatement(
              true, result.getNamedGraphId(), result.getSubj(), result.getProp(), result.getObj());
          count++;
        }
      } finally {
        resultSet2.close();
      }
    }
    if (revisioned) {
      ClosableIterator<SelectAllStatementResult> resultSet =
          ReplicationRdbWrapper.selectAllStatement(
              connectionContext.getStatementProvider(),
              connectionContext.getConnection(),
              connectionContext.getConfiguration().getSessionPrefix());
      try {
        for (SelectAllStatementResult result : resultSet) {
          deltas.handleStatement(
              (result.getRend() == null || result.getRend() == 0),
              result.getNamedGraphId(),
              result.getSubj(),
              result.getProp(),
              result.getObj());
          count++;
        }
      } finally {
        resultSet.close();
      }
    }
    if (log.isDebugEnabled()) {
      log.debug(
          LogUtils.RDB_MARKER,
          "[REPLICATE-GET_ALL_STATEMENTS] {}:{}",
          count,
          (System.currentTimeMillis() - start));
    }

    return count;
  }
  @Override
  protected void replicateInternal(
      IOperationContext context,
      Collection<NamedGraphRevision> newGraphs,
      Collection<NamedGraphRevision> diffGraphs,
      IReplicationHandler handler,
      ReplicationCache cache)
      throws AnzoException {
    NodeCentricOperationContext connectionContext = datasource.getQueryContext(context);
    long startAll = System.currentTimeMillis();
    int count = 0;
    try {
      Map<Long, NamedGraphRevision> idToGraphs = new HashMap<Long, NamedGraphRevision>();
      long revisionCount = diffGraphs.size();
      long norevisionCount = newGraphs.size();

      long start = System.currentTimeMillis();
      datasource.begin(connectionContext.getConnection(), false, false);
      try {
        StringBuilder sb = new StringBuilder("Replicating:");
        HashMap<URI, Boolean> newGraph = new HashMap<URI, Boolean>();
        for (NamedGraphRevision ngRevision : newGraphs) {
          newGraph.put(ngRevision.namedGraphUri, true);
          Long namedGraphId =
              connectionContext
                  .getNodeLayout()
                  .fetchId(ngRevision.namedGraphUri, connectionContext.getConnection());
          Long metadataId =
              connectionContext
                  .getNodeLayout()
                  .fetchId(ngRevision.metadataUri, connectionContext.getConnection());
          if (namedGraphId != null && metadataId != null) {
            idToGraphs.put(metadataId, ngRevision);
            idToGraphs.put(namedGraphId, ngRevision);

            long startInsertNamedGraphEntries = System.currentTimeMillis();
            long insertNamedGraphEntries =
                ReplicationRdbWrapper.insertNamedGraphNewRevisions(
                    connectionContext.getStatementProvider(),
                    connectionContext.getConnection(),
                    namedGraphId.toString(),
                    connectionContext.getConfiguration().getSessionPrefix(),
                    Long.toString(ngRevision.revision));
            if (log.isDebugEnabled()) {
              log.debug(
                  LogUtils.RDB_MARKER,
                  "[REPLICATE-INSERT_NAMEDGRAPH_ENTRIES] {}:{}",
                  insertNamedGraphEntries,
                  (System.currentTimeMillis() - startInsertNamedGraphEntries));
            }
            if (insertNamedGraphEntries == 0) {
              insertNamedGraphEntries =
                  ReplicationRdbWrapper.insertNamedGraphNRNewRevisions(
                      connectionContext.getStatementProvider(),
                      connectionContext.getConnection(),
                      namedGraphId.toString(),
                      connectionContext.getConfiguration().getSessionPrefix(),
                      Long.toString(ngRevision.revision));
              if (log.isDebugEnabled()) {
                log.debug(
                    LogUtils.RDB_MARKER,
                    "[REPLICATE-INSERT_NAMEDGRAPH_NR_ENTRIES] {}:{}",
                    insertNamedGraphEntries,
                    (System.currentTimeMillis() - startInsertNamedGraphEntries));
              }
            }
            sb.append(ngRevision.namedGraphUri + ",");
          }
        }
        for (NamedGraphRevision ngRevision : diffGraphs) {
          newGraph.put(ngRevision.namedGraphUri, false);
          Long namedGraphId =
              connectionContext
                  .getNodeLayout()
                  .fetchId(ngRevision.namedGraphUri, connectionContext.getConnection());
          Long metadataId =
              connectionContext
                  .getNodeLayout()
                  .fetchId(ngRevision.metadataUri, connectionContext.getConnection());
          if (namedGraphId != null && metadataId != null) {
            idToGraphs.put(metadataId, ngRevision);
            idToGraphs.put(namedGraphId, ngRevision);

            long startInsertNamedGraphEntries = System.currentTimeMillis();
            long insertNamedGraphEntries =
                ReplicationRdbWrapper.insertNamedGraphNewRevisions(
                    connectionContext.getStatementProvider(),
                    connectionContext.getConnection(),
                    namedGraphId.toString(),
                    connectionContext.getConfiguration().getSessionPrefix(),
                    Long.toString(ngRevision.revision));
            if (log.isDebugEnabled()) {
              log.debug(
                  LogUtils.RDB_MARKER,
                  "[REPLICATE-INSERT_NAMEDGRAPH_ENTRIES] {}:{}",
                  insertNamedGraphEntries,
                  (System.currentTimeMillis() - startInsertNamedGraphEntries));
            }
            if (insertNamedGraphEntries == 0) {
              insertNamedGraphEntries =
                  ReplicationRdbWrapper.insertNamedGraphNRNewRevisions(
                      connectionContext.getStatementProvider(),
                      connectionContext.getConnection(),
                      namedGraphId.toString(),
                      connectionContext.getConfiguration().getSessionPrefix(),
                      Long.toString(ngRevision.revision));
              if (log.isDebugEnabled()) {
                log.debug(
                    LogUtils.RDB_MARKER,
                    "[REPLICATE-INSERT_NAMEDGRAPH_NR_ENTRIES] {}:{}",
                    insertNamedGraphEntries,
                    (System.currentTimeMillis() - startInsertNamedGraphEntries));
              }
            }
            sb.append(ngRevision.namedGraphUri + ",");
          }
        }
        if (log.isDebugEnabled()) {
          log.debug(LogUtils.RDB_MARKER, "[REPLICATE-NAMEDGRAPHS] {}", sb.toString());
        }

        if (log.isDebugEnabled()) {
          log.debug(
              LogUtils.RDB_MARKER,
              "[REPLICATE-INSERT_REVISIONS] {}:{}",
              revisionCount + norevisionCount,
              (System.currentTimeMillis() - start));
        }

        long insertDeltaStatements = 0;
        long insertDeltaNRStatements = 0;
        if (revisionCount > 0) {
          long startInsertDeltaStatements = System.currentTimeMillis();
          insertDeltaStatements =
              ReplicationRdbWrapper.insertDeltaStatements(
                  connectionContext.getStatementProvider(),
                  connectionContext.getConnection(),
                  connectionContext.getConfiguration().getSessionPrefix());
          if (log.isDebugEnabled()) {
            log.debug(
                LogUtils.RDB_MARKER,
                "[REPLICATE-INSERT_DELTA_STATEMENTS] {}:{}",
                insertDeltaStatements,
                (System.currentTimeMillis() - startInsertDeltaStatements));
          }
          long startInsertDeltaNRStatements = System.currentTimeMillis();
          insertDeltaNRStatements =
              ReplicationRdbWrapper.insertDeltaNRStatements(
                  connectionContext.getStatementProvider(),
                  connectionContext.getConnection(),
                  connectionContext.getConfiguration().getSessionPrefix());
          if (log.isDebugEnabled()) {
            log.debug(
                LogUtils.RDB_MARKER,
                "[REPLICATE-INSERT_DELTA_NR_STATEMENTS] {}:{}",
                insertDeltaNRStatements,
                (System.currentTimeMillis() - startInsertDeltaNRStatements));
          }

          long startPurgeExtraStatements = System.currentTimeMillis();
          long purgeExtraStatements =
              ReplicationRdbWrapper.purgeExtraStatements(
                  connectionContext.getStatementProvider(),
                  connectionContext.getConnection(),
                  connectionContext.getConfiguration().getSessionPrefix());
          if (log.isDebugEnabled()) {
            log.debug(
                LogUtils.RDB_MARKER,
                "[REPLICATE-PURGE_EXTRA_STATEMENTS] {}:{}",
                purgeExtraStatements,
                (System.currentTimeMillis() - startPurgeExtraStatements));
          }
          insertDeltaStatements -= purgeExtraStatements;
        }
        if (insertDeltaStatements > 0 || insertDeltaNRStatements > 0 || norevisionCount > 0) {
          Deltas deltas = new Deltas(handler, connectionContext, newGraph, cache);
          count =
              processDeltaResults(
                  connectionContext,
                  deltas,
                  (insertDeltaStatements > 0 || insertDeltaNRStatements > 0),
                  (norevisionCount > 0),
                  idToGraphs);
          deltas.end();
        }
      } finally {
        // if (datasource.getConfiguration().getForceTempTablePurge()) {
        try {
          BaseSQL.truncateTableWithSessionMayCommit(
              datasource.getStatementProvider(),
              connectionContext.getConnection(),
              datasource.getConfiguration().getSessionPrefix(),
              "NGR_TMP");
          BaseSQL.truncateTableWithSessionMayCommit(
              datasource.getStatementProvider(),
              connectionContext.getConnection(),
              datasource.getConfiguration().getSessionPrefix(),
              "STMTS_REP_TMP");
        } catch (RdbException sqle) {
          log.error(LogUtils.RDB_MARKER, "Error clearing temporary tables", sqle);
        }
        // }
        datasource.commit(connectionContext.getConnection(), false, false);
      }

    } catch (SQLException sqle) {
      SQLException cause = sqle;
      while (cause != null) {
        log.error(LogUtils.RDB_MARKER, "SQL Error in replicate", cause);
        cause = cause.getNextException();
      }
      throw new AnzoException(
          ExceptionConstants.SERVER.REPLICATION_FAILED, sqle, sqle.getMessage());
    } finally {
      handler.end();
      if (log.isDebugEnabled()) {
        log.debug(
            LogUtils.RDB_MARKER,
            "[REPLICATE-TOTAL-TIME] {}:{}",
            count,
            (System.currentTimeMillis() - startAll));
      }
      if (connectionContext != null) {
        datasource.returnQueryContext(connectionContext);
      }
    }
  }