test_class.file: src/server/src/test/java/io/cassandrareaper/service/SegmentGeneratorTest.java
test_class.identifier: SegmentGeneratorTest
test_case.body: @Test(expected = ReaperException.class)
    public void testZeroSizeRange() throws Exception {
  
      List<String> tokenStrings = Lists.newArrayList(
          "0",
          "1",
          "56713727820156410577229101238628035242",
          "56713727820156410577229101238628035242",
          "113427455640312821154458202477256070484",
          "113427455640312821154458202477256070485");
  
      List<BigInteger> tokens = Lists.transform(tokenStrings, (String string) -> new BigInteger(string));
  
      SegmentGenerator generator = new SegmentGenerator("foo.bar.RandomPartitioner");
      generator.generateSegments(10, tokens, Boolean.FALSE, Maps.newHashMap(), "2.2.10");
    }
test_case.class_method_signature: SegmentGeneratorTest.testZeroSizeRange()
test_case.full_signature: @Test(expected = ReaperException.class) public void testZeroSizeRange()
test_case.identifier: testZeroSizeRange
test_case.invocations: newArrayList transform generateSegments newHashMap
test_case.modifiers: @Test(expected = ReaperException.class) public
test_case.parameters: ()
test_case.return: void
test_case.signature: void testZeroSizeRange()
focal_class.declarator: LOG = LoggerFactory.getLogger(SegmentGenerator.class)
focal_class.modifier: private static final
focal_class.original_string: private static final Logger LOG = LoggerFactory.getLogger(SegmentGenerator.class);
focal_class.type: Logger
focal_class.var_name: LOG
focal_class.declarator: COALESCING_DISABLED
        = Boolean.getBoolean(SegmentGenerator.class.getName() + ".disable.tokenrange.coalescing")
focal_class.modifier: private static final
focal_class.original_string: private static final boolean COALESCING_DISABLED
        = Boolean.getBoolean(SegmentGenerator.class.getName() + ".disable.tokenrange.coalescing");
focal_class.type: boolean
focal_class.var_name: COALESCING_DISABLED
focal_class.declarator: partitioner
focal_class.modifier: private final
focal_class.original_string: private final String partitioner;
focal_class.type: String
focal_class.var_name: partitioner
focal_class.declarator: rangeMin
focal_class.modifier: private final
focal_class.original_string: private final BigInteger rangeMin;
focal_class.type: BigInteger
focal_class.var_name: rangeMin
focal_class.declarator: rangeMax
focal_class.modifier: private final
focal_class.original_string: private final BigInteger rangeMax;
focal_class.type: BigInteger
focal_class.var_name: rangeMax
focal_class.declarator: rangeSize
focal_class.modifier: private final
focal_class.original_string: private final BigInteger rangeSize;
focal_class.type: BigInteger
focal_class.var_name: rangeSize
focal_class.file: src/server/src/main/java/io/cassandrareaper/service/SegmentGenerator.java
focal_class.identifier: SegmentGenerator
focal_class.class_method_signature: SegmentGenerator.SegmentGenerator(String partitioner)
focal_class.full_signature:   SegmentGenerator(String partitioner)
focal_class.identifier: SegmentGenerator
focal_class.parameters: (String partitioner)
focal_class.signature:  SegmentGenerator(String partitioner)
focal_class.class_method_signature: SegmentGenerator.SegmentGenerator(BigInteger rangeMin, BigInteger rangeMax)
focal_class.full_signature:   SegmentGenerator(BigInteger rangeMin, BigInteger rangeMax)
focal_class.identifier: SegmentGenerator
focal_class.parameters: (BigInteger rangeMin, BigInteger rangeMax)
focal_class.signature:  SegmentGenerator(BigInteger rangeMin, BigInteger rangeMax)
focal_class.class_method_signature: SegmentGenerator.max(BigInteger big0, BigInteger big1)
focal_class.full_signature: static BigInteger max(BigInteger big0, BigInteger big1)
focal_class.identifier: max
focal_class.modifiers: static
focal_class.parameters: (BigInteger big0, BigInteger big1)
focal_class.return: BigInteger
focal_class.signature: BigInteger max(BigInteger big0, BigInteger big1)
focal_class.class_method_signature: SegmentGenerator.min(BigInteger big0, BigInteger big1)
focal_class.full_signature: static BigInteger min(BigInteger big0, BigInteger big1)
focal_class.identifier: min
focal_class.modifiers: static
focal_class.parameters: (BigInteger big0, BigInteger big1)
focal_class.return: BigInteger
focal_class.signature: BigInteger min(BigInteger big0, BigInteger big1)
focal_class.class_method_signature: SegmentGenerator.lowerThan(BigInteger big0, BigInteger big1)
focal_class.full_signature: static boolean lowerThan(BigInteger big0, BigInteger big1)
focal_class.identifier: lowerThan
focal_class.modifiers: static
focal_class.parameters: (BigInteger big0, BigInteger big1)
focal_class.return: boolean
focal_class.signature: boolean lowerThan(BigInteger big0, BigInteger big1)
focal_class.class_method_signature: SegmentGenerator.lowerThanOrEqual(BigInteger big0, BigInteger big1)
focal_class.full_signature: static boolean lowerThanOrEqual(BigInteger big0, BigInteger big1)
focal_class.identifier: lowerThanOrEqual
focal_class.modifiers: static
focal_class.parameters: (BigInteger big0, BigInteger big1)
focal_class.return: boolean
focal_class.signature: boolean lowerThanOrEqual(BigInteger big0, BigInteger big1)
focal_class.class_method_signature: SegmentGenerator.greaterThan(BigInteger big0, BigInteger big1)
focal_class.full_signature: static boolean greaterThan(BigInteger big0, BigInteger big1)
focal_class.identifier: greaterThan
focal_class.modifiers: static
focal_class.parameters: (BigInteger big0, BigInteger big1)
focal_class.return: boolean
focal_class.signature: boolean greaterThan(BigInteger big0, BigInteger big1)
focal_class.class_method_signature: SegmentGenerator.greaterThanOrEqual(BigInteger big0, BigInteger big1)
focal_class.full_signature: static boolean greaterThanOrEqual(BigInteger big0, BigInteger big1)
focal_class.identifier: greaterThanOrEqual
focal_class.modifiers: static
focal_class.parameters: (BigInteger big0, BigInteger big1)
focal_class.return: boolean
focal_class.signature: boolean greaterThanOrEqual(BigInteger big0, BigInteger big1)
focal_class.class_method_signature: SegmentGenerator.generateSegments(
        int totalSegmentCount,
        List<BigInteger> ringTokens,
        Boolean incrementalRepair,
        Map<List<String>, List<RingRange>> replicasToRange,
        String cassandraVersion)
focal_class.full_signature:  List<Segment> generateSegments(
        int totalSegmentCount,
        List<BigInteger> ringTokens,
        Boolean incrementalRepair,
        Map<List<String>, List<RingRange>> replicasToRange,
        String cassandraVersion)
focal_class.identifier: generateSegments
focal_class.parameters: (
        int totalSegmentCount,
        List<BigInteger> ringTokens,
        Boolean incrementalRepair,
        Map<List<String>, List<RingRange>> replicasToRange,
        String cassandraVersion)
focal_class.return: List<Segment>
focal_class.signature: List<Segment> generateSegments(
        int totalSegmentCount,
        List<BigInteger> ringTokens,
        Boolean incrementalRepair,
        Map<List<String>, List<RingRange>> replicasToRange,
        String cassandraVersion)
focal_class.class_method_signature: SegmentGenerator.coalesceTokenRanges(
        BigInteger targetSegmentSize, Map<List<String>, List<RingRange>> replicasToRange)
focal_class.full_signature: @VisibleForTesting List<Segment> coalesceTokenRanges(
        BigInteger targetSegmentSize, Map<List<String>, List<RingRange>> replicasToRange)
focal_class.identifier: coalesceTokenRanges
focal_class.modifiers: @VisibleForTesting
focal_class.parameters: (
        BigInteger targetSegmentSize, Map<List<String>, List<RingRange>> replicasToRange)
focal_class.return: List<Segment>
focal_class.signature: List<Segment> coalesceTokenRanges(
        BigInteger targetSegmentSize, Map<List<String>, List<RingRange>> replicasToRange)
focal_class.class_method_signature: SegmentGenerator.allTokensHaveBeenCoalesced(
        List<Segment> coalescedRepairSegments, Map<List<String>, List<RingRange>> replicasToRange)
focal_class.full_signature: private static boolean allTokensHaveBeenCoalesced(
        List<Segment> coalescedRepairSegments, Map<List<String>, List<RingRange>> replicasToRange)
focal_class.identifier: allTokensHaveBeenCoalesced
focal_class.modifiers: private static
focal_class.parameters: (
        List<Segment> coalescedRepairSegments, Map<List<String>, List<RingRange>> replicasToRange)
focal_class.return: boolean
focal_class.signature: boolean allTokensHaveBeenCoalesced(
        List<Segment> coalescedRepairSegments, Map<List<String>, List<RingRange>> replicasToRange)
focal_class.class_method_signature: SegmentGenerator.getTargetSegmentSize(int segmentCount)
focal_class.full_signature: private BigInteger getTargetSegmentSize(int segmentCount)
focal_class.identifier: getTargetSegmentSize
focal_class.modifiers: private
focal_class.parameters: (int segmentCount)
focal_class.return: BigInteger
focal_class.signature: BigInteger getTargetSegmentSize(int segmentCount)
focal_class.class_method_signature: SegmentGenerator.inRange(BigInteger token)
focal_class.full_signature: protected boolean inRange(BigInteger token)
focal_class.identifier: inRange
focal_class.modifiers: protected
focal_class.parameters: (BigInteger token)
focal_class.return: boolean
focal_class.signature: boolean inRange(BigInteger token)
focal_class.class_method_signature: SegmentGenerator.supportsSegmentCoalescing(String cassandraVersion)
focal_class.full_signature: private boolean supportsSegmentCoalescing(String cassandraVersion)
focal_class.identifier: supportsSegmentCoalescing
focal_class.modifiers: private
focal_class.parameters: (String cassandraVersion)
focal_class.return: boolean
focal_class.signature: boolean supportsSegmentCoalescing(String cassandraVersion)
focal_method.body: List<Segment> generateSegments(
        int totalSegmentCount,
        List<BigInteger> ringTokens,
        Boolean incrementalRepair,
        Map<List<String>, List<RingRange>> replicasToRange,
        String cassandraVersion)
        throws ReaperException {
  
      List<Segment> repairSegments = Lists.newArrayList();
      int tokenRangeCount = ringTokens.size();
  
      if (tokenRangeCount < totalSegmentCount || !supportsSegmentCoalescing(cassandraVersion)) {
        // We want more segments than there are token ranges.
        // Token ranges will be subdivided to match the requirements.
        for (int i = 0; i < tokenRangeCount; i++) {
          BigInteger start = ringTokens.get(i);
          BigInteger stop = ringTokens.get((i + 1) % tokenRangeCount);
  
          if (!inRange(start) || !inRange(stop)) {
            throw new ReaperException(
                String.format("Tokens (%s,%s) not in range of %s", start, stop, partitioner));
          }
          if (start.equals(stop) && tokenRangeCount != 1) {
            throw new ReaperException(
                String.format("Tokens (%s,%s): two nodes have the same token", start, stop));
          }
  
          BigInteger rs = stop.subtract(start);
          if (lowerThanOrEqual(rs, BigInteger.ZERO)) {
            // wrap around case
            rs = rs.add(rangeSize);
          }
  
          // the below, in essence, does this:
          // segmentCount = ceiling((rangeSize / RANGE_SIZE) * totalSegmentCount)
          BigInteger[] segmentCountAndRemainder
              = rs.multiply(BigInteger.valueOf(totalSegmentCount)).divideAndRemainder(rangeSize);
  
          int segmentCount = segmentCountAndRemainder[0].intValue()
                  + (segmentCountAndRemainder[1].equals(BigInteger.ZERO) ? 0 : 1);
  
          LOG.info("Dividing token range [{},{}) into {} segments", start, stop, segmentCount);
  
          // Make big0 list of all the endpoints for the repair segments, including both start and stop
          List<BigInteger> endpointTokens = Lists.newArrayList();
          for (int j = 0; j <= segmentCount; j++) {
            BigInteger offset = rs.multiply(BigInteger.valueOf(j)).divide(BigInteger.valueOf(segmentCount));
            BigInteger reaperToken = start.add(offset);
            if (greaterThan(reaperToken, rangeMax)) {
              reaperToken = reaperToken.subtract(rangeSize);
            }
            endpointTokens.add(reaperToken);
          }
  
          // Append the segments between the endpoints
          for (int j = 0; j < segmentCount; j++) {
            repairSegments.add(
                Segment.builder()
                    .withTokenRanges(
                        Arrays.asList(
                            new RingRange(endpointTokens.get(j), endpointTokens.get(j + 1))))
                    .build());
            LOG.debug(
                "Segment #{}: [{},{})", j + 1, endpointTokens.get(j), endpointTokens.get(j + 1));
          }
        }
  
        // verify that the whole range is repaired
        BigInteger total = BigInteger.ZERO;
        for (Segment segment : repairSegments) {
          for (RingRange range : segment.getTokenRanges()) {
            BigInteger size = range.span(rangeSize);
            total = total.add(size);
          }
        }
        if (!total.equals(rangeSize) && !incrementalRepair) {
          throw new ReaperException("Not entire ring would get repaired");
        }
      } else {
        // We want less segments than there are token ranges.
        // Token ranges will be grouped to match the requirements.
        LOG.info("Less segments required than there are vnode. Coalescing eligible token ranges...");
        repairSegments = coalesceTokenRanges(getTargetSegmentSize(totalSegmentCount), replicasToRange);
      }
  
      return repairSegments;
    }
focal_method.class_method_signature: SegmentGenerator.generateSegments(
        int totalSegmentCount,
        List<BigInteger> ringTokens,
        Boolean incrementalRepair,
        Map<List<String>, List<RingRange>> replicasToRange,
        String cassandraVersion)
focal_method.full_signature:  List<Segment> generateSegments(
        int totalSegmentCount,
        List<BigInteger> ringTokens,
        Boolean incrementalRepair,
        Map<List<String>, List<RingRange>> replicasToRange,
        String cassandraVersion)
focal_method.identifier: generateSegments
focal_method.invocations: newArrayList size supportsSegmentCoalescing get get inRange inRange format equals format subtract lowerThanOrEqual add divideAndRemainder multiply valueOf intValue equals info newArrayList divide multiply valueOf valueOf add greaterThan subtract add add build withTokenRanges builder asList get get debug get get getTokenRanges span add equals info coalesceTokenRanges getTargetSegmentSize
focal_method.parameters: (
        int totalSegmentCount,
        List<BigInteger> ringTokens,
        Boolean incrementalRepair,
        Map<List<String>, List<RingRange>> replicasToRange,
        String cassandraVersion)
focal_method.return: List<Segment>
focal_method.signature: List<Segment> generateSegments(
        int totalSegmentCount,
        List<BigInteger> ringTokens,
        Boolean incrementalRepair,
        Map<List<String>, List<RingRange>> replicasToRange,
        String cassandraVersion)