Search in sources :

Example 1 with MergeTask

use of org.apache.drill.exec.physical.impl.xsort.managed.SortMemoryManager.MergeTask in project drill by axbaretto.

the class TestExternalSortInternals method testMergeCalcsExtreme.

@Test
public void testMergeCalcsExtreme() {
    SortConfig sortConfig = new SortConfig(fixture.getFragmentContext().getConfig(), fixture.getFragmentContext().getOptions());
    // Force odd situation in which the spill batch is larger
    // than memory. Won't actually run, but needed to test
    // odd merge case.
    long memoryLimit = ONE_MEG / 2;
    SortMemoryManager memManager = new SortMemoryManager(sortConfig, memoryLimit);
    // Prime the estimates. Batch size is data size, not buffer size.
    int rowWidth = (int) memoryLimit;
    int rowCount = 1;
    int batchSize = rowWidth;
    memManager.updateEstimates(batchSize, rowWidth, rowCount);
    assertTrue(memManager.getMergeMemoryLimit() < rowWidth);
    // Only one spill batch, that batch is above the merge memory limit,
    // but nothing useful comes from merging.
    MergeTask task = memManager.consolidateBatches(0, 0, 1);
    assertEquals(MergeAction.NONE, task.action);
}
Also used : MergeTask(org.apache.drill.exec.physical.impl.xsort.managed.SortMemoryManager.MergeTask) OperatorTest(org.apache.drill.categories.OperatorTest) SubOperatorTest(org.apache.drill.test.SubOperatorTest) Test(org.junit.Test)

Example 2 with MergeTask

use of org.apache.drill.exec.physical.impl.xsort.managed.SortMemoryManager.MergeTask in project drill by axbaretto.

the class TestExternalSortInternals method testMergeLimit.

@Test
public void testMergeLimit() {
    // Constrain merge width
    int mergeLimitConstraint = 5;
    OperatorFixture.Builder builder = new OperatorFixture.Builder();
    builder.configBuilder().put(ExecConstants.EXTERNAL_SORT_MERGE_LIMIT, mergeLimitConstraint).build();
    FragmentContext fragmentContext = builder.build().getFragmentContext();
    SortConfig sortConfig = new SortConfig(fragmentContext.getConfig(), fragmentContext.getOptions());
    // Plenty of memory, memory will not be a limit
    long memoryLimit = 400 * ONE_MEG;
    SortMemoryManager memManager = new SortMemoryManager(sortConfig, memoryLimit);
    // Prime the estimates
    int rowWidth = 300;
    int rowCount = 10000;
    int batchSize = rowWidth * rowCount * 2;
    memManager.updateEstimates(batchSize, rowWidth, rowCount);
    // Pretend merge limit runs, additional in-memory batches
    int memBatchCount = 10;
    int spillRunCount = mergeLimitConstraint;
    long allocMemory = batchSize * memBatchCount;
    MergeTask task = memManager.consolidateBatches(allocMemory, memBatchCount, spillRunCount);
    assertEquals(MergeAction.SPILL, task.action);
    // too many to merge, spill
    task = memManager.consolidateBatches(allocMemory, 1, spillRunCount);
    assertEquals(MergeAction.SPILL, task.action);
    // One more runs than can merge in one go, intermediate merge
    task = memManager.consolidateBatches(0, 0, spillRunCount + 1);
    assertEquals(MergeAction.MERGE, task.action);
    assertEquals(2, task.count);
    // Two more spill runs, merge three
    task = memManager.consolidateBatches(0, 0, spillRunCount + 2);
    assertEquals(MergeAction.MERGE, task.action);
    assertEquals(3, task.count);
    // Way more than can merge, limit to the constraint
    task = memManager.consolidateBatches(0, 0, spillRunCount * 3);
    assertEquals(MergeAction.MERGE, task.action);
    assertEquals(mergeLimitConstraint, task.count);
}
Also used : MergeTask(org.apache.drill.exec.physical.impl.xsort.managed.SortMemoryManager.MergeTask) FragmentContext(org.apache.drill.exec.ops.FragmentContext) OperatorFixture(org.apache.drill.test.OperatorFixture) OperatorTest(org.apache.drill.categories.OperatorTest) SubOperatorTest(org.apache.drill.test.SubOperatorTest) Test(org.junit.Test)

Example 3 with MergeTask

use of org.apache.drill.exec.physical.impl.xsort.managed.SortMemoryManager.MergeTask in project drill by axbaretto.

the class TestExternalSortInternals method testMergeCalcs.

@Test
public void testMergeCalcs() {
    // No artificial merge limit
    int mergeLimitConstraint = 100;
    OperatorFixture.Builder builder = new OperatorFixture.Builder();
    builder.configBuilder().put(ExecConstants.EXTERNAL_SORT_MERGE_LIMIT, mergeLimitConstraint).build();
    FragmentContext fragmentContext = builder.build().getFragmentContext();
    SortConfig sortConfig = new SortConfig(fragmentContext.getConfig(), fragmentContext.getOptions());
    // Allow four spill batches, 8 MB each, plus one output of 16
    // Allow for internal fragmentation
    // 96 > (4 * 8 + 16) * 2
    long memoryLimit = 96 * ONE_MEG;
    SortMemoryManager memManager = new SortMemoryManager(sortConfig, memoryLimit);
    // Prime the estimates. Batch size is data size, not buffer size.
    int rowWidth = 300;
    int rowCount = 10000;
    int batchSize = rowWidth * rowCount * 2;
    memManager.updateEstimates(batchSize, rowWidth, rowCount);
    assertFalse(memManager.isLowMemory());
    int spillBatchBufferSize = memManager.getSpillBatchSize().maxBufferSize;
    int inputBatchBufferSize = memManager.getInputBatchSize().expectedBufferSize;
    // One in-mem batch, no merging.
    long allocMemory = inputBatchBufferSize;
    MergeTask task = memManager.consolidateBatches(allocMemory, 1, 0);
    assertEquals(MergeAction.NONE, task.action);
    // Many in-mem batches, just enough to merge
    int memBatches = (int) (memManager.getMergeMemoryLimit() / inputBatchBufferSize);
    allocMemory = memBatches * inputBatchBufferSize;
    task = memManager.consolidateBatches(allocMemory, memBatches, 0);
    assertEquals(MergeAction.NONE, task.action);
    // Spills if no room to merge spilled and in-memory batches
    int spillCount = (int) Math.ceil((memManager.getMergeMemoryLimit() - allocMemory) / (1.0 * spillBatchBufferSize));
    assertTrue(spillCount >= 1);
    task = memManager.consolidateBatches(allocMemory, memBatches, spillCount);
    assertEquals(MergeAction.SPILL, task.action);
    // One more in-mem batch: now needs to spill
    memBatches++;
    allocMemory = memBatches * inputBatchBufferSize;
    task = memManager.consolidateBatches(allocMemory, memBatches, 0);
    assertEquals(MergeAction.SPILL, task.action);
    // No spill for various in-mem/spill run combinations
    long freeMem = memManager.getMergeMemoryLimit() - spillBatchBufferSize;
    memBatches = (int) (freeMem / inputBatchBufferSize);
    allocMemory = memBatches * inputBatchBufferSize;
    task = memManager.consolidateBatches(allocMemory, memBatches, 1);
    assertEquals(MergeAction.NONE, task.action);
    freeMem = memManager.getMergeMemoryLimit() - 2 * spillBatchBufferSize;
    memBatches = (int) (freeMem / inputBatchBufferSize);
    allocMemory = memBatches * inputBatchBufferSize;
    task = memManager.consolidateBatches(allocMemory, memBatches, 2);
    assertEquals(MergeAction.NONE, task.action);
    // No spill if no in-memory, only spill, and spill fits
    freeMem = memManager.getMergeMemoryLimit();
    int spillBatches = (int) (freeMem / spillBatchBufferSize);
    task = memManager.consolidateBatches(0, 0, spillBatches);
    assertEquals(MergeAction.NONE, task.action);
    // One more and must merge
    task = memManager.consolidateBatches(0, 0, spillBatches + 1);
    assertEquals(MergeAction.MERGE, task.action);
    assertEquals(2, task.count);
    // Two more and will merge more
    task = memManager.consolidateBatches(0, 0, spillBatches + 2);
    assertEquals(MergeAction.MERGE, task.action);
    assertEquals(3, task.count);
    // If only one spilled run, and no in-memory batches,
    // skip merge.
    task = memManager.consolidateBatches(0, 0, 1);
    assertEquals(MergeAction.NONE, task.action);
    // Very large number of spilled runs. Limit to what fits in memory.
    task = memManager.consolidateBatches(0, 0, 1000);
    assertEquals(MergeAction.MERGE, task.action);
    assertTrue(task.count <= (int) (memoryLimit / spillBatchBufferSize) - 1);
}
Also used : MergeTask(org.apache.drill.exec.physical.impl.xsort.managed.SortMemoryManager.MergeTask) FragmentContext(org.apache.drill.exec.ops.FragmentContext) OperatorFixture(org.apache.drill.test.OperatorFixture) OperatorTest(org.apache.drill.categories.OperatorTest) SubOperatorTest(org.apache.drill.test.SubOperatorTest) Test(org.junit.Test)

Aggregations

OperatorTest (org.apache.drill.categories.OperatorTest)3 MergeTask (org.apache.drill.exec.physical.impl.xsort.managed.SortMemoryManager.MergeTask)3 SubOperatorTest (org.apache.drill.test.SubOperatorTest)3 Test (org.junit.Test)3 FragmentContext (org.apache.drill.exec.ops.FragmentContext)2 OperatorFixture (org.apache.drill.test.OperatorFixture)2