/**
   * Deletes documents from the activity engine
   *
   * @param uids
   */
  public void delete(long... uids) {
    boolean needToFlush = false;
    if (uids.length == 0) {
      return;
    }

    for (long uid : uids) {
      if (uid == Long.MIN_VALUE) {
        continue;
      }
      Lock writeLock = globalLock.writeLock();
      try {
        writeLock.lock();
        if (!uidToArrayIndex.containsKey(uid)) {
          continue;
        }
        deletedDocumentsCounter.inc();
        int index = uidToArrayIndex.remove(uid);
        for (ActivityValues activityIntValues : valuesMap.values()) {
          activityIntValues.delete(index);
        }
        needToFlush =
            needToFlush | pendingDeletes.addFieldUpdate(new Update(index, Long.MIN_VALUE));
      } finally {
        writeLock.unlock();
      }
    }
    if (needToFlush) {
      flush();
    }
  }
 private boolean updateActivities(Map<String, Object> map, int index) {
   boolean needToFlush = false;
   for (ActivityValues activityIntValues : valuesMap.values()) {
     Object value = map.get(activityIntValues.getFieldName());
     if (value != null) {
       needToFlush = needToFlush | activityIntValues.update(index, value);
     } else {
       needToFlush = needToFlush | activityIntValues.update(index, "+0");
     }
   }
   return needToFlush;
 }
 public void close() {
   closed = true;
   executor.shutdown();
   try {
     executor.awaitTermination(2, TimeUnit.SECONDS);
   } catch (InterruptedException e) {
     Thread.currentThread().interrupt();
   }
   if (activityStorage != null) {
     activityStorage.close();
   }
   for (ActivityValues activityIntValues : valuesMap.values()) {
     activityIntValues.close();
   }
 }
  /** flushes pending updates to disk */
  public synchronized void flush() {

    if (closed || activityStorage == null) {
      return;
    }
    final boolean flushDeletesNeeded = pendingDeletes.updates.size() > 0;
    final UpdateBatch<Update> batchToDelete = (flushDeletesNeeded) ? pendingDeletes : null;
    if (flushDeletesNeeded) {
      pendingDeletes = new UpdateBatch<Update>(activityConfig);
    }
    final boolean flushUpdatesNeeded =
        updateBatch.updates.size() > 0
            || versionComparator.compare(lastVersion, metadata.version) != 0;
    if (!flushUpdatesNeeded && !flushDeletesNeeded) {
      return;
    }
    final UpdateBatch<Update> batchToPersist = flushUpdatesNeeded ? updateBatch : null;
    final List<Runnable> underlyingFlushes = new ArrayList<Runnable>(valuesMap.size());
    // IF WE DON'T NEED TO FLUSH UPDATES,let's keep the persistent version as it is
    final String version = flushUpdatesNeeded ? lastVersion : metadata.version;
    if (flushUpdatesNeeded) {
      updateBatch = new UpdateBatch<CompositeActivityStorage.Update>(activityConfig);
    }
    for (ActivityValues activityIntValues : valuesMap.values()) {
      underlyingFlushes.add(activityIntValues.prepareFlush());
    }
    executor.submit(
        new Runnable() {
          @Override
          public void run() {
            if (closed) {
              return;
            }
            if (flushUpdatesNeeded) {
              activityStorage.flush(batchToPersist.updates);
            }
            if (flushDeletesNeeded) {
              Collections.reverse(batchToDelete.updates);
              activityStorage.flush(batchToDelete.updates);
              synchronized (deletedIndexes) {
                for (Update update : batchToDelete.updates) {
                  deletedIndexes.add(update.index);
                }
              }
            }
            int count = 0;
            globalLock.readLock().lock();
            try {
              synchronized (deletedIndexes) {
                count = uidToArrayIndex.size() + deletedIndexes.size();
                currentDocumentsCounter.clear();
                currentDocumentsCounter.inc(uidToArrayIndex.size());
                reclaimedDocumentsCounter.clear();
                reclaimedDocumentsCounter.inc(deletedIndexes.size());
                logger.info(
                    "Flush compositeActivityValues. Documents = "
                        + uidToArrayIndex.size()
                        + ", Deletes = "
                        + deletedIndexes.size());
              }
            } finally {
              globalLock.readLock().unlock();
            }
            for (Runnable runnable : underlyingFlushes) {
              runnable.run();
            }
            metadata.update(version, count);
          }
        });
  }