| /* |
| * 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; |
| } |
| } |