blob: 8c40ef9c12b9f1739a07eda510fb3da13ca7f041 [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.carbondata.core.indexstore;
import java.io.ByteArrayInputStream;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.DataOutput;
import java.io.IOException;
import java.io.Serializable;
import java.util.List;
import org.apache.carbondata.common.logging.LogServiceFactory;
import org.apache.carbondata.core.metadata.blocklet.BlockletInfo;
import org.apache.carbondata.core.metadata.schema.table.column.ColumnSchema;
import org.apache.carbondata.core.util.BlockletIndexUtil;
import org.apache.hadoop.io.Writable;
import org.apache.log4j.Logger;
/**
* Blocklet detail information to be sent to each executor
*/
public class BlockletDetailInfo implements Serializable, Writable {
/**
* LOGGER
*/
private static final Logger LOGGER =
LogServiceFactory.getLogService(BlockletDetailInfo.class.getName());
private static final long serialVersionUID = 7957493757421513808L;
private int rowCount;
private short pagesCount;
private short versionNumber;
// default blockletId should be -1,which means consider all the blocklets in block
private short blockletId = -1;
private long schemaUpdatedTimeStamp;
private BlockletInfo blockletInfo;
private byte[] blockletInfoBinary;
private long blockFooterOffset;
private List<ColumnSchema> columnSchemas;
private byte[] columnSchemaBinary;
private long blockSize;
/**
* flag to check whether to serialize min max values. The flag will be set to true in case
* 1. When CACHE_LEVEL = BLOCKLET and filter column min/max in not cached in the driver using the
* property COLUMN_META_CACHE
* 2. for CACHE_LEVEL = BLOCK, it will always be true which is also the default value
*/
private boolean useMinMaxForPruning = true;
public int getRowCount() {
return rowCount;
}
public void setRowCount(int rowCount) {
this.rowCount = rowCount;
}
public int getPagesCount() {
return pagesCount;
}
public void setPagesCount(short pagesCount) {
this.pagesCount = pagesCount;
}
public short getVersionNumber() {
return versionNumber;
}
public void setVersionNumber(short versionNumber) {
this.versionNumber = versionNumber;
}
public BlockletInfo getBlockletInfo() {
if (null == blockletInfo) {
try {
synchronized (this) {
if (null == blockletInfo) {
setBlockletInfoFromBinary();
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return blockletInfo;
}
public void setBlockletInfo(BlockletInfo blockletInfo) {
this.blockletInfo = blockletInfo;
}
private void setBlockletInfoFromBinary() throws IOException {
if (null == this.blockletInfo && null != blockletInfoBinary && blockletInfoBinary.length > 0) {
blockletInfo = new BlockletInfo();
ByteArrayInputStream stream = new ByteArrayInputStream(blockletInfoBinary);
DataInputStream inputStream = new DataInputStream(stream);
try {
blockletInfo.readFields(inputStream);
} catch (IOException e) {
LOGGER.error("Problem in reading blocklet info", e);
throw new IOException("Problem in reading blocklet info." + e.getMessage(), e);
} finally {
try {
inputStream.close();
} catch (IOException e) {
LOGGER.error("Problem in closing input stream of reading blocklet info.", e);
}
}
}
}
public long getSchemaUpdatedTimeStamp() {
return schemaUpdatedTimeStamp;
}
public void setSchemaUpdatedTimeStamp(long schemaUpdatedTimeStamp) {
this.schemaUpdatedTimeStamp = schemaUpdatedTimeStamp;
}
public long getBlockSize() {
return blockSize;
}
public void setBlockSize(long blockSize) {
this.blockSize = blockSize;
}
@Override
public void write(DataOutput out) throws IOException {
out.writeInt(rowCount);
out.writeShort(pagesCount);
out.writeShort(versionNumber);
out.writeShort(blockletId);
out.writeLong(schemaUpdatedTimeStamp);
out.writeBoolean(blockletInfo != null);
if (blockletInfo != null) {
blockletInfo.write(out);
}
out.writeLong(blockFooterOffset);
// convert column schema list to binary format for serializing
convertColumnSchemaToBinary();
if (null != columnSchemaBinary) {
out.writeInt(columnSchemaBinary.length);
out.write(columnSchemaBinary);
} else {
// write -1 if columnSchemaBinary is null so that at the time of reading it can distinguish
// whether schema is written or not
out.writeInt(-1);
}
out.writeInt(blockletInfoBinary.length);
out.write(blockletInfoBinary);
out.writeLong(blockSize);
out.writeBoolean(useMinMaxForPruning);
}
@Override
public void readFields(DataInput in) throws IOException {
rowCount = in.readInt();
pagesCount = in.readShort();
versionNumber = in.readShort();
blockletId = in.readShort();
schemaUpdatedTimeStamp = in.readLong();
if (in.readBoolean()) {
blockletInfo = new BlockletInfo();
blockletInfo.readFields(in);
}
blockFooterOffset = in.readLong();
int bytesSize = in.readInt();
// if byteSize is -1 that means schema binary is not written
if (bytesSize != -1) {
byte[] schemaArray = new byte[bytesSize];
in.readFully(schemaArray);
readColumnSchema(schemaArray);
}
int byteSize = in.readInt();
blockletInfoBinary = new byte[byteSize];
in.readFully(blockletInfoBinary);
setBlockletInfoFromBinary();
blockSize = in.readLong();
useMinMaxForPruning = in.readBoolean();
}
/**
* Read column schema from binary
* @param schemaArray
* @throws IOException
*/
public void readColumnSchema(byte[] schemaArray) throws IOException {
if (null != schemaArray) {
columnSchemas = BlockletIndexUtil.readColumnSchema(schemaArray);
}
}
private void convertColumnSchemaToBinary() throws IOException {
if (null != columnSchemas) {
columnSchemaBinary = BlockletIndexUtil.convertSchemaToBinary(columnSchemas);
}
}
/**
* Create copy of BlockletDetailInfo
*/
public BlockletDetailInfo copy() {
BlockletDetailInfo detailInfo = new BlockletDetailInfo();
detailInfo.rowCount = rowCount;
detailInfo.pagesCount = pagesCount;
detailInfo.versionNumber = versionNumber;
detailInfo.blockletId = blockletId;
detailInfo.schemaUpdatedTimeStamp = schemaUpdatedTimeStamp;
detailInfo.blockletInfo = blockletInfo;
detailInfo.blockletInfoBinary = blockletInfoBinary;
detailInfo.blockFooterOffset = blockFooterOffset;
detailInfo.columnSchemas = columnSchemas;
detailInfo.columnSchemaBinary = columnSchemaBinary;
detailInfo.blockSize = blockSize;
detailInfo.useMinMaxForPruning = useMinMaxForPruning;
return detailInfo;
}
public Short getBlockletId() {
return blockletId;
}
public void setBlockletId(Short blockletId) {
this.blockletId = blockletId;
}
public long getBlockFooterOffset() {
return blockFooterOffset;
}
public void setBlockFooterOffset(long blockFooterOffset) {
this.blockFooterOffset = blockFooterOffset;
}
public List<ColumnSchema> getColumnSchemas() throws IOException {
if (columnSchemas == null && columnSchemaBinary != null) {
readColumnSchema(columnSchemaBinary);
}
return columnSchemas;
}
public byte[] getColumnSchemaBinary() {
return columnSchemaBinary;
}
public void setBlockletInfoBinary(byte[] blockletInfoBinary) {
this.blockletInfoBinary = blockletInfoBinary;
}
public void setColumnSchemas(List<ColumnSchema> columnSchemas) {
this.columnSchemas = columnSchemas;
}
public boolean isUseMinMaxForPruning() {
return useMinMaxForPruning;
}
public void setUseMinMaxForPruning(boolean useMinMaxForPruning) {
this.useMinMaxForPruning = useMinMaxForPruning;
}
}