com.facebook.presto.rcfile.AbstractTestRcFileReader.java Source code

Java tutorial

Introduction

Here is the source code for com.facebook.presto.rcfile.AbstractTestRcFileReader.java

Source

/*
 * Licensed 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 com.facebook.presto.rcfile;

import com.facebook.presto.spi.type.DecimalType;
import com.facebook.presto.spi.type.SqlDate;
import com.facebook.presto.spi.type.SqlDecimal;
import com.facebook.presto.spi.type.SqlTimestamp;
import com.facebook.presto.spi.type.SqlVarbinary;
import com.google.common.collect.ContiguousSet;
import com.google.common.collect.DiscreteDomain;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Range;
import org.joda.time.DateTimeZone;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;

import static com.facebook.presto.rcfile.RcFileTester.Format.BINARY;
import static com.facebook.presto.spi.type.BigintType.BIGINT;
import static com.facebook.presto.spi.type.BooleanType.BOOLEAN;
import static com.facebook.presto.spi.type.DateType.DATE;
import static com.facebook.presto.spi.type.DoubleType.DOUBLE;
import static com.facebook.presto.spi.type.IntegerType.INTEGER;
import static com.facebook.presto.spi.type.RealType.REAL;
import static com.facebook.presto.spi.type.SmallintType.SMALLINT;
import static com.facebook.presto.spi.type.TimeZoneKey.UTC_KEY;
import static com.facebook.presto.spi.type.TimestampType.TIMESTAMP;
import static com.facebook.presto.spi.type.TinyintType.TINYINT;
import static com.facebook.presto.spi.type.VarbinaryType.VARBINARY;
import static com.facebook.presto.spi.type.VarcharType.VARCHAR;
import static com.google.common.collect.Iterables.cycle;
import static com.google.common.collect.Iterables.limit;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Collections.nCopies;
import static java.util.stream.Collectors.toList;
import static org.testng.Assert.assertEquals;

public abstract class AbstractTestRcFileReader {
    private static final DecimalType DECIMAL_TYPE_PRECISION_2 = DecimalType.createDecimalType(2, 1);
    private static final DecimalType DECIMAL_TYPE_PRECISION_4 = DecimalType.createDecimalType(4, 2);
    private static final DecimalType DECIMAL_TYPE_PRECISION_8 = DecimalType.createDecimalType(8, 4);
    private static final DecimalType DECIMAL_TYPE_PRECISION_17 = DecimalType.createDecimalType(17, 8);
    private static final DecimalType DECIMAL_TYPE_PRECISION_18 = DecimalType.createDecimalType(18, 8);
    private static final DecimalType DECIMAL_TYPE_PRECISION_38 = DecimalType.createDecimalType(38, 16);

    private final RcFileTester tester;

    public AbstractTestRcFileReader(RcFileTester tester) {
        this.tester = tester;
    }

    @BeforeClass
    public void setUp() {
        assertEquals(DateTimeZone.getDefault(), RcFileTester.HIVE_STORAGE_TIME_ZONE);
    }

    @Test
    public void testNoData() throws Exception {
        tester.testRoundTrip(VARCHAR, ImmutableList.of());
    }

    @Test
    public void testBooleanSequence() throws Exception {
        tester.testRoundTrip(BOOLEAN, limit(cycle(ImmutableList.of(true, false, false)), 3_000));
    }

    @Test
    public void testByteSequence() throws Exception {
        tester.testRoundTrip(TINYINT,
                intsBetween(-31_234, 31_234).stream().filter(i -> i % 11 == 0).map(Integer::byteValue) // truncate values to byte range
                        .collect(toList()));
    }

    @Test
    public void testShortSequence() throws Exception {
        tester.testRoundTrip(SMALLINT,
                intsBetween(-31_234, 31_234).stream().filter(i -> i % 11 == 0).map(Integer::shortValue) // truncate values to short range
                        .collect(toList()));
        tester.testRoundTrip(SMALLINT,
                intsBetween(Short.MIN_VALUE, Short.MIN_VALUE + 1000).stream().map(Integer::shortValue) // truncate values to short range
                        .collect(toList()));
        tester.testRoundTrip(SMALLINT,
                intsBetween(Short.MAX_VALUE - 1000, Short.MAX_VALUE).stream().map(Integer::shortValue) // truncate values to short range
                        .collect(toList()));
    }

    @Test
    public void testIntSequence() throws Exception {
        tester.testRoundTrip(INTEGER,
                intsBetween(-31_234, 31_234).stream().filter(i -> i % 11 == 0).collect(toList()));
        tester.testRoundTrip(INTEGER, intsBetween(Integer.MIN_VALUE, Integer.MIN_VALUE + 1000));
        tester.testRoundTrip(INTEGER, intsBetween(Integer.MAX_VALUE - 1000, Integer.MAX_VALUE));
    }

    @Test
    public void testLongSequence() throws Exception {
        tester.testRoundTrip(BIGINT,
                longsBetween(-31_234, 31_234).stream().filter(i -> i % 11 == 0).collect(toList()));
        tester.testRoundTrip(BIGINT, longsBetween(Long.MIN_VALUE, Long.MIN_VALUE + 1000));
        tester.testRoundTrip(BIGINT, longsBetween(Long.MAX_VALUE - 1000, Long.MAX_VALUE));
    }

    @Test
    public void testDateSequence() throws Exception {
        tester.testRoundTrip(DATE,
                intsBetween(-31_234, 31_234).stream().filter(i -> i % 11 == 0).map(SqlDate::new).collect(toList()));
    }

    @Test
    public void testTimestampSequence() throws Exception {
        tester.testRoundTrip(TIMESTAMP, intsBetween(-31_234, 31_234).stream().filter(i -> i % 19 == 0)
                .map(timestamp -> new SqlTimestamp(timestamp, UTC_KEY)).collect(toList()));
    }

    @Test
    public void testFloatSequence() throws Exception {
        // this results in rounding errors inside of structural types
        tester.testRoundTrip(REAL,
                doubleSequence(-500.12f, 1.0f, 3_000).stream().map(Double::floatValue).collect(toList()));
    }

    @Test
    public void testDoubleSequence() throws Exception {
        tester.testRoundTrip(DOUBLE, doubleSequence(-500.12, 1, 3_000));
    }

    @Test
    public void testDecimalSequence() throws Exception {
        tester.testRoundTrip(DECIMAL_TYPE_PRECISION_2, decimalSequence("-30", "1", 60, 2, 1));
        tester.testRoundTrip(DECIMAL_TYPE_PRECISION_4, decimalSequence("-3000", "6", 1_000, 4, 2));
        tester.testRoundTrip(DECIMAL_TYPE_PRECISION_8, decimalSequence("-3000000", "6000", 1_000, 8, 4));
        tester.testRoundTrip(DECIMAL_TYPE_PRECISION_17, decimalSequence("-30000000000", "60000000", 1_000, 17, 8));
        tester.testRoundTrip(DECIMAL_TYPE_PRECISION_18, decimalSequence("-30000000000", "60000000", 1_000, 18, 8));
        tester.testRoundTrip(DECIMAL_TYPE_PRECISION_38,
                decimalSequence("-3000000000000000000", "6000000000000000", 1_000, 38, 16));
    }

    @Test
    public void testStringSequence() throws Exception {
        tester.testRoundTrip(VARCHAR,
                intsBetween(0, 31_234).stream().filter(i -> i % 19 == 0).map(Object::toString).collect(toList()));
    }

    @Test
    public void testEmptyStringSequence() throws Exception {
        tester.testRoundTrip(VARCHAR, nCopies(3_000, ""));
    }

    @Test
    public void testBinarySequence() throws Exception {
        tester.testRoundTrip(VARBINARY,
                intsBetween(0, 30_000).stream().filter(i -> i % 19 == 0).map(Object::toString)
                        .map(string -> string.getBytes(UTF_8)).map(SqlVarbinary::new).collect(toList()));
    }

    @Test
    public void testEmptyBinarySequence() throws Exception {
        // Binary serde can not serialize an empty binary sequence
        tester.testRoundTrip(VARBINARY, nCopies(3_000, new SqlVarbinary(new byte[0])), BINARY);
    }

    private static List<Double> doubleSequence(double start, double step, int items) {
        List<Double> values = new ArrayList<>();
        double nextValue = start;
        for (int i = 0; i < items; i++) {
            values.add(nextValue);
            nextValue += step;
        }
        return values;
    }

    private static ContiguousSet<Long> longsBetween(long lowerInclusive, long upperExclusive) {
        return ContiguousSet.create(Range.openClosed(lowerInclusive, upperExclusive), DiscreteDomain.longs());
    }

    private static ContiguousSet<Integer> intsBetween(int lowerInclusive, int upperExclusive) {
        return ContiguousSet.create(Range.openClosed(lowerInclusive, upperExclusive), DiscreteDomain.integers());
    }

    private static List<SqlDecimal> decimalSequence(String start, String step, int items, int precision,
            int scale) {
        BigInteger decimalStep = new BigInteger(step);

        List<SqlDecimal> values = new ArrayList<>();
        BigInteger nextValue = new BigInteger(start);
        for (int i = 0; i < items; i++) {
            values.add(new SqlDecimal(nextValue, precision, scale));
            nextValue = nextValue.add(decimalStep);
        }
        return values;
    }
}