Repository: cassandra Updated Branches: refs/heads/trunk e4c99d67e -> 229e61282
Fix AIOOBE when concurrently accessing ABSC patch by Aleksey Yeschenko and Benedict Elliott Smith for CASSANDRA-6742 Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/d5c3d2fa Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/d5c3d2fa Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/d5c3d2fa Branch: refs/heads/trunk Commit: d5c3d2fa56e63c9ae5cd6d6a0cab06b5eb2b6b9f Parents: ce2bbcb Author: Aleksey Yeschenko <alek...@apache.org> Authored: Thu Feb 20 02:16:51 2014 +0300 Committer: Aleksey Yeschenko <alek...@apache.org> Committed: Thu Feb 20 02:26:28 2014 +0300 ---------------------------------------------------------------------- CHANGES.txt | 1 + .../cassandra/db/ArrayBackedSortedColumns.java | 18 +++++++++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/d5c3d2fa/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index e7b8802..8b887cb 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,5 +1,6 @@ 2.1.0-beta2 * Allow nodetool to use a file or prompt for password (CASSANDRA-6660) + * Fix AIOOBE when concurrently accessing ABSC (CASSANDRA-6742) 2.1.0-beta1 * Add flush directory distinct from compaction directories (CASSANDRA-6357) http://git-wip-us.apache.org/repos/asf/cassandra/blob/d5c3d2fa/src/java/org/apache/cassandra/db/ArrayBackedSortedColumns.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/db/ArrayBackedSortedColumns.java b/src/java/org/apache/cassandra/db/ArrayBackedSortedColumns.java index eaebd11..7d966ac 100644 --- a/src/java/org/apache/cassandra/db/ArrayBackedSortedColumns.java +++ b/src/java/org/apache/cassandra/db/ArrayBackedSortedColumns.java @@ -47,7 +47,7 @@ public class ArrayBackedSortedColumns extends ColumnFamily private Cell[] cells; private int size; - private int sortedSize; + private volatile int sortedSize; public static final ColumnFamily.Factory<ArrayBackedSortedColumns> factory = new Factory<ArrayBackedSortedColumns>() { @@ -103,8 +103,14 @@ public class ArrayBackedSortedColumns extends ColumnFamily sortCells(); } - private void sortCells() + /** + * synchronized so that concurrent (read-only) accessors don't mess the internal state. + */ + private synchronized void sortCells() { + if (size == sortedSize) + return; // Just sorted by a previous call. + Comparator<Cell> comparator = reversed ? getComparator().columnReverseComparator() : getComparator().columnComparator(); @@ -126,8 +132,8 @@ public class ArrayBackedSortedColumns extends ColumnFamily int rightStart = sortedSize; int rightEnd = size; - // 'Trim' the size to what's left without the leftCopy - size = sortedSize = pos; + sortedSize = -1; // Set to -1 to avoid the pos == sortedSize edge case + size = pos; // 'Trim' the size to what's left without the leftCopy // Merge the cells from both segments. When adding from the left segment we can rely on it not having any // duplicate cells, and thus omit the comparison with the previously entered cell - we'll never need to reconcile. @@ -147,6 +153,9 @@ public class ArrayBackedSortedColumns extends ColumnFamily while (r < rightEnd) internalAppendOrReconcile(cells[r++]); + // Fully sorted at this point + sortedSize = size; + // Nullify the remainder of the array (in case we had duplicate cells that got reconciled) for (int i = size; i < rightEnd; i++) cells[i] = null; @@ -242,7 +251,6 @@ public class ArrayBackedSortedColumns extends ColumnFamily { cells[size] = cell; size++; - sortedSize++; } /**