|
21 | 21 |
|
22 | 22 | import com.fasterxml.jackson.databind.ObjectMapper; |
23 | 23 | import com.google.common.base.Preconditions; |
| 24 | +import com.google.common.collect.ImmutableList; |
24 | 25 | import com.google.common.collect.Iterables; |
25 | 26 | import com.google.common.util.concurrent.Futures; |
26 | 27 | import com.google.inject.Guice; |
|
36 | 37 | import org.apache.druid.guice.annotations.Json; |
37 | 38 | import org.apache.druid.indexer.TaskStatus; |
38 | 39 | import org.apache.druid.indexer.granularity.UniformGranularitySpec; |
| 40 | +import org.apache.druid.indexer.partitions.DimensionRangePartitionsSpec; |
39 | 41 | import org.apache.druid.indexer.partitions.DynamicPartitionsSpec; |
| 42 | +import org.apache.druid.indexer.partitions.PartitionsSpec; |
40 | 43 | import org.apache.druid.indexing.common.LockGranularity; |
41 | 44 | import org.apache.druid.indexing.common.TaskToolbox; |
42 | 45 | import org.apache.druid.indexing.common.TestUtils; |
|
46 | 49 | import org.apache.druid.indexing.common.task.CompactionTaskRunBase; |
47 | 50 | import org.apache.druid.indexing.common.task.IndexTask; |
48 | 51 | import org.apache.druid.indexing.common.task.Tasks; |
| 52 | +import org.apache.druid.indexing.common.task.TuningConfigBuilder; |
49 | 53 | import org.apache.druid.java.util.common.Intervals; |
50 | 54 | import org.apache.druid.java.util.common.Pair; |
51 | 55 | import org.apache.druid.java.util.common.concurrent.Execs; |
|
76 | 80 | import org.apache.druid.segment.IndexSpec; |
77 | 81 | import org.apache.druid.segment.QueryableIndexSegment; |
78 | 82 | import org.apache.druid.segment.ReferenceCountedSegmentProvider; |
| 83 | +import org.apache.druid.segment.indexing.TuningConfig; |
79 | 84 | import org.apache.druid.segment.loading.AcquireSegmentAction; |
80 | 85 | import org.apache.druid.segment.loading.AcquireSegmentResult; |
81 | 86 | import org.apache.druid.segment.loading.DataSegmentPusher; |
|
89 | 94 | import org.apache.druid.timeline.CompactionState; |
90 | 95 | import org.apache.druid.timeline.DataSegment; |
91 | 96 | import org.apache.druid.timeline.partition.NumberedShardSpec; |
| 97 | +import org.apache.druid.timeline.partition.ShardSpec; |
92 | 98 | import org.joda.time.Interval; |
93 | 99 | import org.junit.Assert; |
94 | 100 | import org.junit.Assume; |
@@ -581,18 +587,82 @@ public void testIncrementalCompaction() throws Exception |
581 | 587 | Assert.assertEquals(1, resultPair2.rhs.getSegments().size()); |
582 | 588 | final DataSegment compactedSegment2 = Iterables.getOnlyElement(resultPair2.rhs.getSegments()); |
583 | 589 |
|
584 | | - final List<DataSegment> usedSegments = |
585 | | - coordinatorClient.fetchUsedSegments(DATA_SOURCE, List.of(Intervals.of("2014-01-01/2014-01-02"))).get(); |
| 590 | + final List<String> usedSegments = |
| 591 | + coordinatorClient.fetchUsedSegments(DATA_SOURCE, List.of(Intervals.of("2014-01-01/2014-01-02"))) |
| 592 | + .get() |
| 593 | + .stream() |
| 594 | + .map(DataSegment::toString) |
| 595 | + .collect(Collectors.toList()); |
586 | 596 | Assert.assertEquals( |
587 | 597 | List.of( |
588 | | - compactedSegment2, |
| 598 | + compactedSegment2.withShardSpec(new NumberedShardSpec(0, 2)).toString(), |
| 599 | + // shard spec in compactedSegment2 has been updated |
589 | 600 | compactedSegment1.toBuilder() |
590 | 601 | .shardSpec(new NumberedShardSpec(1, 2)) |
591 | 602 | .version(compactedSegment2.getVersion()) |
592 | | - .build() // compactedSegment1 has been upgraded with the new version & shardSpec |
| 603 | + .build() |
| 604 | + .toString() // compactedSegment1 has been upgraded with the new version & shardSpec |
593 | 605 | ), usedSegments); |
594 | 606 | } |
595 | 607 |
|
| 608 | + @Test |
| 609 | + public void testIncrementalCompactionRangePartition() throws Exception |
| 610 | + { |
| 611 | + List<String> rows = ImmutableList.of( |
| 612 | + "2014-01-01T00:00:10Z,a,1\n", |
| 613 | + "2014-01-01T00:00:10Z,b,2\n", |
| 614 | + "2014-01-01T00:00:10Z,c,3\n", |
| 615 | + "2014-01-01T01:00:20Z,a,1\n", |
| 616 | + "2014-01-01T01:00:20Z,b,2\n", |
| 617 | + "2014-01-01T01:00:20Z,c,3\n", |
| 618 | + "2014-01-01T02:00:30Z,a,1\n", |
| 619 | + "2014-01-01T02:00:30Z,b,2\n", |
| 620 | + "2014-01-01T02:00:30Z,c,3\n" |
| 621 | + ); |
| 622 | + Assume.assumeTrue(lockGranularity == LockGranularity.TIME_CHUNK); |
| 623 | + Assume.assumeTrue("Incremental compaction depends on concurrent lock", useConcurrentLocks); |
| 624 | + verifyTaskSuccessRowsAndSchemaMatch( |
| 625 | + runTask(buildIndexTask(DEFAULT_PARSE_SPEC, rows, inputInterval, false)), |
| 626 | + 9 |
| 627 | + ); |
| 628 | + |
| 629 | + PartitionsSpec rangePartitionSpec = new DimensionRangePartitionsSpec(null, 3, List.of("dim"), false); |
| 630 | + TuningConfig tuningConfig = TuningConfigBuilder.forCompactionTask() |
| 631 | + .withMaxTotalRows(Long.MAX_VALUE) |
| 632 | + .withPartitionsSpec(rangePartitionSpec) |
| 633 | + .withForceGuaranteedRollup(true) |
| 634 | + .build(); |
| 635 | + final CompactionTask compactionTask1 = |
| 636 | + compactionTaskBuilder(segmentGranularity).interval(inputInterval, true).tuningConfig(tuningConfig).build(); |
| 637 | + |
| 638 | + final Pair<TaskStatus, DataSegmentsWithSchemas> resultPair1 = runTask(compactionTask1); |
| 639 | + verifyTaskSuccessRowsAndSchemaMatch(resultPair1, 9); |
| 640 | + Assert.assertEquals(3, resultPair1.rhs.getSegments().size()); |
| 641 | + |
| 642 | + Pair<TaskStatus, DataSegmentsWithSchemas> appendTask = |
| 643 | + runTask(buildIndexTask(DEFAULT_PARSE_SPEC, rows, inputInterval, true)); |
| 644 | + verifyTaskSuccessRowsAndSchemaMatch(appendTask, 9); |
| 645 | + |
| 646 | + List<SegmentDescriptor> uncompacted = appendTask.rhs.getSegments() |
| 647 | + .stream() |
| 648 | + .map(DataSegment::toDescriptor) |
| 649 | + .collect(Collectors.toList()); |
| 650 | + final CompactionTask compactionTask2 = |
| 651 | + compactionTaskBuilder(segmentGranularity) |
| 652 | + .inputSpec(new CompactionIntervalSpec(inputInterval, uncompacted, null), true) |
| 653 | + .tuningConfig(tuningConfig) |
| 654 | + .build(); |
| 655 | + final Pair<TaskStatus, DataSegmentsWithSchemas> resultPair2 = runTask(compactionTask2); |
| 656 | + verifyTaskSuccessRowsAndSchemaMatch(resultPair2, 9); |
| 657 | + Assert.assertEquals(3, resultPair2.rhs.getSegments().size()); |
| 658 | + |
| 659 | + final List<DataSegment> usedSegments = |
| 660 | + coordinatorClient.fetchUsedSegments(DATA_SOURCE, List.of(Intervals.of("2014-01-01/2014-01-02"))).get(); |
| 661 | + Assert.assertEquals(6, usedSegments.size()); |
| 662 | + final List<ShardSpec> shards = usedSegments.stream().map(DataSegment::getShardSpec).collect(Collectors.toList()); |
| 663 | + Assert.assertEquals(Set.of("range"), shards.stream().map(ShardSpec::getType).collect(Collectors.toSet())); |
| 664 | + } |
| 665 | + |
596 | 666 | @Test |
597 | 667 | public void testIncrementalCompactionOverlappingInterval() throws Exception |
598 | 668 | { |
|
0 commit comments