Updated Branches: refs/heads/cassandra-2.0 800e45f48 -> 16f99c5a2 refs/heads/trunk 319877fda -> de9be79d5
Fix EstimatedHistogram races patch by Paulo Gaspar; reviewed by jbellis for CASSANDRA-6682 Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/16f99c5a Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/16f99c5a Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/16f99c5a Branch: refs/heads/cassandra-2.0 Commit: 16f99c5a2edd2df3ed9512d3598d60f845e58d19 Parents: 800e45f Author: Jonathan Ellis <jbel...@apache.org> Authored: Mon Feb 10 00:43:14 2014 -0600 Committer: Jonathan Ellis <jbel...@apache.org> Committed: Mon Feb 10 00:43:14 2014 -0600 ---------------------------------------------------------------------- CHANGES.txt | 2 ++ .../cassandra/utils/EstimatedHistogram.java | 31 ++++++++++++-------- 2 files changed, 20 insertions(+), 13 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/16f99c5a/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index d32490e..b98dec7 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 2.0.6 + * Fix EstimatedHistogram races (CASSANDRA-6682) * Failure detector correctly converts initial value to nanos (CASSANDRA-6658) * Add nodetool taketoken to relocate vnodes (CASSANDRA-4445) * Fix upgradesstables NPE for non-CF-based indexes (CASSANDRA-6645) @@ -13,6 +14,7 @@ Merged from 1.2: * Fix mean cells and mean row size per sstable calculations (CASSANDRA-6667) * Compact hints after partial replay to clean out tombstones (CASSANDRA-6666) + 2.0.5 * Reduce garbage generated by bloom filter lookups (CASSANDRA-6609) * Add ks.cf names to tombstone logging (CASSANDRA-6597) http://git-wip-us.apache.org/repos/asf/cassandra/blob/16f99c5a/src/java/org/apache/cassandra/utils/EstimatedHistogram.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/utils/EstimatedHistogram.java b/src/java/org/apache/cassandra/utils/EstimatedHistogram.java index 1b8ffe1..5941057 100644 --- a/src/java/org/apache/cassandra/utils/EstimatedHistogram.java +++ b/src/java/org/apache/cassandra/utils/EstimatedHistogram.java @@ -44,7 +44,7 @@ public class EstimatedHistogram * * Each bucket represents values from (previous bucket offset, current offset]. */ - private long[] bucketOffsets; + private final long[] bucketOffsets; // buckets is one element longer than bucketOffsets -- the last element is values greater than the last offset final AtomicLongArray buckets; @@ -56,7 +56,7 @@ public class EstimatedHistogram public EstimatedHistogram(int bucketCount) { - makeOffsets(bucketCount); + bucketOffsets = newOffsets(bucketCount); buckets = new AtomicLongArray(bucketOffsets.length + 1); } @@ -67,19 +67,21 @@ public class EstimatedHistogram buckets = new AtomicLongArray(bucketData); } - private void makeOffsets(int size) + private static long[] newOffsets(int size) { - bucketOffsets = new long[size]; + long[] result = new long[size]; long last = 1; - bucketOffsets[0] = last; + result[0] = last; for (int i = 1; i < size; i++) { long next = Math.round(last * 1.2); if (next == last) next++; - bucketOffsets[i] = next; + result[i] = next; last = next; } + + return result; } /** @@ -120,13 +122,15 @@ public class EstimatedHistogram */ public long[] getBuckets(boolean reset) { - long[] rv = new long[buckets.length()]; - for (int i = 0; i < buckets.length(); i++) - rv[i] = buckets.get(i); + final int len = buckets.length(); + long[] rv = new long[len]; if (reset) - for (int i = 0; i < buckets.length(); i++) - buckets.set(i, 0L); + for (int i = 0; i < len; i++) + rv[i] = buckets.getAndSet(i, 0L); + else + for (int i = 0; i < len; i++) + rv[i] = buckets.get(i); return rv; } @@ -201,8 +205,9 @@ public class EstimatedHistogram long sum = 0; for (int i = 0; i < lastBucket; i++) { - elements += buckets.get(i); - sum += buckets.get(i) * bucketOffsets[i]; + long bCount = buckets.get(i); + elements += bCount; + sum += bCount * bucketOffsets[i]; } return (long) Math.ceil((double) sum / elements);