blob: 200aeb2f5bd79566d942313a943f2c525c3ea443 [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.iotdb.tsfile.read.reader;
import org.apache.iotdb.tsfile.common.conf.TSFileConfig;
import org.apache.iotdb.tsfile.encoding.decoder.Decoder;
import org.apache.iotdb.tsfile.encoding.decoder.DeltaBinaryDecoder;
import org.apache.iotdb.tsfile.encoding.decoder.DoublePrecisionDecoderV1;
import org.apache.iotdb.tsfile.encoding.decoder.IntRleDecoder;
import org.apache.iotdb.tsfile.encoding.decoder.LongRleDecoder;
import org.apache.iotdb.tsfile.encoding.decoder.PlainDecoder;
import org.apache.iotdb.tsfile.encoding.decoder.SinglePrecisionDecoderV1;
import org.apache.iotdb.tsfile.encoding.encoder.DeltaBinaryEncoder;
import org.apache.iotdb.tsfile.encoding.encoder.DoublePrecisionEncoderV1;
import org.apache.iotdb.tsfile.encoding.encoder.Encoder;
import org.apache.iotdb.tsfile.encoding.encoder.IntRleEncoder;
import org.apache.iotdb.tsfile.encoding.encoder.LongRleEncoder;
import org.apache.iotdb.tsfile.encoding.encoder.PlainEncoder;
import org.apache.iotdb.tsfile.encoding.encoder.SinglePrecisionEncoderV1;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.read.common.BatchData;
import org.apache.iotdb.tsfile.read.common.TimeRange;
import org.apache.iotdb.tsfile.read.reader.page.PageReader;
import org.apache.iotdb.tsfile.utils.Binary;
import org.apache.iotdb.tsfile.write.page.PageWriter;
import org.junit.Assert;
import org.junit.Test;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
public class PageReaderTest {
private static final int POINTS_COUNT_IN_ONE_PAGE = 1000000;
@Test
public void testLong() {
LoopWriteReadTest test =
new LoopWriteReadTest(
"Test INT64",
new LongRleEncoder(),
new LongRleDecoder(),
TSDataType.INT64,
POINTS_COUNT_IN_ONE_PAGE) {
@Override
public Object generateValueByIndex(int i) {
return Long.MAX_VALUE - i;
}
};
test.test(TSDataType.INT64);
}
@Test
public void testBoolean() {
LoopWriteReadTest test =
new LoopWriteReadTest(
"Test Boolean",
new IntRleEncoder(),
new IntRleDecoder(),
TSDataType.BOOLEAN,
POINTS_COUNT_IN_ONE_PAGE) {
@Override
public Object generateValueByIndex(int i) {
return i % 3 == 0;
}
};
test.test(TSDataType.BOOLEAN);
}
@Test
public void testInt() {
LoopWriteReadTest test =
new LoopWriteReadTest(
"Test INT32",
new IntRleEncoder(),
new IntRleDecoder(),
TSDataType.INT32,
POINTS_COUNT_IN_ONE_PAGE) {
@Override
public Object generateValueByIndex(int i) {
return i;
}
};
test.test(TSDataType.INT32);
}
@Test
public void testFloat() {
LoopWriteReadTest test =
new LoopWriteReadTest(
"Test FLOAT",
new SinglePrecisionEncoderV1(),
new SinglePrecisionDecoderV1(),
TSDataType.FLOAT,
POINTS_COUNT_IN_ONE_PAGE) {
@Override
public Object generateValueByIndex(int i) {
return (float) i / 10 - (float) i / 100;
}
};
test.test(TSDataType.FLOAT);
LoopWriteReadTest test2 =
new LoopWriteReadTest(
"Test FLOAT",
new SinglePrecisionEncoderV1(),
new SinglePrecisionDecoderV1(),
TSDataType.FLOAT,
POINTS_COUNT_IN_ONE_PAGE) {
@Override
public Object generateValueByIndex(int i) {
return (float) i / 100 - (float) i / 10;
}
};
test2.test(TSDataType.FLOAT);
}
@Test
public void testDouble() {
LoopWriteReadTest test =
new LoopWriteReadTest(
"Test Double",
new DoublePrecisionEncoderV1(),
new DoublePrecisionDecoderV1(),
TSDataType.DOUBLE,
POINTS_COUNT_IN_ONE_PAGE) {
@Override
public Object generateValueByIndex(int i) {
return (double) i / 10 - (double) i / 100;
}
};
test.test(TSDataType.DOUBLE);
LoopWriteReadTest test2 =
new LoopWriteReadTest(
"Test Double",
new DoublePrecisionEncoderV1(),
new DoublePrecisionDecoderV1(),
TSDataType.DOUBLE,
POINTS_COUNT_IN_ONE_PAGE) {
@Override
public Object generateValueByIndex(int i) {
return (double) i / 1000 - (double) i / 100;
}
};
test2.test(TSDataType.DOUBLE);
}
@Test
public void testBinary() {
LoopWriteReadTest test =
new LoopWriteReadTest(
"Test Double",
new PlainEncoder(TSDataType.TEXT, 1000),
new PlainDecoder(),
TSDataType.TEXT,
POINTS_COUNT_IN_ONE_PAGE) {
@Override
public Object generateValueByIndex(int i) {
return new Binary("TEST TEXT" + i, TSFileConfig.STRING_CHARSET);
}
};
test.test(TSDataType.TEXT);
}
private abstract static class LoopWriteReadTest {
private Encoder encoder;
private Decoder decoder;
private TSDataType dataType;
private PageWriter pageWriter;
private String name;
private int count;
public LoopWriteReadTest(
String name, Encoder encoder, Decoder decoder, TSDataType dataType, int count) {
this.name = name;
this.encoder = encoder;
this.decoder = decoder;
this.dataType = dataType;
this.count = count;
}
public void test(TSDataType dataType) {
try {
pageWriter = new PageWriter();
pageWriter.setTimeEncoder(new DeltaBinaryEncoder.LongDeltaEncoder());
pageWriter.setValueEncoder(this.encoder);
pageWriter.initStatistics(dataType);
writeData();
ByteBuffer page = ByteBuffer.wrap(pageWriter.getUncompressedBytes().array());
PageReader pageReader =
new PageReader(page, dataType, decoder, new DeltaBinaryDecoder.LongDeltaDecoder());
int index = 0;
BatchData data = pageReader.getAllSatisfiedPageData();
Assert.assertNotNull(data);
while (data.hasCurrent()) {
Assert.assertEquals(Long.valueOf(index), (Long) data.currentTime());
Assert.assertEquals(generateValueByIndex(index), data.currentValue());
data.next();
index++;
}
Assert.assertEquals(count, index);
} catch (IOException e) {
e.printStackTrace();
Assert.fail("Fail when executing test: [" + name + "]");
}
}
public void testDelete(TSDataType dataType) {
try {
pageWriter = new PageWriter();
pageWriter.setTimeEncoder(new DeltaBinaryEncoder.LongDeltaEncoder());
pageWriter.setValueEncoder(this.encoder);
pageWriter.initStatistics(dataType);
writeData();
ByteBuffer page = ByteBuffer.wrap(pageWriter.getUncompressedBytes().array());
PageReader pageReader =
new PageReader(page, dataType, decoder, new DeltaBinaryDecoder.LongDeltaDecoder());
int index = 0;
List<TimeRange> deleteIntervals = new ArrayList<>();
deleteIntervals.add(new TimeRange(5, 10));
deleteIntervals.add(new TimeRange(20, 30));
deleteIntervals.add(new TimeRange(50, 70));
pageReader.setDeleteIntervalList(deleteIntervals);
BatchData data = pageReader.getAllSatisfiedPageData();
Assert.assertNotNull(data);
for (TimeRange range : pageReader.getDeleteIntervalList()) {
while (data.hasCurrent()) {
Assert.assertEquals(Long.valueOf(index), (Long) data.currentTime());
Assert.assertEquals(generateValueByIndex(index), data.currentValue());
data.next();
index++;
if (index == range.getMin()) {
index = (int) (range.getMax() + 1);
break;
}
}
}
} catch (IOException e) {
e.printStackTrace();
Assert.fail("Fail when executing test: [" + name + "]");
}
}
private void writeData() {
for (int i = 0; i < count; i++) {
switch (dataType) {
case BOOLEAN:
pageWriter.write(i, (Boolean) generateValueByIndex(i));
break;
case INT32:
pageWriter.write(i, (Integer) generateValueByIndex(i));
break;
case INT64:
pageWriter.write(i, (Long) generateValueByIndex(i));
break;
case FLOAT:
pageWriter.write(i, (Float) generateValueByIndex(i));
break;
case DOUBLE:
pageWriter.write(i, (Double) generateValueByIndex(i));
break;
case TEXT:
pageWriter.write(i, (Binary) generateValueByIndex(i));
break;
}
}
}
public abstract Object generateValueByIndex(int i);
}
@Test
public void testPageDelete() {
LoopWriteReadTest test =
new LoopWriteReadTest(
"Test INT64", new LongRleEncoder(), new LongRleDecoder(), TSDataType.INT64, 100) {
@Override
public Object generateValueByIndex(int i) {
return Long.MAX_VALUE - i;
}
};
test.testDelete(TSDataType.INT64);
}
}