/*
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for additional information regarding
 * copyright ownership. The ASF licenses this file to You 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 org.apache.geode.internal.cache;


import org.apache.geode.StatisticDescriptor;
import org.apache.geode.Statistics;
import org.apache.geode.StatisticsFactory;
import org.apache.geode.StatisticsType;
import org.apache.geode.StatisticsTypeFactory;
import org.apache.geode.annotations.Immutable;
import org.apache.geode.annotations.VisibleForTesting;
import org.apache.geode.distributed.internal.PoolStatHelper;
import org.apache.geode.distributed.internal.QueueStatHelper;
import org.apache.geode.internal.NanoTimer;
import org.apache.geode.internal.statistics.StatisticsClock;
import org.apache.geode.internal.statistics.StatisticsTypeFactoryImpl;

/**
 * CachePerfStats tracks statistics about Geode cache performance and usage.
 */
public class CachePerfStats {
  @Immutable
  private static final StatisticsType type;

  static final int loadsInProgressId;
  static final int loadsCompletedId;
  static final int loadTimeId;
  static final int netloadsInProgressId;
  static final int netloadsCompletedId;
  static final int netloadTimeId;
  static final int netsearchesInProgressId;
  static final int netsearchesCompletedId;
  static final int netsearchTimeId;
  static final int cacheWriterCallsInProgressId;
  static final int cacheWriterCallsCompletedId;
  static final int cacheWriterCallTimeId;
  static final int cacheListenerCallsInProgressId;
  static final int cacheListenerCallsCompletedId;
  static final int cacheListenerCallTimeId;
  static final int getInitialImagesInProgressId;
  static final int getInitialImagesCompletedId;
  static final int deltaGetInitialImagesCompletedId;
  static final int getInitialImageTimeId;
  static final int getInitialImageKeysReceivedId;
  static final int regionsId;
  static final int partitionedRegionsId;
  protected static final int destroysId;
  static final int createsId;
  static final int putsId;
  protected static final int putTimeId;
  static final int putAllsId;
  static final int putAllTimeId;
  static final int removeAllsId;
  private static final int removeAllTimeId;
  protected static final int updatesId;
  static final int updateTimeId;
  static final int invalidatesId;
  static final int getsId;
  protected static final int getTimeId;
  protected static final int eventQueueSizeId;
  static final int eventQueueThrottleTimeId;
  static final int eventQueueThrottleCountId;
  static final int eventThreadsId;
  static final int missesId;
  protected static final int queryExecutionsId;
  static final int queryExecutionTimeId;
  static final int queryResultsHashCollisionsId;
  static final int queryResultsHashCollisionProbeTimeId;
  static final int partitionedRegionQueryRetriesId;

  static final int txSuccessLifeTimeId;
  static final int txFailedLifeTimeId;
  static final int txRollbackLifeTimeId;
  static final int txCommitsId;
  static final int txFailuresId;
  static final int txRollbacksId;
  static final int txCommitTimeId;
  static final int txFailureTimeId;
  static final int txRollbackTimeId;
  static final int txCommitChangesId;
  static final int txFailureChangesId;
  static final int txRollbackChangesId;
  static final int txConflictCheckTimeId;

  static final int reliableQueuedOpsId;
  static final int reliableQueueSizeId;
  static final int reliableQueueMaxId;
  static final int reliableRegionsId;
  static final int reliableRegionsMissingId;
  static final int reliableRegionsQueuingId;
  static final int reliableRegionsMissingFullAccessId;
  static final int reliableRegionsMissingLimitedAccessId;
  static final int reliableRegionsMissingNoAccessId;
  static final int entryCountId;
  protected static final int eventsQueuedId;
  static final int retriesId;

  static final int diskTasksWaitingId;
  static final int evictorJobsStartedId;
  static final int evictorJobsCompletedId;
  static final int evictorQueueSizeId;

  static final int evictWorkTimeId;

  static final int indexUpdateInProgressId;
  static final int indexUpdateCompletedId;
  static final int indexUpdateTimeId;
  static final int clearsId;
  private static final int indexInitializationInProgressId;
  private static final int indexInitializationCompletedId;
  private static final int indexInitializationTimeId;

  /** Id of the meta data refresh statistic */
  static final int metaDataRefreshCountId;

  static final int conflatedEventsId;
  static final int tombstoneCountId;
  static final int tombstoneGCCountId;
  private static final int tombstoneOverhead1Id;
  private static final int tombstoneOverhead2Id;
  static final int clearTimeoutsId;

  static final int deltaUpdatesId;
  private static final int deltaUpdatesTimeId;
  static final int deltaFailedUpdatesId;

  static final int deltasPreparedId;
  private static final int deltasPreparedTimeId;
  static final int deltasSentId;

  static final int deltaFullValuesSentId;
  static final int deltaFullValuesRequestedId;

  static final int importedEntriesCountId;
  static final int importTimeId;
  static final int exportedEntriesCountId;
  static final int exportTimeId;

  static final int compressionCompressTimeId;
  static final int compressionDecompressTimeId;
  static final int compressionCompressionsId;
  static final int compressionDecompressionsId;
  static final int compressionPreCompressedBytesId;
  static final int compressionPostCompressedBytesId;

  @VisibleForTesting
  static final int handlingNetsearchesInProgressId;
  @VisibleForTesting
  static final int handlingNetsearchesCompletedId;
  @VisibleForTesting
  static final int handlingNetsearchesTimeId;
  @VisibleForTesting
  static final int handlingNetsearchesFailedId;
  @VisibleForTesting
  static final int handlingNetsearchesFailedTimeId;
  @VisibleForTesting
  protected static final int previouslySeenEventsId;

  static {
    StatisticsTypeFactory f = StatisticsTypeFactoryImpl.singleton();

    final String loadsInProgressDesc =
        "Current number of threads in this cache doing a cache load.";
    final String loadsCompletedDesc =
        "Total number of times a load on this cache has completed (as a result of either a local get() or a remote netload).";
    final String loadTimeDesc = "Total time spent invoking loaders on this cache.";
    final String netloadsInProgressDesc =
        "Current number of threads doing a network load initiated by a get() in this cache.";
    final String netloadsCompletedDesc =
        "Total number of times a network load initiated on this cache has completed.";
    final String netloadTimeDesc = "Total time spent doing network loads on this cache.";
    final String netsearchesInProgressDesc =
        "Current number of threads doing a network search initiated by a get() in this cache.";
    final String netsearchesCompletedDesc =
        "Total number of times network searches initiated by this cache have completed.";
    final String netsearchTimeDesc = "Total time spent doing network searches for cache values.";
    final String cacheWriterCallsInProgressDesc =
        "Current number of threads doing a cache writer call.";
    final String cacheWriterCallsCompletedDesc =
        "Total number of times a cache writer call has completed.";
    final String cacheWriterCallTimeDesc = "Total time spent doing cache writer calls.";
    final String cacheListenerCallsInProgressDesc =
        "Current number of threads doing a cache listener call.";
    final String cacheListenerCallsCompletedDesc =
        "Total number of times a cache listener call has completed.";
    final String cacheListenerCallTimeDesc = "Total time spent doing cache listener calls.";
    final String getInitialImagesInProgressDesc =
        "Current number of getInitialImage operations currently in progress.";
    final String getInitialImagesCompletedDesc =
        "Total number of times getInitialImages (both delta and full GII) initiated by this cache have completed.";
    final String deltaGetInitialImagesCompletedDesc =
        "Total number of times delta getInitialImages initiated by this cache have completed.";
    final String getInitialImageTimeDesc =
        "Total time spent doing getInitialImages for region creation.";
    final String getInitialImageKeysReceivedDesc =
        "Total number of keys received while doing getInitialImage operations.";
    final String regionsDesc = "The current number of regions in the cache.";
    final String partitionedRegionsDesc = "The current number of partitioned regions in the cache.";
    final String destroysDesc =
        "The total number of times a cache object entry has been destroyed in this cache.";
    final String updatesDesc =
        "The total number of updates originating remotely that have been applied to this cache.";
    final String updateTimeDesc = "Total time spent performing an update.";
    final String invalidatesDesc =
        "The total number of times an existing cache object entry value in this cache has been invalidated";
    final String getsDesc =
        "The total number of times a successful get has been done on this cache.";
    final String createsDesc = "The total number of times an entry is added to this cache.";
    final String putsDesc =
        "The total number of times an entry is added or replaced in this cache as a result of a local operation (put(), create(), or get() which results in load, netsearch, or netloading a value). Note that this only counts puts done explicitly on this cache. It does not count updates pushed from other caches.";
    final String putTimeDesc =
        "Total time spent adding or replacing an entry in this cache as a result of a local operation.  This includes synchronizing on the map, invoking cache callbacks, sending messages to other caches and waiting for responses (if required).";
    final String putallsDesc =
        "The total number of times a map is added or replaced in this cache as a result of a local operation. Note that this only counts putAlls done explicitly on this cache. It does not count updates pushed from other caches.";
    final String putallTimeDesc =
        "Total time spent replacing a map in this cache as a result of a local operation.  This includes synchronizing on the map, invoking cache callbacks, sending messages to other caches and waiting for responses (if required).";
    final String removeAllsDesc =
        "The total number of removeAll operations that originated in this cache. Note that this only counts removeAlls done explicitly on this cache. It does not count removes pushed from other caches.";
    final String removeAllTimeDesc =
        "Total time spent performing removeAlls that originated in this cache. This includes time spent waiting for the removeAll to be done in remote caches (if required).";
    final String getTimeDesc =
        "Total time spent doing get operations from this cache (including netsearch and netload)";
    final String eventQueueSizeDesc = "The number of cache events waiting to be processed.";
    final String eventQueueThrottleTimeDesc =
        "The total amount of time, in nanoseconds, spent delayed by the event queue throttle.";
    final String eventQueueThrottleCountDesc =
        "The total number of times a thread was delayed in adding an event to the event queue.";
    final String eventThreadsDesc = "The number of threads currently processing events.";
    final String missesDesc =
        "Total number of times a get on the cache did not find a value already in local memory. The number of hits (i.e. gets that did not miss) can be calculated by subtracting misses from gets.";
    final String queryExecutionsDesc = "Total number of times some query has been executed";
    final String queryExecutionTimeDesc = "Total time spent executing queries";
    final String queryResultsHashCollisionsDesc =
        "Total number of times an hash code collision occurred when inserting an object into an OQL result set or rehashing it";
    final String queryResultsHashCollisionProbeTimeDesc =
        "Total time spent probing the hashtable in an OQL result set due to hash code collisions, includes reads, writes, and rehashes";
    final String partitionedRegionOQLQueryRetriesDesc =
        "Total number of times an OQL Query on a Partitioned Region had to be retried";
    final String txSuccessLifeTimeDesc =
        "The total amount of time, in nanoseconds, spent in a transaction before a successful commit. The time measured starts at transaction begin and ends when commit is called.";
    final String txFailedLifeTimeDesc =
        "The total amount of time, in nanoseconds, spent in a transaction before a failed commit. The time measured starts at transaction begin and ends when commit is called.";
    final String txRollbackLifeTimeDesc =
        "The total amount of time, in nanoseconds, spent in a transaction before an explicit rollback. The time measured starts at transaction begin and ends when rollback is called.";
    final String txCommitsDesc = "Total number times a transaction commit has succeeded.";
    final String txFailuresDesc = "Total number times a transaction commit has failed.";
    final String txRollbacksDesc =
        "Total number times a transaction has been explicitly rolled back.";
    final String txCommitTimeDesc =
        "The total amount of time, in nanoseconds, spent doing successful transaction commits.";
    final String txFailureTimeDesc =
        "The total amount of time, in nanoseconds, spent doing failed transaction commits.";
    final String txRollbackTimeDesc =
        "The total amount of time, in nanoseconds, spent doing explicit transaction rollbacks.";
    final String txCommitChangesDesc = "Total number of changes made by committed transactions.";
    final String txFailureChangesDesc = "Total number of changes lost by failed transactions.";
    final String txRollbackChangesDesc =
        "Total number of changes lost by explicit transaction rollbacks.";
    final String txConflictCheckTimeDesc =
        "The total amount of time, in nanoseconds, spent doing conflict checks during transaction commit";
    final String reliableQueuedOpsDesc =
        "Current number of cache operations queued for distribution to required roles.";
    final String reliableQueueSizeDesc =
        "Current size in megabytes of disk used to queue for distribution to required roles.";
    final String reliableQueueMaxDesc =
        "Maximum size in megabytes allotted for disk usage to queue for distribution to required roles.";
    final String reliableRegionsDesc = "Current number of regions configured for reliability.";
    final String reliableRegionsMissingDesc =
        "Current number regions configured for reliability that are missing required roles.";
    final String reliableRegionsQueuingDesc =
        "Current number regions configured for reliability that are queuing for required roles.";
    final String reliableRegionsMissingFullAccessDesc =
        "Current number of regions configured for reliablity that are missing require roles with full access";
    final String reliableRegionsMissingLimitedAccessDesc =
        "Current number of regions configured for reliablity that are missing required roles with Limited access";
    final String reliableRegionsMissingNoAccessDesc =
        "Current number of regions configured for reliablity that are missing required roles with No access";
    final String clearsDesc = "The total number of times a clear has been done on this cache.";
    final String metaDataRefreshCountDesc =
        "Total number of times the meta data is refreshed due to hopping observed.";
    final String conflatedEventsDesc =
        "Number of events not delivered due to conflation.  Typically this means that the event arrived after a later event was already applied to the cache.";
    final String tombstoneCountDesc =
        "Number of destroyed entries that are retained for concurrent modification detection";
    final String tombstoneGCCountDesc =
        "Number of garbage-collections performed on destroyed entries";
    final String tombstoneOverhead1Desc =
        "Amount of memory consumed by destroyed entries in replicated or partitioned regions";
    final String tombstoneOverhead2Desc =
        "Amount of memory consumed by destroyed entries in non-replicated regions";
    final String clearTimeoutsDesc =
        "Number of timeouts waiting for events concurrent to a clear() operation to be received and applied before performing the clear()";
    final String deltaUpdatesDesc =
        "The total number of times entries in this cache are updated through delta bytes.";
    final String deltaUpdatesTimeDesc =
        "Total time spent applying the received delta bytes to entries in this cache.";
    final String deltaFailedUpdatesDesc =
        "The total number of times entries in this cache failed to be updated through delta bytes.";
    final String deltasPreparedDesc = "The total number of times delta was prepared in this cache.";
    final String deltasPreparedTimeDesc = "Total time spent preparing delta bytes in this cache.";
    final String deltasSentDesc =
        "The total number of times delta was sent to remote caches. This excludes deltas sent from server to client.";
    final String deltaFullValuesSentDesc =
        "The total number of times a full value was sent to a remote cache.";
    final String deltaFullValuesRequestedDesc =
        "The total number of times a full value was requested by this cache.";
    final String importedEntriesCountDesc =
        "The total number of entries imported from a snapshot file.";
    final String importTimeDesc = "The total time spent importing entries from a snapshot file.";
    final String exportedEntriesCountDesc =
        "The total number of entries exported into a snapshot file.";
    final String exportTimeDesc = "The total time spent exporting entries into a snapshot file.";
    final String compressionCompressTimeDesc = "The total time spent compressing data.";
    final String compressionDecompressTimeDesc = "The total time spent decompressing data.";
    final String compressionCompressionsDesc = "The total number of compression operations.";
    final String compressionDecompressionsDesc = "The total number of decompression operations.";
    final String compressionPreCompresssedBytesDesc =
        "The total number of bytes before compressing.";
    final String compressionPostCompressedBytesDesc =
        "The total number of bytes after compressing.";

    // total actual evictions (entries evicted)
    final String evictByCriteria_evictionsDesc = "The total number of entries evicted";

    // total eviction time including product + user expr.
    final String evictByCriteria_evictionTimeDesc = "Time taken for eviction process";
    final String evictByCriteria_evictionsInProgressDesc = "Total number of evictions in progress";

    // total eviction attempts
    final String evictByCriteria_evaluationsDesc = "Total number of evaluations for eviction";

    // time taken to evaluate user expression.
    final String evictByCriteria_evaluationTimeDesc =
        "Total time taken for evaluation of user expression during eviction";

    final String handlingNetsearchesInProgressDesc =
        "Current number of threads handling a network search initiated by a remote cache.";
    final String handlingNetsearchesCompletedDesc =
        "Total number of times handling a network search initiated by a remote cache completed with success.";
    final String handlingNetsearchesTimeDesc =
        "Total time spent handling successful network searches for remote caches.";
    final String handlingNetsearchesFailedDesc =
        "Total number of times handling a network search initiated by a remote cache failed without success.";
    final String handlingNetsearchesFailedTimeDesc =
        "Total time spent handling failed network searches for remote caches.";
    final String previouslySeenEventsDesc =
        "The number of previously seen events ignored by the event tracker.";

    type = f.createType("CachePerfStats", "Statistics about GemFire cache performance",
        new StatisticDescriptor[] {
            f.createLongGauge("loadsInProgress", loadsInProgressDesc, "operations"),
            f.createLongCounter("loadsCompleted", loadsCompletedDesc, "operations"),
            f.createLongCounter("loadTime", loadTimeDesc, "nanoseconds", false),
            f.createLongGauge("netloadsInProgress", netloadsInProgressDesc, "operations"),
            f.createLongCounter("netloadsCompleted", netloadsCompletedDesc, "operations"),
            f.createLongCounter("netloadTime", netloadTimeDesc, "nanoseconds", false),
            f.createLongGauge("netsearchesInProgress", netsearchesInProgressDesc, "operations"),
            f.createLongCounter("netsearchesCompleted", netsearchesCompletedDesc, "operations"),
            f.createLongCounter("netsearchTime", netsearchTimeDesc, "nanoseconds"),
            f.createLongGauge("cacheWriterCallsInProgress", cacheWriterCallsInProgressDesc,
                "operations"),
            f.createLongCounter("cacheWriterCallsCompleted", cacheWriterCallsCompletedDesc,
                "operations"),
            f.createLongCounter("cacheWriterCallTime", cacheWriterCallTimeDesc, "nanoseconds"),
            f.createLongGauge("cacheListenerCallsInProgress", cacheListenerCallsInProgressDesc,
                "operations"),
            f.createLongCounter("cacheListenerCallsCompleted", cacheListenerCallsCompletedDesc,
                "operations"),
            f.createLongCounter("cacheListenerCallTime", cacheListenerCallTimeDesc, "nanoseconds"),
            f.createLongGauge("indexUpdateInProgress", "Current number of ops in progress",
                "operations"),
            f.createLongCounter("indexUpdateCompleted", "Total number of ops that have completed",
                "operations"),
            f.createLongCounter("indexUpdateTime", "Total amount of time spent doing this op",
                "nanoseconds"),
            f.createLongGauge("indexInitializationInProgress",
                "Current number of index initializations in progress", "operations"),
            f.createLongCounter("indexInitializationCompleted",
                "Total number of index initializations that have completed", "operations"),
            f.createLongCounter("indexInitializationTime",
                "Total amount of time spent initializing indexes", "nanoseconds"),

            f.createLongGauge("getInitialImagesInProgress", getInitialImagesInProgressDesc,
                "operations"),
            f.createLongCounter("getInitialImagesCompleted", getInitialImagesCompletedDesc,
                "operations"),
            f.createLongCounter("deltaGetInitialImagesCompleted",
                deltaGetInitialImagesCompletedDesc,
                "operations"),
            f.createLongCounter("getInitialImageTime", getInitialImageTimeDesc, "nanoseconds"),
            f.createLongCounter("getInitialImageKeysReceived", getInitialImageKeysReceivedDesc,
                "keys"),
            f.createLongGauge("regions", regionsDesc, "regions"),
            f.createLongGauge("partitionedRegions", partitionedRegionsDesc, "partitionedRegions"),
            f.createLongCounter("destroys", destroysDesc, "operations"),
            f.createLongCounter("updates", updatesDesc, "operations"),
            f.createLongCounter("updateTime", updateTimeDesc, "nanoseconds"),
            f.createLongCounter("invalidates", invalidatesDesc, "operations"),
            f.createLongCounter("gets", getsDesc, "operations"),
            f.createLongCounter("misses", missesDesc, "operations"),
            f.createLongCounter("creates", createsDesc, "operations"),
            f.createLongCounter("puts", putsDesc, "operations"),
            f.createLongCounter("putTime", putTimeDesc, "nanoseconds", false),
            f.createLongCounter("putalls", putallsDesc, "operations"),
            f.createLongCounter("putallTime", putallTimeDesc, "nanoseconds", false),
            f.createLongCounter("removeAlls", removeAllsDesc, "operations"),
            f.createLongCounter("removeAllTime", removeAllTimeDesc, "nanoseconds", false),
            f.createLongCounter("getTime", getTimeDesc, "nanoseconds", false),
            f.createLongGauge("eventQueueSize", eventQueueSizeDesc, "messages"),
            f.createLongGauge("eventQueueThrottleCount", eventQueueThrottleCountDesc, "delays"),
            f.createLongCounter("eventQueueThrottleTime", eventQueueThrottleTimeDesc, "nanoseconds",
                false),
            f.createLongGauge("eventThreads", eventThreadsDesc, "threads"),
            f.createLongCounter("queryExecutions", queryExecutionsDesc, "operations"),
            f.createLongCounter("queryExecutionTime", queryExecutionTimeDesc, "nanoseconds"),
            f.createLongCounter("queryResultsHashCollisions", queryResultsHashCollisionsDesc,
                "operations"),
            f.createLongCounter("queryResultsHashCollisionProbeTime",
                queryResultsHashCollisionProbeTimeDesc, "nanoseconds"),
            f.createLongCounter("partitionedRegionQueryRetries",
                partitionedRegionOQLQueryRetriesDesc, "retries"),

            f.createLongCounter("txCommits", txCommitsDesc, "commits"),
            f.createLongCounter("txCommitChanges", txCommitChangesDesc, "changes"),
            f.createLongCounter("txCommitTime", txCommitTimeDesc, "nanoseconds", false),
            f.createLongCounter("txSuccessLifeTime", txSuccessLifeTimeDesc, "nanoseconds", false),

            f.createLongCounter("txFailures", txFailuresDesc, "failures"),
            f.createLongCounter("txFailureChanges", txFailureChangesDesc, "changes"),
            f.createLongCounter("txFailureTime", txFailureTimeDesc, "nanoseconds", false),
            f.createLongCounter("txFailedLifeTime", txFailedLifeTimeDesc, "nanoseconds", false),

            f.createLongCounter("txRollbacks", txRollbacksDesc, "rollbacks"),
            f.createLongCounter("txRollbackChanges", txRollbackChangesDesc, "changes"),
            f.createLongCounter("txRollbackTime", txRollbackTimeDesc, "nanoseconds", false),
            f.createLongCounter("txRollbackLifeTime", txRollbackLifeTimeDesc, "nanoseconds", false),
            f.createLongCounter("txConflictCheckTime", txConflictCheckTimeDesc, "nanoseconds",
                false),

            f.createLongGauge("reliableQueuedOps", reliableQueuedOpsDesc, "operations"),
            f.createLongGauge("reliableQueueSize", reliableQueueSizeDesc, "megabytes"),
            f.createLongGauge("reliableQueueMax", reliableQueueMaxDesc, "megabytes"),
            f.createLongGauge("reliableRegions", reliableRegionsDesc, "regions"),
            f.createLongGauge("reliableRegionsMissing", reliableRegionsMissingDesc, "regions"),
            f.createLongGauge("reliableRegionsQueuing", reliableRegionsQueuingDesc, "regions"),
            f.createLongGauge("reliableRegionsMissingFullAccess",
                reliableRegionsMissingFullAccessDesc, "regions"),
            f.createLongGauge("reliableRegionsMissingLimitedAccess",
                reliableRegionsMissingLimitedAccessDesc, "regions"),
            f.createLongGauge("reliableRegionsMissingNoAccess", reliableRegionsMissingNoAccessDesc,
                "regions"),
            f.createLongGauge("entries",
                "Current number of entries in the cache. This does not include any entries that are tombstones. See tombstoneCount.",
                "entries"),
            f.createLongCounter("eventsQueued",
                "Number of events attached to " + "other events for callback invocation", "events"),
            f.createLongCounter("retries",
                "Number of times a concurrent destroy followed by a create has caused an entry operation to need to retry.",
                "operations"),
            f.createLongCounter("clears", clearsDesc, "operations"),
            f.createLongGauge("diskTasksWaiting",
                "Current number of disk tasks (oplog compactions, asynchronous recoveries, etc) that are waiting for a thread to run the operation",
                "operations"),
            f.createLongCounter("conflatedEvents", conflatedEventsDesc, "operations"),
            f.createLongGauge("tombstones", tombstoneCountDesc, "entries"),
            f.createLongCounter("tombstoneGCs", tombstoneGCCountDesc, "operations"),
            f.createLongGauge("replicatedTombstonesSize", tombstoneOverhead1Desc, "bytes"),
            f.createLongGauge("nonReplicatedTombstonesSize", tombstoneOverhead2Desc, "bytes"),
            f.createLongCounter("clearTimeouts", clearTimeoutsDesc, "timeouts"),
            f.createLongGauge("evictorJobsStarted", "Number of evictor jobs started", "jobs"),
            f.createLongGauge("evictorJobsCompleted", "Number of evictor jobs completed", "jobs"),
            f.createLongGauge("evictorQueueSize",
                "Number of jobs waiting to be picked up by evictor threads", "jobs"),
            f.createLongCounter("evictWorkTime",
                "Total time spent doing eviction work in background threads", "nanoseconds", false),
            f.createLongCounter("metaDataRefreshCount", metaDataRefreshCountDesc,
                "refreshes", false),
            f.createLongCounter("deltaUpdates", deltaUpdatesDesc, "operations"),
            f.createLongCounter("deltaUpdatesTime", deltaUpdatesTimeDesc, "nanoseconds", false),
            f.createLongCounter("deltaFailedUpdates", deltaFailedUpdatesDesc, "operations"),
            f.createLongCounter("deltasPrepared", deltasPreparedDesc, "operations"),
            f.createLongCounter("deltasPreparedTime", deltasPreparedTimeDesc, "nanoseconds", false),
            f.createLongCounter("deltasSent", deltasSentDesc, "operations"),
            f.createLongCounter("deltaFullValuesSent", deltaFullValuesSentDesc, "operations"),
            f.createLongCounter("deltaFullValuesRequested", deltaFullValuesRequestedDesc,
                "operations"),

            f.createLongCounter("importedEntries", importedEntriesCountDesc, "entries"),
            f.createLongCounter("importTime", importTimeDesc, "nanoseconds"),
            f.createLongCounter("exportedEntries", exportedEntriesCountDesc, "entries"),
            f.createLongCounter("exportTime", exportTimeDesc, "nanoseconds"),

            f.createLongCounter("compressTime", compressionCompressTimeDesc, "nanoseconds"),
            f.createLongCounter("decompressTime", compressionDecompressTimeDesc, "nanoseconds"),
            f.createLongCounter("compressions", compressionCompressionsDesc, "operations"),
            f.createLongCounter("decompressions", compressionDecompressionsDesc, "operations"),
            f.createLongCounter("preCompressedBytes", compressionPreCompresssedBytesDesc, "bytes"),
            f.createLongCounter("postCompressedBytes", compressionPostCompressedBytesDesc, "bytes"),

            f.createLongCounter("evictByCriteria_evictions", evictByCriteria_evictionsDesc,
                "operations"),
            f.createLongCounter("evictByCriteria_evictionTime", evictByCriteria_evictionTimeDesc,
                "nanoseconds"),
            f.createLongCounter("evictByCriteria_evictionsInProgress",
                evictByCriteria_evictionsInProgressDesc, "operations"),
            f.createLongCounter("evictByCriteria_evaluations", evictByCriteria_evaluationsDesc,
                "operations"),
            f.createLongCounter("evictByCriteria_evaluationTime",
                evictByCriteria_evaluationTimeDesc, "nanoseconds"),

            f.createLongGauge("handlingNetsearchesInProgress", handlingNetsearchesInProgressDesc,
                "operations"),
            f.createLongCounter("handlingNetsearchesCompleted", handlingNetsearchesCompletedDesc,
                "operations"),
