blob: def804053a2167751a8420d41a8e9f14410da788 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.drill.exec.vector;
import org.apache.drill.common.config.DrillConfig;
import org.apache.drill.common.types.TypeProtos.MinorType;
import org.apache.drill.common.types.Types;
import org.apache.drill.exec.memory.BufferAllocator;
import org.apache.drill.exec.memory.RootAllocatorFactory;
import org.apache.drill.exec.record.MaterializedField;
import org.apache.drill.exec.record.TransferPair;
import org.apache.drill.exec.vector.NullableVarCharVector.Accessor;
import org.apache.drill.test.BaseTest;
import org.junit.Test;
import java.nio.charset.StandardCharsets;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertArrayEquals;
public class TestSplitAndTransfer extends BaseTest {
@Test
public void test() throws Exception {
final DrillConfig drillConfig = DrillConfig.create();
final BufferAllocator allocator = RootAllocatorFactory.newRoot(drillConfig);
final MaterializedField field = MaterializedField.create("field", Types.optional(MinorType.VARCHAR));
final NullableVarCharVector varCharVector = new NullableVarCharVector(field, allocator);
varCharVector.allocateNew(10000, 1000);
final int valueCount = 500;
final String[] compareArray = new String[valueCount];
final NullableVarCharVector.Mutator mutator = varCharVector.getMutator();
for (int i = 0; i < valueCount; i += 3) {
final String s = String.format("%010d", i);
mutator.set(i, s.getBytes(StandardCharsets.UTF_8));
compareArray[i] = s;
}
mutator.setValueCount(valueCount);
final TransferPair tp = varCharVector.getTransferPair(allocator);
final NullableVarCharVector newVarCharVector = (NullableVarCharVector) tp.getTo();
final Accessor accessor = newVarCharVector.getAccessor();
final int[][] startLengths = {{0, 201}, {201, 200}, {401, 99}};
for (final int[] startLength : startLengths) {
final int start = startLength[0];
final int length = startLength[1];
tp.splitAndTransfer(start, length);
newVarCharVector.getMutator().setValueCount(length);
for (int i = 0; i < length; i++) {
final boolean expectedSet = ((start + i) % 3) == 0;
if (expectedSet) {
final byte[] expectedValue = compareArray[start + i].getBytes(StandardCharsets.UTF_8);
assertFalse(accessor.isNull(i));
assertArrayEquals(expectedValue, accessor.get(i));
} else {
assertTrue(accessor.isNull(i));
}
}
newVarCharVector.clear();
}
varCharVector.close();
allocator.close();
}
/**
* BitVector tests
*/
enum TestBitPattern {
ZERO,
ONE,
ALTERNATING,
RANDOM
}
@Test
public void testBitVectorUnalignedStart() throws Exception {
testBitVectorImpl(16, new int[][] {{2, 4}}, TestBitPattern.RANDOM);
testBitVectorImpl(16, new int[][] {{2, 4}}, TestBitPattern.ONE);
testBitVectorImpl(16, new int[][] {{2, 4}}, TestBitPattern.ZERO);
testBitVectorImpl(16, new int[][] {{2, 4}}, TestBitPattern.ALTERNATING);
testBitVectorImpl(4096, new int[][] {{4092, 4}}, TestBitPattern.ONE);
testBitVectorImpl(4096, new int[][] {{4092, 4}}, TestBitPattern.ZERO);
testBitVectorImpl(4096, new int[][] {{4092, 4}}, TestBitPattern.ALTERNATING);
testBitVectorImpl(4096, new int[][] {{4092, 4}}, TestBitPattern.RANDOM);
testBitVectorImpl(4096, new int[][] {{1020, 8}}, TestBitPattern.ONE);
testBitVectorImpl(4096, new int[][] {{1020, 8}}, TestBitPattern.ZERO);
testBitVectorImpl(4096, new int[][] {{1020, 8}}, TestBitPattern.ALTERNATING);
testBitVectorImpl(4096, new int[][] {{1020, 8}}, TestBitPattern.RANDOM);
testBitVectorImpl(24, new int[][] {{5, 17}}, TestBitPattern.ONE);
testBitVectorImpl(24, new int[][] {{5, 17}}, TestBitPattern.ZERO);
testBitVectorImpl(24, new int[][] {{5, 17}}, TestBitPattern.ALTERNATING);
testBitVectorImpl(24, new int[][] {{5, 17}}, TestBitPattern.RANDOM);
testBitVectorImpl(3443, new int[][] {{0, 2047}, {2047, 1396}}, TestBitPattern.ZERO);
testBitVectorImpl(3443, new int[][] {{0, 2047}, {2047, 1396}}, TestBitPattern.ONE);
testBitVectorImpl(3443, new int[][] {{0, 2047}, {2047, 1396}}, TestBitPattern.ALTERNATING);
testBitVectorImpl(3443, new int[][] {{0, 2047}, {2047, 1396}}, TestBitPattern.RANDOM);
testBitVectorImpl(3447, new int[][] {{0, 2047}, {2047, 1400}}, TestBitPattern.ZERO);
testBitVectorImpl(3447, new int[][] {{0, 2047}, {2047, 1400}}, TestBitPattern.ONE);
testBitVectorImpl(3447, new int[][] {{0, 2047}, {2047, 1400}}, TestBitPattern.ALTERNATING);
testBitVectorImpl(3447, new int[][] {{0, 2047}, {2047, 1400}}, TestBitPattern.RANDOM);
}
@Test
public void testBitVectorAlignedStart() throws Exception {
testBitVectorImpl(32, new int[][] {{0, 4}}, TestBitPattern.RANDOM);
testBitVectorImpl(32, new int[][] {{0, 4}}, TestBitPattern.ONE);
testBitVectorImpl(32, new int[][] {{0, 4}}, TestBitPattern.ZERO);
testBitVectorImpl(32, new int[][] {{0, 4}}, TestBitPattern.ALTERNATING);
testBitVectorImpl(32, new int[][] {{0, 8}}, TestBitPattern.ONE);
testBitVectorImpl(32, new int[][] {{0, 8}}, TestBitPattern.ZERO);
testBitVectorImpl(32, new int[][] {{0, 8}}, TestBitPattern.ALTERNATING);
testBitVectorImpl(32, new int[][] {{0, 8}}, TestBitPattern.RANDOM);
testBitVectorImpl(24, new int[][] {{0, 17}}, TestBitPattern.ONE);
testBitVectorImpl(24, new int[][] {{0, 17}}, TestBitPattern.ZERO);
testBitVectorImpl(24, new int[][] {{0, 17}}, TestBitPattern.ALTERNATING);
testBitVectorImpl(24, new int[][] {{0, 17}}, TestBitPattern.RANDOM);
testBitVectorImpl(3444, new int[][] {{0, 2048}, {2048, 1396}}, TestBitPattern.ZERO);
testBitVectorImpl(3444, new int[][] {{0, 2048}, {2048, 1396}}, TestBitPattern.ONE);
testBitVectorImpl(3444, new int[][] {{0, 2048}, {2048, 1396}}, TestBitPattern.ALTERNATING);
testBitVectorImpl(3444, new int[][] {{0, 2048}, {2048, 1396}}, TestBitPattern.RANDOM);
testBitVectorImpl(3448, new int[][] {{0, 2048}, {2048, 1400}}, TestBitPattern.ZERO);
testBitVectorImpl(3448, new int[][] {{0, 2048}, {2048, 1400}}, TestBitPattern.ONE);
testBitVectorImpl(3448, new int[][] {{0, 2048}, {2048, 1400}}, TestBitPattern.ALTERNATING);
testBitVectorImpl(3448, new int[][] {{0, 2048}, {2048, 1400}}, TestBitPattern.RANDOM);
}
int getBit(TestBitPattern pattern, int index) {
if (pattern == TestBitPattern.RANDOM) {
return (int) (Math.random() * 2);
}
return (pattern == TestBitPattern.ALTERNATING) ? (index % 2) : ((pattern == TestBitPattern.ONE) ? 1 : 0);
}
public void testBitVectorImpl(int valueCount, final int[][] startLengths, TestBitPattern pattern) throws Exception {
final DrillConfig drillConfig = DrillConfig.create();
final BufferAllocator allocator = RootAllocatorFactory.newRoot(drillConfig);
final MaterializedField field = MaterializedField.create("field", Types.optional(MinorType.BIT));
final BitVector bitVector = new BitVector(field, allocator);
bitVector.allocateNew(valueCount + 8); // extra byte at the end that gets filled with junk
final int[] compareArray = new int[valueCount];
int testBitValue = 0;
final BitVector.Mutator mutator = bitVector.getMutator();
for (int i = 0; i < valueCount; i++) {
testBitValue = getBit(pattern, i);
mutator.set(i, testBitValue);
compareArray[i] = testBitValue;
}
// write some junk value at the end to catch
// off-by-one out-of-bound reads
for (int j = valueCount; j < valueCount + 8; j++) {
mutator.set(j, ~testBitValue); // fill with compliment of testBit
}
mutator.setValueCount(valueCount);
final TransferPair tp = bitVector.getTransferPair(allocator);
final BitVector newBitVector = (BitVector) tp.getTo();
final BitVector.Accessor accessor = newBitVector.getAccessor();
for (final int[] startLength : startLengths) {
final int start = startLength[0];
final int length = startLength[1];
tp.splitAndTransfer(start, length);
assertEquals(newBitVector.getAccessor().getValueCount(), length);
for (int i = 0; i < length; i++) {
final int expectedValue = compareArray[start + i];
assertEquals(expectedValue, accessor.get(i));
}
newBitVector.clear();
}
bitVector.close();
allocator.close();
}
}