cassandra-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From brandonwilli...@apache.org
Subject git commit: Expose global CF metrics
Date Thu, 26 Jun 2014 15:09:29 GMT
Repository: cassandra
Updated Branches:
  refs/heads/trunk 7000bde6c -> ae0f63463


Expose global CF metrics

Patch by Chris Lohfink, reviewed by brandonwilliams for CASSANDRA-7273


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/ae0f6346
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/ae0f6346
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/ae0f6346

Branch: refs/heads/trunk
Commit: ae0f63463d5ff4e49b6dfa209d03dfaa98105d56
Parents: 7000bde
Author: Brandon Williams <brandonwilliams@apache.org>
Authored: Thu Jun 26 10:08:53 2014 -0500
Committer: Brandon Williams <brandonwilliams@apache.org>
Committed: Thu Jun 26 10:08:53 2014 -0500

----------------------------------------------------------------------
 .../apache/cassandra/db/ColumnFamilyStore.java  |   4 +-
 src/java/org/apache/cassandra/db/Keyspace.java  |   2 +-
 .../cassandra/metrics/ColumnFamilyMetrics.java  | 345 +++++++++++++++----
 .../cassandra/metrics/KeyspaceMetrics.java      | 253 +++++++-------
 .../cassandra/metrics/LatencyMetrics.java       |  28 +-
 .../org/apache/cassandra/db/KeyspaceTest.java   |  16 +-
 6 files changed, 439 insertions(+), 209 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/ae0f6346/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/ColumnFamilyStore.java b/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
index 3975352..db3ed15 100644
--- a/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
+++ b/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
@@ -2674,12 +2674,12 @@ public class ColumnFamilyStore implements ColumnFamilyStoreMBean
 
     public double getTombstonesPerSlice()
     {
-        return metric.tombstoneScannedHistogram.getSnapshot().getMedian();
+        return metric.tombstoneScannedHistogram.cf.getSnapshot().getMedian();
     }
 
     public double getLiveCellsPerSlice()
     {
-        return metric.liveScannedHistogram.getSnapshot().getMedian();
+        return metric.liveScannedHistogram.cf.getSnapshot().getMedian();
     }
 
     // End JMX get/set.

http://git-wip-us.apache.org/repos/asf/cassandra/blob/ae0f6346/src/java/org/apache/cassandra/db/Keyspace.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/Keyspace.java b/src/java/org/apache/cassandra/db/Keyspace.java
index 60183db..9c686b7 100644
--- a/src/java/org/apache/cassandra/db/Keyspace.java
+++ b/src/java/org/apache/cassandra/db/Keyspace.java
@@ -273,12 +273,12 @@ public class Keyspace
         assert metadata != null : "Unknown keyspace " + keyspaceName;
         createReplicationStrategy(metadata);
 
+        this.metric = new KeyspaceMetrics(this);
         for (CFMetaData cfm : new ArrayList<CFMetaData>(metadata.cfMetaData().values()))
         {
             logger.debug("Initializing {}.{}", getName(), cfm.cfName);
             initCf(cfm.cfId, cfm.cfName, loadSSTables);
         }
-        this.metric = new KeyspaceMetrics(this);
     }
 
     public void createReplicationStrategy(KSMetaData ksm)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/ae0f6346/src/java/org/apache/cassandra/metrics/ColumnFamilyMetrics.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/metrics/ColumnFamilyMetrics.java b/src/java/org/apache/cassandra/metrics/ColumnFamilyMetrics.java
index f4682da..75a21dc 100644
--- a/src/java/org/apache/cassandra/metrics/ColumnFamilyMetrics.java
+++ b/src/java/org/apache/cassandra/metrics/ColumnFamilyMetrics.java
@@ -17,17 +17,23 @@
  */
 package org.apache.cassandra.metrics;
 
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.TimeUnit;
 
-import com.yammer.metrics.Metrics;
-import com.yammer.metrics.core.*;
-import com.yammer.metrics.util.RatioGauge;
-
 import org.apache.cassandra.db.ColumnFamilyStore;
+import org.apache.cassandra.db.Keyspace;
 import org.apache.cassandra.io.sstable.SSTableReader;
 import org.apache.cassandra.io.sstable.metadata.MetadataCollector;
 import org.apache.cassandra.utils.EstimatedHistogram;
 
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.yammer.metrics.Metrics;
+import com.yammer.metrics.core.*;
+import com.yammer.metrics.util.RatioGauge;
+
 /**
  * Metrics for {@link ColumnFamilyStore}.
  */
@@ -56,7 +62,7 @@ public class ColumnFamilyMetrics
     /** Histogram of estimated number of columns. */
     public final Gauge<long[]> estimatedColumnCountHistogram;
     /** Histogram of the number of sstable data files accessed per read */
-    public final Histogram sstablesPerReadHistogram;
+    public final ColumnFamilyHistogram sstablesPerReadHistogram;
     /** (Local) read metrics */
     public final LatencyMetrics readLatency;
     /** (Local) range slice metrics */
@@ -92,9 +98,9 @@ public class ColumnFamilyMetrics
     /** Key cache hit rate  for this CF */
     public final Gauge<Double> keyCacheHitRate;
     /** Tombstones scanned in queries on this CF */
-    public final Histogram tombstoneScannedHistogram;
+    public final ColumnFamilyHistogram tombstoneScannedHistogram;
     /** Live cells scanned in queries on this CF */
-    public final Histogram liveScannedHistogram;
+    public final ColumnFamilyHistogram liveScannedHistogram;
     /** Disk space used by snapshot files which */
     public final Gauge<Long> trueSnapshotsSize;
     /** Row cache hits, but result out of range */
@@ -111,14 +117,28 @@ public class ColumnFamilyMetrics
     public final Timer waitingOnFreeMemtableSpace;
 
     private final MetricNameFactory factory;
+    private static final MetricNameFactory globalNameFactory = new AllColumnFamilyMetricNameFactory();;
 
     public final Counter speculativeRetries;
 
     // for backward compatibility
     @Deprecated public final EstimatedHistogram sstablesPerRead = new EstimatedHistogram(35);
     @Deprecated public final EstimatedHistogram recentSSTablesPerRead = new EstimatedHistogram(35);
-
-
+    
+    public final static LatencyMetrics globalReadLatency = new LatencyMetrics(globalNameFactory, "Read");
+    public final static LatencyMetrics globalWriteLatency = new LatencyMetrics(globalNameFactory, "Write");
+    public final static LatencyMetrics globalRangeLatency = new LatencyMetrics(globalNameFactory, "Range");
+    
+    /**
+     * stores metrics that will be rolled into a single global metric
+     */
+    public final static ConcurrentMap<String, Set<Metric>> allColumnFamilyMetrics = Maps.newConcurrentMap();
+    
+    /**
+     * Stores all metric names created that can be used when unregistering
+     */
+    public final static Set<String> all = Sets.newHashSet();
+    
     /**
      * Creates metrics for given {@link ColumnFamilyStore}.
      *
@@ -128,35 +148,35 @@ public class ColumnFamilyMetrics
     {
         factory = new ColumnFamilyMetricNameFactory(cfs);
 
-        memtableColumnsCount = Metrics.newGauge(factory.createMetricName("MemtableColumnsCount"), new Gauge<Long>()
+        memtableColumnsCount = createColumnFamilyGauge("MemtableColumnsCount", new Gauge<Long>()
         {
             public Long value()
             {
                 return cfs.getDataTracker().getView().getCurrentMemtable().getOperations();
             }
         });
-        memtableOnHeapSize = Metrics.newGauge(factory.createMetricName("MemtableHeapSize"), new Gauge<Long>()
+        memtableOnHeapSize = createColumnFamilyGauge("MemtableOnHeapSize", new Gauge<Long>()
         {
             public Long value()
             {
                 return cfs.getDataTracker().getView().getCurrentMemtable().getAllocator().onHeap().owns();
             }
         });
-        memtableOffHeapSize = Metrics.newGauge(factory.createMetricName("MemtableHeapSize"), new Gauge<Long>()
+        memtableOffHeapSize = createColumnFamilyGauge("MemtableOffHeapSize", new Gauge<Long>()
         {
             public Long value()
             {
                 return cfs.getDataTracker().getView().getCurrentMemtable().getAllocator().offHeap().owns();
             }
         });
-        memtableLiveDataSize = Metrics.newGauge(factory.createMetricName("MemtableLiveDataSize"), new Gauge<Long>()
+        memtableLiveDataSize = createColumnFamilyGauge("MemtableLiveDataSize", new Gauge<Long>()
         {
             public Long value()
             {
                 return cfs.getDataTracker().getView().getCurrentMemtable().getLiveDataSize();
             }
         });
-        allMemtablesOnHeapSize = Metrics.newGauge(factory.createMetricName("AllMemtablesHeapSize"), new Gauge<Long>()
+        allMemtablesOnHeapSize = createColumnFamilyGauge("AllMemtablesHeapSize", new Gauge<Long>()
         {
             public Long value()
             {
@@ -166,7 +186,7 @@ public class ColumnFamilyMetrics
                 return size;
             }
         });
-        allMemtablesOffHeapSize = Metrics.newGauge(factory.createMetricName("AllMemtablesHeapSize"), new Gauge<Long>()
+        allMemtablesOffHeapSize = createColumnFamilyGauge("AllMemtablesOffHeapSize", new Gauge<Long>()
         {
             public Long value()
             {
@@ -176,7 +196,7 @@ public class ColumnFamilyMetrics
                 return size;
             }
         });
-        allMemtablesLiveDataSize = Metrics.newGauge(factory.createMetricName("AllMemtablesLiveDataSize"), new Gauge<Long>()
+        allMemtablesLiveDataSize = createColumnFamilyGauge("AllMemtablesLiveDataSize", new Gauge<Long>()
         {
             public Long value()
             {
@@ -186,7 +206,7 @@ public class ColumnFamilyMetrics
                 return size;
             }
         });
-        memtableSwitchCount = Metrics.newCounter(factory.createMetricName("MemtableSwitchCount"));
+        memtableSwitchCount = createColumnFamilyCounter("MemtableSwitchCount");
         estimatedRowSizeHistogram = Metrics.newGauge(factory.createMetricName("EstimatedRowSizeHistogram"), new Gauge<long[]>()
         {
             public long[] value()
@@ -215,8 +235,8 @@ public class ColumnFamilyMetrics
                 return histogram;
             }
         });
-        sstablesPerReadHistogram = Metrics.newHistogram(factory.createMetricName("SSTablesPerReadHistogram"), true);
-        compressionRatio = Metrics.newGauge(factory.createMetricName("CompressionRatio"), new Gauge<Double>()
+        sstablesPerReadHistogram = createColumnFamilyHistogram("SSTablesPerReadHistogram", cfs.keyspace.metric.sstablesPerReadHistogram);
+        compressionRatio = createColumnFamilyGauge("CompressionRatio", new Gauge<Double>()
         {
             public Double value()
             {
@@ -232,28 +252,47 @@ public class ColumnFamilyMetrics
                 }
                 return total != 0 ? sum / total : 0;
             }
+        }, new Gauge<Double>() // global gauge
+        {
+            public Double value()
+            {
+                double sum = 0;
+                int total = 0;
+                for (Keyspace keyspace : Keyspace.all())
+                {
+                    for (SSTableReader sstable : keyspace.getAllSSTables())
+                    {
+                        if (sstable.getCompressionRatio() != MetadataCollector.NO_COMPRESSION_RATIO)
+                        {
+                            sum += sstable.getCompressionRatio();
+                            total++;
+                        }
+                    }
+                }
+                return total != 0 ? sum / total : 0;
+            }
         });
-        readLatency = new LatencyMetrics(factory, "Read");
-        writeLatency = new LatencyMetrics(factory, "Write");
-        rangeLatency = new LatencyMetrics(factory, "Range");
-        pendingFlushes = Metrics.newCounter(factory.createMetricName("PendingFlushes"));
-        pendingCompactions = Metrics.newGauge(factory.createMetricName("PendingCompactions"), new Gauge<Integer>()
+        readLatency = new LatencyMetrics(factory, "Read", cfs.keyspace.metric.readLatency, globalReadLatency);
+        writeLatency = new LatencyMetrics(factory, "Write", cfs.keyspace.metric.writeLatency, globalWriteLatency);
+        rangeLatency = new LatencyMetrics(factory, "Range", cfs.keyspace.metric.rangeLatency, globalRangeLatency);
+        pendingFlushes = createColumnFamilyCounter("PendingFlushes");
+        pendingCompactions = createColumnFamilyGauge("PendingCompactions", new Gauge<Integer>()
         {
             public Integer value()
             {
                 return cfs.getCompactionStrategy().getEstimatedRemainingTasks();
             }
         });
-        liveSSTableCount = Metrics.newGauge(factory.createMetricName("LiveSSTableCount"), new Gauge<Integer>()
+        liveSSTableCount = createColumnFamilyGauge("LiveSSTableCount", new Gauge<Integer>()
         {
             public Integer value()
             {
                 return cfs.getDataTracker().getSSTables().size();
             }
         });
-        liveDiskSpaceUsed = Metrics.newCounter(factory.createMetricName("LiveDiskSpaceUsed"));
-        totalDiskSpaceUsed = Metrics.newCounter(factory.createMetricName("TotalDiskSpaceUsed"));
-        minRowSize = Metrics.newGauge(factory.createMetricName("MinRowSize"), new Gauge<Long>()
+        liveDiskSpaceUsed = createColumnFamilyCounter("LiveDiskSpaceUsed");
+        totalDiskSpaceUsed = createColumnFamilyCounter("TotalDiskSpaceUsed");
+        minRowSize = createColumnFamilyGauge("MinRowSize", new Gauge<Long>()
         {
             public Long value()
             {
@@ -265,8 +304,19 @@ public class ColumnFamilyMetrics
                 }
                 return min;
             }
+        }, new Gauge<Long>() // global gauge
+        {
+            public Long value()
+            {
+                long min = Long.MAX_VALUE;
+                for (Metric cfGauge : allColumnFamilyMetrics.get("MinRowSize"))
+                {
+                    min = Math.min(min, ((Gauge<? extends Number>) cfGauge).value().longValue());
+                }
+                return min;
+            }
         });
-        maxRowSize = Metrics.newGauge(factory.createMetricName("MaxRowSize"), new Gauge<Long>()
+        maxRowSize = createColumnFamilyGauge("MaxRowSize", new Gauge<Long>()
         {
             public Long value()
             {
@@ -278,8 +328,19 @@ public class ColumnFamilyMetrics
                 }
                 return max;
             }
+        }, new Gauge<Long>() // global gauge
+        {
+            public Long value()
+            {
+                long max = 0;
+                for (Metric cfGauge : allColumnFamilyMetrics.get("MaxRowSize"))
+                {
+                    max = Math.max(max, ((Gauge<? extends Number>) cfGauge).value().longValue());
+                }
+                return max;
+            }
         });
-        meanRowSize = Metrics.newGauge(factory.createMetricName("MeanRowSize"), new Gauge<Long>()
+        meanRowSize = createColumnFamilyGauge("MeanRowSize", new Gauge<Long>()
         {
             public Long value()
             {
@@ -293,8 +354,25 @@ public class ColumnFamilyMetrics
                 }
                 return count > 0 ? sum / count : 0;
             }
+        }, new Gauge<Long>() // global gauge
+        {
+            public Long value()
+            {
+                long sum = 0;
+                long count = 0;
+                for (Keyspace keyspace : Keyspace.all())
+                {
+                    for (SSTableReader sstable : keyspace.getAllSSTables())
+                    {
+                        long n = sstable.getEstimatedRowSize().count();
+                        sum += sstable.getEstimatedRowSize().mean() * n;
+                        count += n;
+                    }
+                }
+                return count > 0 ? sum / count : 0;
+            }
         });
-        bloomFilterFalsePositives = Metrics.newGauge(factory.createMetricName("BloomFilterFalsePositives"), new Gauge<Long>()
+        bloomFilterFalsePositives = createColumnFamilyGauge("BloomFilterFalsePositives", new Gauge<Long>()
         {
             public Long value()
             {
@@ -304,7 +382,7 @@ public class ColumnFamilyMetrics
                 return count;
             }
         });
-        recentBloomFilterFalsePositives = Metrics.newGauge(factory.createMetricName("RecentBloomFilterFalsePositives"), new Gauge<Long>()
+        recentBloomFilterFalsePositives = createColumnFamilyGauge("RecentBloomFilterFalsePositives", new Gauge<Long>()
         {
             public Long value()
             {
@@ -314,7 +392,7 @@ public class ColumnFamilyMetrics
                 return count;
             }
         });
-        bloomFilterFalseRatio = Metrics.newGauge(factory.createMetricName("BloomFilterFalseRatio"), new Gauge<Double>()
+        bloomFilterFalseRatio = createColumnFamilyGauge("BloomFilterFalseRatio", new Gauge<Double>()
         {
             public Double value()
             {
@@ -329,8 +407,26 @@ public class ColumnFamilyMetrics
                     return 0d;
                 return (double) falseCount / (trueCount + falseCount);
             }
+        }, new Gauge<Double>() // global gauge
+        {
+            public Double value()
+            {
+                long falseCount = 0L;
+                long trueCount = 0L;
+                for (Keyspace keyspace : Keyspace.all())
+                {
+                    for (SSTableReader sstable : keyspace.getAllSSTables())
+                    {
+                        falseCount += sstable.getBloomFilterFalsePositiveCount();
+                        trueCount += sstable.getBloomFilterTruePositiveCount();
+                    }
+                }
+                if (falseCount == 0L && trueCount == 0L)
+                    return 0d;
+                return (double) falseCount / (trueCount + falseCount);
+            }
         });
-        recentBloomFilterFalseRatio = Metrics.newGauge(factory.createMetricName("RecentBloomFilterFalseRatio"), new Gauge<Double>()
+        recentBloomFilterFalseRatio = createColumnFamilyGauge("RecentBloomFilterFalseRatio", new Gauge<Double>()
         {
             public Double value()
             {
@@ -345,8 +441,26 @@ public class ColumnFamilyMetrics
                     return 0d;
                 return (double) falseCount / (trueCount + falseCount);
             }
+        }, new Gauge<Double>() // global gauge
+        {
+            public Double value()
+            {
+                long falseCount = 0L;
+                long trueCount = 0L;
+                for (Keyspace keyspace : Keyspace.all())
+                {
+                    for (SSTableReader sstable : keyspace.getAllSSTables())
+                    {
+                        falseCount += sstable.getRecentBloomFilterFalsePositiveCount();
+                        trueCount += sstable.getRecentBloomFilterTruePositiveCount();
+                    }
+                }
+                if (falseCount == 0L && trueCount == 0L)
+                    return 0d;
+                return (double) falseCount / (trueCount + falseCount);
+            }
         });
-        bloomFilterDiskSpaceUsed = Metrics.newGauge(factory.createMetricName("BloomFilterDiskSpaceUsed"), new Gauge<Long>()
+        bloomFilterDiskSpaceUsed = createColumnFamilyGauge("BloomFilterDiskSpaceUsed", new Gauge<Long>()
         {
             public Long value()
             {
@@ -356,7 +470,7 @@ public class ColumnFamilyMetrics
                 return total;
             }
         });
-        speculativeRetries = Metrics.newCounter(factory.createMetricName("SpeculativeRetries"));
+        speculativeRetries = createColumnFamilyCounter("SpeculativeRetries");
         keyCacheHitRate = Metrics.newGauge(factory.createMetricName("KeyCacheHitRate"), new RatioGauge()
         {
             protected double getNumerator()
@@ -375,22 +489,22 @@ public class ColumnFamilyMetrics
                 return Math.max(requests, 1); // to avoid NaN.
             }
         });
-        tombstoneScannedHistogram = Metrics.newHistogram(factory.createMetricName("TombstoneScannedHistogram"), true);
-        liveScannedHistogram = Metrics.newHistogram(factory.createMetricName("LiveScannedHistogram"), true);
+        tombstoneScannedHistogram = createColumnFamilyHistogram("TombstoneScannedHistogram", cfs.keyspace.metric.tombstoneScannedHistogram);
+        liveScannedHistogram = createColumnFamilyHistogram("LiveScannedHistogram", cfs.keyspace.metric.liveScannedHistogram);
         coordinatorReadLatency = Metrics.newTimer(factory.createMetricName("CoordinatorReadLatency"), TimeUnit.MICROSECONDS, TimeUnit.SECONDS);
         coordinatorScanLatency = Metrics.newTimer(factory.createMetricName("CoordinatorScanLatency"), TimeUnit.MICROSECONDS, TimeUnit.SECONDS);
         waitingOnFreeMemtableSpace = Metrics.newTimer(factory.createMetricName("WaitingOnFreeMemtableSpace"), TimeUnit.MICROSECONDS, TimeUnit.SECONDS);
 
-        trueSnapshotsSize = Metrics.newGauge(factory.createMetricName("SnapshotsSize"), new Gauge<Long>()
+        trueSnapshotsSize = createColumnFamilyGauge("SnapshotsSize", new Gauge<Long>()
         {
             public Long value()
             {
                 return cfs.trueSnapshotsSize();
             }
         });
-        rowCacheHitOutOfRange = Metrics.newCounter(factory.createMetricName("RowCacheHitOutOfRange"));
-        rowCacheHit = Metrics.newCounter(factory.createMetricName("RowCacheHit"));
-        rowCacheMiss = Metrics.newCounter(factory.createMetricName("RowCacheMiss"));
+        rowCacheHitOutOfRange = createColumnFamilyCounter("RowCacheHitOutOfRange");
+        rowCacheHit = createColumnFamilyCounter("RowCacheHit");
+        rowCacheMiss = createColumnFamilyCounter("RowCacheMiss");
     }
 
     public void updateSSTableIterated(int count)
@@ -405,41 +519,124 @@ public class ColumnFamilyMetrics
      */
     public void release()
     {
+        for(String name : all)
+        {
+            allColumnFamilyMetrics.get(name).remove(Metrics.defaultRegistry().allMetrics().get(factory.createMetricName(name)));
+            Metrics.defaultRegistry().removeMetric(factory.createMetricName(name));
+        }
         readLatency.release();
         writeLatency.release();
         rangeLatency.release();
-        Metrics.defaultRegistry().removeMetric(factory.createMetricName("AllMemtablesDataSize"));
-        Metrics.defaultRegistry().removeMetric(factory.createMetricName("MemtableColumnsCount"));
-        Metrics.defaultRegistry().removeMetric(factory.createMetricName("MemtableDataSize"));
-        Metrics.defaultRegistry().removeMetric(factory.createMetricName("MemtableSwitchCount"));
-        Metrics.defaultRegistry().removeMetric(factory.createMetricName("CompressionRatio"));
         Metrics.defaultRegistry().removeMetric(factory.createMetricName("EstimatedRowSizeHistogram"));
         Metrics.defaultRegistry().removeMetric(factory.createMetricName("EstimatedColumnCountHistogram"));
-        Metrics.defaultRegistry().removeMetric(factory.createMetricName("SSTablesPerReadHistogram"));
-        Metrics.defaultRegistry().removeMetric(factory.createMetricName("PendingFlushes"));
-        Metrics.defaultRegistry().removeMetric(factory.createMetricName("LiveSSTableCount"));
-        Metrics.defaultRegistry().removeMetric(factory.createMetricName("LiveDiskSpaceUsed"));
-        Metrics.defaultRegistry().removeMetric(factory.createMetricName("TotalDiskSpaceUsed"));
-        Metrics.defaultRegistry().removeMetric(factory.createMetricName("MinRowSize"));
-        Metrics.defaultRegistry().removeMetric(factory.createMetricName("MaxRowSize"));
-        Metrics.defaultRegistry().removeMetric(factory.createMetricName("MeanRowSize"));
-        Metrics.defaultRegistry().removeMetric(factory.createMetricName("BloomFilterFalsePositives"));
-        Metrics.defaultRegistry().removeMetric(factory.createMetricName("RecentBloomFilterFalsePositives"));
-        Metrics.defaultRegistry().removeMetric(factory.createMetricName("BloomFilterFalseRatio"));
-        Metrics.defaultRegistry().removeMetric(factory.createMetricName("RecentBloomFilterFalseRatio"));
-        Metrics.defaultRegistry().removeMetric(factory.createMetricName("BloomFilterDiskSpaceUsed"));
         Metrics.defaultRegistry().removeMetric(factory.createMetricName("KeyCacheHitRate"));
-        Metrics.defaultRegistry().removeMetric(factory.createMetricName("SpeculativeRetries"));
-        Metrics.defaultRegistry().removeMetric(factory.createMetricName("TombstoneScannedHistogram"));
-        Metrics.defaultRegistry().removeMetric(factory.createMetricName("LiveScannedHistogram"));
         Metrics.defaultRegistry().removeMetric(factory.createMetricName("CoordinatorReadLatency"));
         Metrics.defaultRegistry().removeMetric(factory.createMetricName("CoordinatorScanLatency"));
-        Metrics.defaultRegistry().removeMetric(factory.createMetricName("SnapshotsSize"));
-        Metrics.defaultRegistry().removeMetric(factory.createMetricName("RowCacheHitOutOfRange"));
-        Metrics.defaultRegistry().removeMetric(factory.createMetricName("RowCacheHit"));
-        Metrics.defaultRegistry().removeMetric(factory.createMetricName("RowCacheHitMiss"));
+        Metrics.defaultRegistry().removeMetric(factory.createMetricName("WaitingOnFreeMemtableSpace"));
     }
 
+
+    /**
+     * Create a gauge that will be part of a merged version of all column families.  The global gauge
+     * will merge each CF gauge by adding their values 
+     */
+    protected <T extends Number> Gauge<T> createColumnFamilyGauge(final String name, Gauge<T> gauge)
+    {
+        return createColumnFamilyGauge(name, gauge, new Gauge<Long>()
+        {
+            public Long value()
+            {
+                long total = 0;
+                for (Metric cfGauge : allColumnFamilyMetrics.get(name))
+                {
+                    total = total + ((Gauge<? extends Number>) cfGauge).value().longValue();
+                }
+                return total;
+            }
+        });
+    }
+    
+    /**
+     * Create a gauge that will be part of a merged version of all column families.  The global gauge
+     * is defined as the globalGauge parameter
+     */
+    protected <G,T> Gauge<T> createColumnFamilyGauge(String name, Gauge<T> gauge, Gauge<G> globalGauge)
+    {
+        Gauge<T> cfGauge = Metrics.newGauge(factory.createMetricName(name), gauge);
+        if (register(name, cfGauge))
+        {
+            Metrics.newGauge(globalNameFactory.createMetricName(name), globalGauge);
+        }
+        return cfGauge;
+    }
+    
+    /**
+     * Creates a counter that will also have a global counter thats the sum of all counters across 
+     * different column families
+     */
+    protected Counter createColumnFamilyCounter(final String name)
+    {
+        Counter cfCounter = Metrics.newCounter(factory.createMetricName(name));
+        if (register(name, cfCounter))
+        {
+            Metrics.newGauge(globalNameFactory.createMetricName(name), new Gauge<Long>()
+            {
+                public Long value()
+                {
+                    long total = 0;
+                    for (Metric cfGauge : allColumnFamilyMetrics.get(name))
+                    {
+                        total += ((Counter) cfGauge).count();
+                    }
+                    return total;
+                }
+            });
+        }
+        return cfCounter;
+    }
+    
+    /**
+     * Create a histogram-like interface that will register both a CF, keyspace and global level
+     * histogram and forward any updates to both
+     */
+    protected ColumnFamilyHistogram createColumnFamilyHistogram(String name, Histogram keyspaceHistogram) 
+    {
+        Histogram cfHistogram = Metrics.newHistogram(factory.createMetricName(name), true);  
+        register(name, cfHistogram);
+        return new ColumnFamilyHistogram(cfHistogram, keyspaceHistogram, Metrics.newHistogram(globalNameFactory.createMetricName(name), true));
+    }
+    
+    /**
+     * Registers a metric to be removed when unloading CF.
+     * @return true if first time metric with that name has been registered
+     */
+    private boolean register(String name, Metric metric)
+    { 
+        boolean ret = allColumnFamilyMetrics.putIfAbsent(name,  new HashSet<Metric>()) == null;
+        allColumnFamilyMetrics.get(name).add(metric);
+        all.add(name);
+        return ret;
+    }
+    
+    public class ColumnFamilyHistogram
+    {
+        public final Histogram[] all;
+        public final Histogram cf;
+        private ColumnFamilyHistogram(Histogram cf, Histogram keyspace, Histogram global) 
+        {
+            this.cf = cf;
+            this.all = new Histogram[]{cf, keyspace, global};
+        }
+        
+        public void update(long i) 
+        {
+            for(Histogram histo : all)
+            {
+                histo.update(i);
+            }
+        }
+    }
+    
     class ColumnFamilyMetricNameFactory implements MetricNameFactory
     {
         private final String keyspaceName;
@@ -468,5 +665,17 @@ public class ColumnFamilyMetrics
             return new MetricName(groupName, type, metricName, keyspaceName + "." + columnFamilyName, mbeanName.toString());
         }
     }
-
+    
+    static class AllColumnFamilyMetricNameFactory implements MetricNameFactory
+    {
+        public MetricName createMetricName(String metricName)
+        {
+            String groupName = ColumnFamilyMetrics.class.getPackage().getName(); 
+            StringBuilder mbeanName = new StringBuilder();
+            mbeanName.append(groupName).append(":");
+            mbeanName.append("type=ColumnFamily");
+            mbeanName.append(",name=").append(metricName);
+            return new MetricName(groupName, "ColumnFamily", metricName, "all", mbeanName.toString());
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/ae0f6346/src/java/org/apache/cassandra/metrics/KeyspaceMetrics.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/metrics/KeyspaceMetrics.java b/src/java/org/apache/cassandra/metrics/KeyspaceMetrics.java
index c5afcc1..92fabf1 100644
--- a/src/java/org/apache/cassandra/metrics/KeyspaceMetrics.java
+++ b/src/java/org/apache/cassandra/metrics/KeyspaceMetrics.java
@@ -17,50 +17,66 @@
  */
 package org.apache.cassandra.metrics;
 
-import java.util.ArrayList;
-import java.util.List;
-
-import com.yammer.metrics.Metrics;
-import com.yammer.metrics.core.*;
-import com.yammer.metrics.stats.Snapshot;
+import java.util.Set;
 
 import org.apache.cassandra.db.ColumnFamilyStore;
 import org.apache.cassandra.db.Keyspace;
 
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import com.yammer.metrics.Metrics;
+import com.yammer.metrics.core.*;
+
 /**
  * Metrics for {@link ColumnFamilyStore}.
  */
 public class KeyspaceMetrics
 {
-    /** Total amount of data stored in the memtable, including column related overhead. */
+    /** Total amount of live data stored in the memtable, excluding any data structure overhead */
     public final Gauge<Long> memtableLiveDataSize;
     /** Total amount of data stored in the memtable that resides on-heap, including column related overhead and overwritten rows. */
     public final Gauge<Long> memtableOnHeapDataSize;
     /** Total amount of data stored in the memtable that resides off-heap, including column related overhead and overwritten rows. */
     public final Gauge<Long> memtableOffHeapDataSize;
+    /** Total amount of live data stored in the memtables (2i and pending flush memtables included) that resides off-heap, excluding any data structure overhead */
+    public final Gauge<Long> allMemtablesLiveDataSize;
     /** Total amount of data stored in the memtables (2i and pending flush memtables included) that resides on-heap. */
     public final Gauge<Long> allMemtablesOnHeapDataSize;
     /** Total amount of data stored in the memtables (2i and pending flush memtables included) that resides off-heap. */
     public final Gauge<Long> allMemtablesOffHeapDataSize;
-    /** Total amount of live data stored in the memtables (2i and pending flush memtables included) that resides off-heap, excluding any data structure overhead */
-    public final Gauge<Long> allMemtablesLiveDataSize;
     /** Total number of columns present in the memtable. */
     public final Gauge<Long> memtableColumnsCount;
     /** Number of times flush has resulted in the memtable being switched out. */
     public final Gauge<Long> memtableSwitchCount;
     /** Estimated number of tasks pending for this column family */
-    public final Gauge<Integer> pendingFlushes;
+    public final Gauge<Long> pendingFlushes;
     /** Estimate of number of pending compactios for this CF */
-    public final Gauge<Integer> pendingCompactions;
+    public final Gauge<Long> pendingCompactions;
     /** Disk space used by SSTables belonging to this CF */
     public final Gauge<Long> liveDiskSpaceUsed;
     /** Total disk space used by SSTables belonging to this CF, including obsolete ones waiting to be GC'd */
     public final Gauge<Long> totalDiskSpaceUsed;
     /** Disk space used by bloom filter */
     public final Gauge<Long> bloomFilterDiskSpaceUsed;
-
-    private final MetricNameFactory factory;
-
+    /** (Local) read metrics */
+    public final LatencyMetrics readLatency;
+    /** (Local) range slice metrics */
+    public final LatencyMetrics rangeLatency;
+    /** (Local) write metrics */
+    public final LatencyMetrics writeLatency;
+    /** Histogram of the number of sstable data files accessed per read */
+    public final Histogram sstablesPerReadHistogram;
+    /** Tombstones scanned in queries on this Keyspace */
+    public final Histogram tombstoneScannedHistogram;
+    /** Live cells scanned in queries on this Keyspace */
+    public final Histogram liveScannedHistogram;
+    
+    public final MetricNameFactory factory;
+    private Keyspace keyspace;
+    
+    /** set containing names of all the metrics stored here, for releasing later */
+    private Set<String> allMetrics = Sets.newHashSet();
+    
     /**
      * Creates metrics for given {@link ColumnFamilyStore}.
      *
@@ -69,159 +85,108 @@ public class KeyspaceMetrics
     public KeyspaceMetrics(final Keyspace ks)
     {
         factory = new KeyspaceMetricNameFactory(ks);
-
-        memtableColumnsCount = Metrics.newGauge(factory.createMetricName("MemtableColumnsCount"), new Gauge<Long>()
+        keyspace = ks;
+        memtableColumnsCount = createKeyspaceGauge("MemtableColumnsCount", new MetricValue()
         {
-            public Long value()
+            public Long getValue(ColumnFamilyMetrics metric)
             {
-                long total = 0;
-                for (ColumnFamilyStore cf : ks.getColumnFamilyStores())
-                {
-                    total += cf.metric.memtableColumnsCount.value();
-                }
-                return total;
+                return metric.memtableColumnsCount.value();
             }
         });
-        memtableOnHeapDataSize = Metrics.newGauge(factory.createMetricName("MemtableOnHeapDataSize"), new Gauge<Long>()
+        memtableLiveDataSize = createKeyspaceGauge("MemtableLiveDataSize", new MetricValue()
         {
-            public Long value()
+            public Long getValue(ColumnFamilyMetrics metric)
             {
-                long total = 0;
-                for (ColumnFamilyStore cf : ks.getColumnFamilyStores())
-                {
-                    total += cf.metric.memtableOnHeapSize.value();
-                }
-                return total;
+                return metric.memtableLiveDataSize.value();
             }
-        });
-        memtableOffHeapDataSize = Metrics.newGauge(factory.createMetricName("MemtableOffHeapDataSize"), new Gauge<Long>()
+        }); 
+        memtableOnHeapDataSize = createKeyspaceGauge("MemtableOnHeapDataSize", new MetricValue()
         {
-            public Long value()
+            public Long getValue(ColumnFamilyMetrics metric)
             {
-                long total = 0;
-                for (ColumnFamilyStore cf : ks.getColumnFamilyStores())
-                {
-                    total += cf.metric.memtableOffHeapSize.value();
-                }
-                return total;
+                return metric.memtableOnHeapSize.value();
             }
         });
-        memtableLiveDataSize = Metrics.newGauge(factory.createMetricName("MemtableLiveDataSize"), new Gauge<Long>()
+        memtableOffHeapDataSize = createKeyspaceGauge("MemtableOffHeapDataSize", new MetricValue()
         {
-            public Long value()
+            public Long getValue(ColumnFamilyMetrics metric)
             {
-                long total = 0;
-                for (ColumnFamilyStore cf : ks.getColumnFamilyStores())
-                {
-                    total += cf.metric.memtableLiveDataSize.value();
-                }
-                return total;
+                return metric.memtableOffHeapSize.value();
             }
         });
-        allMemtablesOnHeapDataSize = Metrics.newGauge(factory.createMetricName("AllMemtablesOnHeapDataSize"), new Gauge<Long>()
+        allMemtablesLiveDataSize = createKeyspaceGauge("AllMemtablesLiveDataSize", new MetricValue()
         {
-            public Long value()
+            public Long getValue(ColumnFamilyMetrics metric)
             {
-                long total = 0;
-                for (ColumnFamilyStore cf : ks.getColumnFamilyStores())
-                {
-                    total += cf.metric.allMemtablesOnHeapSize.value();
-                }
-                return total;
+                return metric.allMemtablesLiveDataSize.value();
             }
         });
-        allMemtablesOffHeapDataSize = Metrics.newGauge(factory.createMetricName("AllMemtablesOffHeapDataSize"), new Gauge<Long>()
+        allMemtablesOnHeapDataSize = createKeyspaceGauge("AllMemtablesOnHeapDataSize", new MetricValue()
         {
-            public Long value()
+            public Long getValue(ColumnFamilyMetrics metric)
             {
-                long total = 0;
-                for (ColumnFamilyStore cf : ks.getColumnFamilyStores())
-                {
-                    total += cf.metric.allMemtablesOffHeapSize.value();
-                }
-                return total;
+                return metric.allMemtablesOnHeapSize.value();
             }
         });
-        allMemtablesLiveDataSize = Metrics.newGauge(factory.createMetricName("AllMemtablesLiveDataSize"), new Gauge<Long>()
+        allMemtablesOffHeapDataSize = createKeyspaceGauge("AllMemtablesOffHeapDataSize", new MetricValue()
         {
-            public Long value()
+            public Long getValue(ColumnFamilyMetrics metric)
             {
-                long total = 0;
-                for (ColumnFamilyStore cf : ks.getColumnFamilyStores())
-                {
-                    total += cf.metric.allMemtablesLiveDataSize.value();
-                }
-                return total;
+                return metric.allMemtablesOffHeapSize.value();
             }
         });
-        memtableSwitchCount = Metrics.newGauge(factory.createMetricName("MemtableSwitchCount"), new Gauge<Long>()
+        memtableSwitchCount = createKeyspaceGauge("MemtableSwitchCount", new MetricValue()
         {
-            public Long value()
+            public Long getValue(ColumnFamilyMetrics metric)
             {
-                long sum = 0;
-                for (ColumnFamilyStore cf : ks.getColumnFamilyStores())
-                    sum += cf.metric.memtableSwitchCount.count();
-                return sum;
+                return metric.memtableSwitchCount.count();
             }
         });
-        pendingCompactions = Metrics.newGauge(factory.createMetricName("PendingCompactions"), new Gauge<Integer>()
+        pendingCompactions = createKeyspaceGauge("PendingCompactions", new MetricValue()
         {
-            public Integer value()
+            public Long getValue(ColumnFamilyMetrics metric)
             {
-                int sum = 0;
-                for (ColumnFamilyStore cf : ks.getColumnFamilyStores())
-                {
-                    sum += cf.metric.pendingCompactions.value();
-                }
-                return sum;
+                return (long) metric.pendingCompactions.value();
             }
         });
-        pendingFlushes = Metrics.newGauge(factory.createMetricName("PendingFlushes"), new Gauge<Integer>()
+        pendingFlushes = createKeyspaceGauge("PendingFlushes", new MetricValue()
         {
-            public Integer value()
+            public Long getValue(ColumnFamilyMetrics metric)
             {
-                int sum = 0;
-                for (ColumnFamilyStore cf : ks.getColumnFamilyStores())
-                {
-                    sum += cf.metric.pendingFlushes.count();
-                }
-                return sum;
+                return (long) metric.pendingFlushes.count();
             }
         });
-        liveDiskSpaceUsed = Metrics.newGauge(factory.createMetricName("LiveDiskSpaceUsed"), new Gauge<Long>()
+        liveDiskSpaceUsed = createKeyspaceGauge("LiveDiskSpaceUsed", new MetricValue()
         {
-            public Long value()
+            public Long getValue(ColumnFamilyMetrics metric)
             {
-                long sum = 0;
-                for (ColumnFamilyStore cf : ks.getColumnFamilyStores())
-                {
-                    sum += cf.metric.liveDiskSpaceUsed.count();
-                }
-                return sum;
+                return metric.liveDiskSpaceUsed.count();
             }
         });
-        totalDiskSpaceUsed = Metrics.newGauge(factory.createMetricName("TotalDiskSpaceUsed"), new Gauge<Long>()
+        totalDiskSpaceUsed = createKeyspaceGauge("TotalDiskSpaceUsed", new MetricValue()
         {
-            public Long value()
+            public Long getValue(ColumnFamilyMetrics metric)
             {
-                long sum = 0;
-                for (ColumnFamilyStore cf : ks.getColumnFamilyStores())
-                {
-                    sum += cf.metric.totalDiskSpaceUsed.count();
-                }
-                return sum;
+                return metric.totalDiskSpaceUsed.count();
             }
         });
-        bloomFilterDiskSpaceUsed = Metrics.newGauge(factory.createMetricName("BloomFilterDiskSpaceUsed"), new Gauge<Long>()
+        bloomFilterDiskSpaceUsed = createKeyspaceGauge("BloomFilterDiskSpaceUsed", new MetricValue()
         {
-            public Long value()
+            public Long getValue(ColumnFamilyMetrics metric)
             {
-                long total = 0;
-                for (ColumnFamilyStore cf : ks.getColumnFamilyStores())
-                    total += cf.metric.bloomFilterDiskSpaceUsed.value();
-                return total;
+                return metric.bloomFilterDiskSpaceUsed.value();
             }
         });
+        // latency metrics for ColumnFamilyMetrics to update
+        readLatency = new LatencyMetrics(factory, "Read");
+        writeLatency = new LatencyMetrics(factory, "Write");
+        rangeLatency = new LatencyMetrics(factory, "Range");
+        // create histograms for ColumnFamilyMetrics to replicate updates to
+        sstablesPerReadHistogram = Metrics.newHistogram(factory.createMetricName("SSTablesPerReadHistogram"), true);
+        tombstoneScannedHistogram = Metrics.newHistogram(factory.createMetricName("TombstoneScannedHistogram"), true);
+        liveScannedHistogram = Metrics.newHistogram(factory.createMetricName("LiveScannedHistogram"), true);
+        // add manually since histograms do not use createKeyspaceGauge method
+        allMetrics.addAll(Lists.newArrayList("SSTablesPerReadHistogram", "TombstoneScannedHistogram", "LiveScannedHistogram"));
     }
 
     /**
@@ -229,18 +194,50 @@ public class KeyspaceMetrics
      */
     public void release()
     {
-        Metrics.defaultRegistry().removeMetric(factory.createMetricName("AllMemtablesLiveDataSize"));
-        Metrics.defaultRegistry().removeMetric(factory.createMetricName("AllMemtablesOnHeapDataSize"));
-        Metrics.defaultRegistry().removeMetric(factory.createMetricName("AllMemtablesOffHeapDataSize"));
-        Metrics.defaultRegistry().removeMetric(factory.createMetricName("MemtableLiveDataSize"));
-        Metrics.defaultRegistry().removeMetric(factory.createMetricName("MemtableOnHeapDataSize"));
-        Metrics.defaultRegistry().removeMetric(factory.createMetricName("MemtableOffHeapDataSize"));
-        Metrics.defaultRegistry().removeMetric(factory.createMetricName("MemtableColumnsCount"));
-        Metrics.defaultRegistry().removeMetric(factory.createMetricName("MemtableSwitchCount"));
-        Metrics.defaultRegistry().removeMetric(factory.createMetricName("PendingFlushes"));
-        Metrics.defaultRegistry().removeMetric(factory.createMetricName("LiveDiskSpaceUsed"));
-        Metrics.defaultRegistry().removeMetric(factory.createMetricName("TotalDiskSpaceUsed"));
-        Metrics.defaultRegistry().removeMetric(factory.createMetricName("BloomFilterDiskSpaceUsed"));
+        for(String name : allMetrics) 
+        {
+            Metrics.defaultRegistry().removeMetric(factory.createMetricName(name));
+        }
+        // latency metrics contain multiple metrics internally and need to be released manually
+        readLatency.release();
+        writeLatency.release();
+        rangeLatency.release();
+    }
+    
+    /**
+     * Represents a column family metric value.
+     */
+    private interface MetricValue
+    {
+        /**
+         * get value of a metric
+         * @param columnfamilymetrics of a column family in this keyspace
+         * @return current value of a metric
+         */
+        public Long getValue(ColumnFamilyMetrics metric);
+    }
+
+    /**
+     * Creates a gauge that will sum the current value of a metric for all column families in this keyspace
+     * @param name
+     * @param MetricValue 
+     * @return Gauge&gt;Long> that computes sum of MetricValue.getValue()
+     */
+    private <T extends Number> Gauge<Long> createKeyspaceGauge(String name, final MetricValue extractor)
+    {
+        allMetrics.add(name);
+        return Metrics.newGauge(factory.createMetricName(name), new Gauge<Long>()
+        {
+            public Long value()
+            {
+                long sum = 0;
+                for (ColumnFamilyStore cf : keyspace.getColumnFamilyStores())
+                {
+                    sum += extractor.getValue(cf.metric);
+                }
+                return sum;
+            }
+        });
     }
 
     class KeyspaceMetricNameFactory implements MetricNameFactory

http://git-wip-us.apache.org/repos/asf/cassandra/blob/ae0f6346/src/java/org/apache/cassandra/metrics/LatencyMetrics.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/metrics/LatencyMetrics.java b/src/java/org/apache/cassandra/metrics/LatencyMetrics.java
index b456e2a..28256fe 100644
--- a/src/java/org/apache/cassandra/metrics/LatencyMetrics.java
+++ b/src/java/org/apache/cassandra/metrics/LatencyMetrics.java
@@ -17,14 +17,17 @@
  */
 package org.apache.cassandra.metrics;
 
+import java.util.List;
 import java.util.concurrent.TimeUnit;
 
+import org.apache.cassandra.utils.EstimatedHistogram;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
 import com.yammer.metrics.Metrics;
 import com.yammer.metrics.core.Counter;
 import com.yammer.metrics.core.Timer;
 
-import org.apache.cassandra.utils.EstimatedHistogram;
-
 /**
  * Metrics about latencies
  */
@@ -35,6 +38,9 @@ public class LatencyMetrics
     /** Total latency in micro sec */
     public final Counter totalLatency;
 
+    /** parent metrics to replicate any updates to **/
+    private List<LatencyMetrics> parents = Lists.newArrayList();
+    
     protected final MetricNameFactory factory;
     protected final String namePrefix;
 
@@ -80,6 +86,20 @@ public class LatencyMetrics
         latency = Metrics.newTimer(factory.createMetricName(namePrefix + "Latency"), TimeUnit.MICROSECONDS, TimeUnit.SECONDS);
         totalLatency = Metrics.newCounter(factory.createMetricName(namePrefix + "TotalLatency"));
     }
+    
+    /**
+     * Create LatencyMetrics with given group, type, prefix to append to each metric name, and scope.  Any updates
+     * to this will also run on parent
+     *
+     * @param factory MetricName factory to use
+     * @param namePrefix Prefix to append to each metric name
+     * @param parents... any amount of parents to replicate updates to
+     */
+    public LatencyMetrics(MetricNameFactory factory, String namePrefix, LatencyMetrics ... parents)
+    {
+        this(factory, namePrefix);
+        this.parents.addAll(ImmutableList.copyOf(parents));
+    }
 
     /** takes nanoseconds **/
     public void addNano(long nanos)
@@ -89,6 +109,10 @@ public class LatencyMetrics
         totalLatency.inc(nanos / 1000);
         totalLatencyHistogram.add(nanos / 1000);
         recentLatencyHistogram.add(nanos / 1000);
+        for(LatencyMetrics parent : parents)
+        {
+            parent.addNano(nanos);
+        }
     }
 
     public void release()

http://git-wip-us.apache.org/repos/asf/cassandra/blob/ae0f6346/test/unit/org/apache/cassandra/db/KeyspaceTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/db/KeyspaceTest.java b/test/unit/org/apache/cassandra/db/KeyspaceTest.java
index a71b0dd..0bd428d 100644
--- a/test/unit/org/apache/cassandra/db/KeyspaceTest.java
+++ b/test/unit/org/apache/cassandra/db/KeyspaceTest.java
@@ -481,18 +481,18 @@ public class KeyspaceTest
             rm.apply();
             cfStore.forceBlockingFlush();
         }
-        cfStore.metric.sstablesPerReadHistogram.clear();
+        cfStore.metric.sstablesPerReadHistogram.cf.clear();
         ColumnFamily cf = cfStore.getColumnFamily(key, Composites.EMPTY, cellname("col1499"), false, 1000, System.currentTimeMillis());
-        assertEquals(cfStore.metric.sstablesPerReadHistogram.max(), 5, 0.1);
+        assertEquals(cfStore.metric.sstablesPerReadHistogram.cf.max(), 5, 0.1);
         int i = 0;
         for (Cell c : cf.getSortedColumns())
         {
             assertEquals(ByteBufferUtil.string(c.name().toByteBuffer()), "col" + (1000 + i++));
         }
         assertEquals(i, 500);
-        cfStore.metric.sstablesPerReadHistogram.clear();
+        cfStore.metric.sstablesPerReadHistogram.cf.clear();
         cf = cfStore.getColumnFamily(key, cellname("col1500"), cellname("col2000"), false, 1000, System.currentTimeMillis());
-        assertEquals(cfStore.metric.sstablesPerReadHistogram.max(), 5, 0.1);
+        assertEquals(cfStore.metric.sstablesPerReadHistogram.cf.max(), 5, 0.1);
 
         for (Cell c : cf.getSortedColumns())
         {
@@ -501,9 +501,9 @@ public class KeyspaceTest
         assertEquals(i, 1000);
 
         // reverse
-        cfStore.metric.sstablesPerReadHistogram.clear();
+        cfStore.metric.sstablesPerReadHistogram.cf.clear();
         cf = cfStore.getColumnFamily(key, cellname("col2000"), cellname("col1500"), true, 1000, System.currentTimeMillis());
-        assertEquals(cfStore.metric.sstablesPerReadHistogram.max(), 5, 0.1);
+        assertEquals(cfStore.metric.sstablesPerReadHistogram.cf.max(), 5, 0.1);
         i = 500;
         for (Cell c : cf.getSortedColumns())
         {
@@ -550,13 +550,13 @@ public class KeyspaceTest
         }
         Composite start = type.builder().add(ByteBufferUtil.bytes("a5")).add(ByteBufferUtil.bytes(85)).build();
         Composite finish = type.builder().add(ByteBufferUtil.bytes("a5")).build().end();
-        cfs.metric.sstablesPerReadHistogram.clear();
+        cfs.metric.sstablesPerReadHistogram.cf.clear();
         ColumnFamily cf = cfs.getColumnFamily(key, start, finish, false, 1000, System.currentTimeMillis());
         int colCount = 0;
         for (Cell c : cf)
             colCount++;
         assertEquals(2, colCount);
-        assertEquals(2, cfs.metric.sstablesPerReadHistogram.max(), 0.1);
+        assertEquals(2, cfs.metric.sstablesPerReadHistogram.cf.max(), 0.1);
     }
 
     private void validateSliceLarge(ColumnFamilyStore cfStore) throws IOException


Mime
View raw message