/** * 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.trevni; import java.io.ByteArrayOutputStream; import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.Collection; import java.util.Arrays; import java.util.Iterator; import java.util.Map; import java.util.HashMap; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; @RunWith(value = Parameterized.class) public class TestColumnFile { private static final File FILE = new File("target", "test.trv"); private static final int COUNT = 1024*64; private String codec; private String checksum; public TestColumnFile(String codec, String checksum) { this.codec = codec; this.checksum = checksum; } @Parameters public static Collection<Object[]> codecs() { Object[][] data = new Object[][] {{"null", "null"}, {"snappy", "crc32"}, {"deflate", "crc32"}}; return Arrays.asList(data); } private ColumnFileMetaData createFileMeta() { return new ColumnFileMetaData() .setCodec(codec) .setChecksum(checksum); } @Test public void testEmptyFile() throws Exception { FILE.delete(); ColumnFileWriter out = new ColumnFileWriter(createFileMeta()); out.writeTo(FILE); ColumnFileReader in = new ColumnFileReader(FILE); Assert.assertEquals(0, in.getRowCount()); Assert.assertEquals(0, in.getColumnCount()); in.close(); } @Test public void testEmptyColumn() throws Exception { FILE.delete(); ColumnFileWriter out = new ColumnFileWriter(createFileMeta(), new ColumnMetaData("test", ValueType.INT)); out.writeTo(FILE); ColumnFileReader in = new ColumnFileReader(FILE); Assert.assertEquals(0, in.getRowCount()); Assert.assertEquals(1, in.getColumnCount()); ColumnValues<Integer> values = in.getValues("test"); for (int i : values) throw new Exception("no value should be found"); in.close(); } @Test public void testInts() throws Exception { FILE.delete(); ColumnFileWriter out = new ColumnFileWriter(createFileMeta(), new ColumnMetaData("test", ValueType.INT)); Random random = TestUtil.createRandom(); for (int i = 0; i < COUNT; i++) out.writeRow(TestUtil.randomLength(random)); out.writeTo(FILE); random = TestUtil.createRandom(); ColumnFileReader in = new ColumnFileReader(FILE); Assert.assertEquals(COUNT, in.getRowCount()); Assert.assertEquals(1, in.getColumnCount()); Iterator<Integer> i = in.getValues("test"); int count = 0; while (i.hasNext()) { Assert.assertEquals(TestUtil.randomLength(random), (int)i.next()); count++; } Assert.assertEquals(COUNT, count); } @Test public void testLongs() throws Exception { FILE.delete(); ColumnFileWriter out = new ColumnFileWriter(createFileMeta(), new ColumnMetaData("test", ValueType.LONG)); Random random = TestUtil.createRandom(); for (int i = 0; i < COUNT; i++) out.writeRow(random.nextLong()); out.writeTo(FILE); random = TestUtil.createRandom(); ColumnFileReader in = new ColumnFileReader(FILE); Assert.assertEquals(COUNT, in.getRowCount()); Assert.assertEquals(1, in.getColumnCount()); Iterator<Long> i = in.getValues("test"); int count = 0; while (i.hasNext()) { Assert.assertEquals(random.nextLong(), (long)i.next()); count++; } Assert.assertEquals(COUNT, count); } @Test public void testStrings() throws Exception { FILE.delete(); ColumnFileWriter out = new ColumnFileWriter(createFileMeta(), new ColumnMetaData("test", ValueType.STRING)); Random random = TestUtil.createRandom(); for (int i = 0; i < COUNT; i++) out.writeRow(TestUtil.randomString(random)); out.writeTo(FILE); random = TestUtil.createRandom(); ColumnFileReader in = new ColumnFileReader(FILE); Assert.assertEquals(COUNT, in.getRowCount()); Assert.assertEquals(1, in.getColumnCount()); Iterator<String> i = in.getValues("test"); int count = 0; while (i.hasNext()) { Assert.assertEquals(TestUtil.randomString(random), i.next()); count++; } Assert.assertEquals(COUNT, count); } @Test public void testTwoColumn() throws Exception { FILE.delete(); ColumnFileWriter out = new ColumnFileWriter(createFileMeta(), new ColumnMetaData("a", ValueType.FIXED32), new ColumnMetaData("b", ValueType.STRING)); Random random = TestUtil.createRandom(); for (int i = 0; i < COUNT; i++) out.writeRow(random.nextInt(), TestUtil.randomString(random)); out.writeTo(FILE); random = TestUtil.createRandom(); ColumnFileReader in = new ColumnFileReader(FILE); Assert.assertEquals(COUNT, in.getRowCount()); Assert.assertEquals(2, in.getColumnCount()); Iterator<String> i = in.getValues("a"); Iterator<String> j = in.getValues("b"); int count = 0; while (i.hasNext() && j.hasNext()) { Assert.assertEquals(random.nextInt(), i.next()); Assert.assertEquals(TestUtil.randomString(random), j.next()); count++; } Assert.assertEquals(COUNT, count); } @Test public void testSeekLongs() throws Exception { FILE.delete(); ColumnFileWriter out = new ColumnFileWriter(createFileMeta(), new ColumnMetaData("test", ValueType.LONG)); Random random = TestUtil.createRandom(); int seekCount = COUNT/1024; int[] seekRows = new int[seekCount]; Map<Integer,Integer> seekRowMap = new HashMap<Integer,Integer>(seekCount); while (seekRowMap.size() < seekCount) { int row = random.nextInt(COUNT); if (!seekRowMap.containsKey(row)) { seekRows[seekRowMap.size()] = row; seekRowMap.put(row, seekRowMap.size()); } } Long[] seekValues = new Long[seekCount]; for (int i = 0; i < COUNT; i++) { long l = random.nextLong(); out.writeRow(l); if (seekRowMap.containsKey(i)) seekValues[seekRowMap.get(i)] = l; } out.writeTo(FILE); ColumnFileReader in = new ColumnFileReader(FILE); ColumnValues<Long> v = in.getValues("test"); for (int i = 0; i < seekCount; i++) { v.seek(seekRows[i]); Assert.assertEquals(seekValues[i], v.next()); } } @Test public void testSeekStrings() throws Exception { FILE.delete(); ColumnFileWriter out = new ColumnFileWriter(createFileMeta(), new ColumnMetaData("test", ValueType.STRING) .hasIndexValues(true)); Random random = TestUtil.createRandom(); int seekCount = COUNT/1024; Map<Integer,Integer> seekRowMap = new HashMap<Integer,Integer>(seekCount); while (seekRowMap.size() < seekCount) { int row = random.nextInt(COUNT); if (!seekRowMap.containsKey(row)) seekRowMap.put(row, seekRowMap.size()); } String[] values = new String[COUNT]; for (int i = 0; i < COUNT; i++) values[i] = TestUtil.randomString(random); Arrays.sort(values); String[] seekValues = new String[seekCount]; for (int i = 0; i < COUNT; i++) { out.writeRow(values[i]); if (seekRowMap.containsKey(i)) seekValues[seekRowMap.get(i)] = values[i]; } out.writeTo(FILE); ColumnFileReader in = new ColumnFileReader(FILE); ColumnValues<String> v = in.getValues("test"); for (int i = 0; i < seekCount; i++) { v.seek(seekValues[i]); Assert.assertEquals(seekValues[i], v.next()); } } }