diff --git a/src/java/org/apache/cassandra/service/StorageService.java b/src/java/org/apache/cassandra/service/StorageService.java index a78786fb3f..eb3485e8a1 100644 --- a/src/java/org/apache/cassandra/service/StorageService.java +++ b/src/java/org/apache/cassandra/service/StorageService.java @@ -3546,15 +3546,24 @@ public class StorageService extends NotificationBroadcasterSupport implements IE long totalRowCountEstimate = cfs.estimatedKeysForRange(range); - // splitCount should be much smaller than number of key samples, to avoid huge sampling error - int minSamplesPerSplit = 4; - int maxSplitCount = keys.size() / minSamplesPerSplit + 1; - int splitCount = Math.max(1, Math.min(maxSplitCount, (int)(totalRowCountEstimate / keysPerSplit))); + int splitCount = calculateSplitCount(keysPerSplit, totalRowCountEstimate, keys.size()); List tokens = keysToTokens(range, keys); return getSplits(tokens, splitCount, cfs); } + static int calculateSplitCount(int keysPerSplit, long totalRowCountEstimate, int numberOfKeys) + { + // splitCount should be much smaller than number of key samples, to avoid huge sampling error + int minSamplesPerSplit = 4; + int maxSplitCount = numberOfKeys / minSamplesPerSplit + 1; + int splitCount = Math.max(1, + Math.min( + maxSplitCount, + (int) (totalRowCountEstimate / keysPerSplit))); + return splitCount; + } + private List, Long>> getSplits(List tokens, int splitCount, ColumnFamilyStore cfs) { double step = (double) (tokens.size() - 1) / splitCount; diff --git a/test/unit/org/apache/cassandra/service/StorageServiceTest.java b/test/unit/org/apache/cassandra/service/StorageServiceTest.java index 725f105db8..7a403c01bf 100644 --- a/test/unit/org/apache/cassandra/service/StorageServiceTest.java +++ b/test/unit/org/apache/cassandra/service/StorageServiceTest.java @@ -316,4 +316,25 @@ public class StorageServiceTest extends TestBaseImpl assertEquals("Cannot specify tokens without keyspace.", ex.getMessage()); } } + + @Test + public void calculateSplitCountHappyPath() + { + int result = StorageService.calculateSplitCount(2, 4, 40); + assertEquals(2, result); + } + + @Test + public void calculateSplitCountForMin() + { + int result = StorageService.calculateSplitCount(2, 100, 40); + assertEquals(11, result); + } + + @Test + public void calculateSplitCountForMaxWithOverflow() + { + int result = StorageService.calculateSplitCount(1, Long.MAX_VALUE, 4); + assertEquals(1, result); + } }