blob: 663da60e685042002b2158cdb7754dd6fb663340 [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.file.header;
import org.apache.iotdb.tsfile.common.conf.TSFileConfig;
import org.apache.iotdb.tsfile.file.MetaMarker;
import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
import org.apache.iotdb.tsfile.read.reader.TsFileInput;
import org.apache.iotdb.tsfile.utils.ReadWriteForEncodingUtils;
import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
public class ChunkHeader {
/**
* 1 means this chunk has more than one page, so each page has its own page statistic 5 means this
* chunk has only one page, and this page has no page statistic
*/
private byte chunkType;
private String measurementID;
private int dataSize;
private TSDataType dataType;
private CompressionType compressionType;
private TSEncoding encodingType;
// the following fields do not need to be serialized.
private int numOfPages;
private int serializedSize;
public ChunkHeader(
String measurementID,
int dataSize,
TSDataType dataType,
CompressionType compressionType,
TSEncoding encoding,
int numOfPages) {
this(
numOfPages <= 1 ? MetaMarker.ONLY_ONE_PAGE_CHUNK_HEADER : MetaMarker.CHUNK_HEADER,
measurementID,
dataSize,
getSerializedSize(measurementID, dataSize),
dataType,
compressionType,
encoding);
this.numOfPages = numOfPages;
}
public ChunkHeader(
byte chunkType,
String measurementID,
int dataSize,
TSDataType dataType,
CompressionType compressionType,
TSEncoding encoding) {
this(
chunkType,
measurementID,
dataSize,
getSerializedSize(measurementID, dataSize),
dataType,
compressionType,
encoding);
}
public ChunkHeader(
byte chunkType,
String measurementID,
int dataSize,
int headerSize,
TSDataType dataType,
CompressionType compressionType,
TSEncoding encoding) {
this.chunkType = chunkType;
this.measurementID = measurementID;
this.dataSize = dataSize;
this.dataType = dataType;
this.compressionType = compressionType;
this.encodingType = encoding;
this.serializedSize = headerSize;
}
/** the exact serialized size of chunk header */
public static int getSerializedSize(String measurementID, int dataSize) {
int measurementIdLength = measurementID.getBytes(TSFileConfig.STRING_CHARSET).length;
return Byte.BYTES // chunkType
+ ReadWriteForEncodingUtils.varIntSize(measurementIdLength) // measurementID length
+ measurementIdLength // measurementID
+ ReadWriteForEncodingUtils.uVarIntSize(dataSize) // dataSize
+ TSDataType.getSerializedSize() // dataType
+ CompressionType.getSerializedSize() // compressionType
+ TSEncoding.getSerializedSize(); // encodingType
}
/**
* The estimated serialized size of chunk header. Only used when we don't know the actual dataSize
* attribute
*/
public static int getSerializedSize(String measurementID) {
int measurementIdLength = measurementID.getBytes(TSFileConfig.STRING_CHARSET).length;
return Byte.BYTES // chunkType
+ ReadWriteForEncodingUtils.varIntSize(measurementIdLength) // measurementID length
+ measurementIdLength // measurementID
+ Integer.BYTES
+ 1 // uVarInt dataSize
+ TSDataType.getSerializedSize() // dataType
+ CompressionType.getSerializedSize() // compressionType
+ TSEncoding.getSerializedSize(); // encodingType
}
/** deserialize from inputStream, the marker has already been read. */
public static ChunkHeader deserializeFrom(InputStream inputStream, byte chunkType)
throws IOException {
// read measurementID
String measurementID = ReadWriteIOUtils.readVarIntString(inputStream);
int dataSize = ReadWriteForEncodingUtils.readUnsignedVarInt(inputStream);
TSDataType dataType = ReadWriteIOUtils.readDataType(inputStream);
CompressionType type = ReadWriteIOUtils.readCompressionType(inputStream);
TSEncoding encoding = ReadWriteIOUtils.readEncoding(inputStream);
return new ChunkHeader(chunkType, measurementID, dataSize, dataType, type, encoding);
}
/**
* deserialize from TsFileInput, the marker has not been read.
*
* @param input TsFileInput
* @param offset offset
* @param chunkHeaderSize the estimated size of chunk's header
* @return CHUNK_HEADER object
* @throws IOException IOException
*/
public static ChunkHeader deserializeFrom(TsFileInput input, long offset, int chunkHeaderSize)
throws IOException {
// read chunk header from input to buffer
ByteBuffer buffer = ByteBuffer.allocate(chunkHeaderSize);
input.read(buffer, offset);
buffer.flip();
byte chunkType = buffer.get();
// read measurementID
String measurementID = ReadWriteIOUtils.readVarIntString(buffer);
int dataSize = ReadWriteForEncodingUtils.readUnsignedVarInt(buffer);
TSDataType dataType = ReadWriteIOUtils.readDataType(buffer);
CompressionType type = ReadWriteIOUtils.readCompressionType(buffer);
TSEncoding encoding = ReadWriteIOUtils.readEncoding(buffer);
chunkHeaderSize =
chunkHeaderSize - Integer.BYTES - 1 + ReadWriteForEncodingUtils.uVarIntSize(dataSize);
return new ChunkHeader(
chunkType, measurementID, dataSize, chunkHeaderSize, dataType, type, encoding);
}
public int getSerializedSize() {
return serializedSize;
}
public String getMeasurementID() {
return measurementID;
}
public int getDataSize() {
return dataSize;
}
public TSDataType getDataType() {
return dataType;
}
/**
* serialize to outputStream.
*
* @param outputStream outputStream
* @return length
* @throws IOException IOException
*/
public int serializeTo(OutputStream outputStream) throws IOException {
int length = 0;
length += ReadWriteIOUtils.write(chunkType, outputStream);
length += ReadWriteIOUtils.writeVar(measurementID, outputStream);
length += ReadWriteForEncodingUtils.writeUnsignedVarInt(dataSize, outputStream);
length += ReadWriteIOUtils.write(dataType, outputStream);
length += ReadWriteIOUtils.write(compressionType, outputStream);
length += ReadWriteIOUtils.write(encodingType, outputStream);
return length;
}
/**
* serialize to ByteBuffer.
*
* @param buffer ByteBuffer
* @return length
*/
public int serializeTo(ByteBuffer buffer) {
int length = 0;
length += ReadWriteIOUtils.write(chunkType, buffer);
length += ReadWriteIOUtils.writeVar(measurementID, buffer);
length += ReadWriteForEncodingUtils.writeUnsignedVarInt(dataSize, buffer);
length += ReadWriteIOUtils.write(dataType, buffer);
length += ReadWriteIOUtils.write(compressionType, buffer);
length += ReadWriteIOUtils.write(encodingType, buffer);
return length;
}
public int getNumOfPages() {
return numOfPages;
}
public CompressionType getCompressionType() {
return compressionType;
}
public TSEncoding getEncodingType() {
return encodingType;
}
@Override
public String toString() {
return "CHUNK_HEADER{"
+ "measurementID='"
+ measurementID
+ '\''
+ ", dataSize="
+ dataSize
+ ", dataType="
+ dataType
+ ", compressionType="
+ compressionType
+ ", encodingType="
+ encodingType
+ ", numOfPages="
+ numOfPages
+ ", serializedSize="
+ serializedSize
+ '}';
}
public void mergeChunkHeader(ChunkHeader chunkHeader) {
this.dataSize += chunkHeader.getDataSize();
this.numOfPages += chunkHeader.getNumOfPages();
}
public void setDataSize(int dataSize) {
this.dataSize = dataSize;
}
public byte getChunkType() {
return chunkType;
}
public void setChunkType(byte chunkType) {
this.chunkType = chunkType;
}
public void increasePageNums(int i) {
numOfPages += i;
}
}