blob: 168bbf01419baf87bc38aaed8cdb2b3d53e38263 [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.datastore.block;
import java.io.IOException;
import java.io.Serializable;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Comparator;
import org.apache.carbondata.core.constants.CarbonCommonConstants;
import org.apache.carbondata.core.datastore.impl.FileFactory;
import org.apache.carbondata.core.index.Segment;
import org.apache.carbondata.core.indexstore.BlockletDetailInfo;
import org.apache.carbondata.core.metadata.ColumnarFormatVersion;
import org.apache.carbondata.core.metadata.blocklet.DataFileFooter;
import org.apache.carbondata.core.util.ByteUtil;
import org.apache.carbondata.core.util.path.CarbonTablePath;
import org.apache.carbondata.core.util.path.CarbonTablePath.DataFileUtil;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
/**
* class will be used to pass the block detail detail will be passed form driver
* to all the executor to load the b+ tree
*/
public class TableBlockInfo implements Distributable, Serializable {
/**
* serialization id
*/
private static final long serialVersionUID = -6502868998599821172L;
/**
* full qualified file path of the block
*/
private String filePath;
/**
* file size of the block
*/
private long fileSize;
/**
* block offset in the file
*/
private long blockOffset;
/**
* length of the block
*/
private long blockLength;
/**
* id of the segment this will be used to sort the blocks
*/
private Segment segment;
private String[] locations;
private ColumnarFormatVersion version;
/**
* delete delta files path for this block
*/
private String[] deletedDeltaFilePath;
private BlockletDetailInfo detailInfo;
private String indexWriterPath;
private transient DataFileFooter dataFileFooter;
/**
* comparator to sort by block size in descending order.
* Since each line is not exactly the same, the size of a InputSplit may differs,
* so we allow some deviation for these splits.
*/
public static final Comparator<Distributable> DATA_SIZE_DESC_COMPARATOR =
new Comparator<Distributable>() {
@Override
public int compare(Distributable o1, Distributable o2) {
long diff =
((TableBlockInfo) o1).getBlockLength() - ((TableBlockInfo) o2).getBlockLength();
return diff < 0 ? 1 : (diff == 0 ? 0 : -1);
}
};
public TableBlockInfo(String filePath, long blockOffset, String segmentId,
String[] locations, long blockLength, ColumnarFormatVersion version,
String[] deletedDeltaFilePath) {
this.filePath = FileFactory.getUpdatedFilePath(filePath);
this.blockOffset = blockOffset;
this.segment = Segment.toSegment(segmentId);
this.locations = locations;
this.blockLength = blockLength;
this.version = version;
this.deletedDeltaFilePath = deletedDeltaFilePath;
}
public TableBlockInfo() {
}
/**
* Create copy of TableBlockInfo object
*/
public TableBlockInfo copy() {
TableBlockInfo info = new TableBlockInfo();
info.filePath = filePath;
info.blockOffset = blockOffset;
info.blockLength = blockLength;
info.segment = segment;
info.locations = locations;
info.version = version;
info.deletedDeltaFilePath = deletedDeltaFilePath;
info.detailInfo = detailInfo.copy();
info.indexWriterPath = indexWriterPath;
return info;
}
/**
* @return the filePath
*/
public String getFilePath() {
return filePath;
}
/**
* @return the blockOffset
*/
public long getBlockOffset() {
return blockOffset;
}
public void setBlockOffset(long blockOffset) {
this.blockOffset = blockOffset;
}
/**
* @return the segmentId
*/
public String getSegmentId() {
if (segment == null) {
return null;
} else {
return segment.getSegmentNo();
}
}
public Segment getSegment() {
return segment;
}
/**
* @return the blockLength
*/
public long getBlockLength() {
if (blockLength == 0) {
Path path = new Path(filePath);
try {
FileSystem fs = path.getFileSystem(FileFactory.getConfiguration());
blockLength = fs.listStatus(path)[0].getLen();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return blockLength;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof TableBlockInfo)) {
return false;
}
TableBlockInfo other = (TableBlockInfo) obj;
if (!segment.equals(other.segment)) {
return false;
}
if (blockOffset != other.blockOffset) {
return false;
}
if (blockLength != other.blockLength) {
return false;
}
if (null == filePath || null == other.filePath) {
return false;
}
if (!new Path(filePath).equals(new Path(other.filePath))) {
return false;
}
return true;
}
/**
* Below method will used to compare to TableBlockInfos object this will
* used for sorting Comparison logic is: 1. compare segment id if segment id
* is same 2. compare task id if task id is same 3. compare offsets of the
* block
*/
@Override
public int compareTo(Distributable other) {
int compareResult = 0;
// get the segment id
// convert segment ID to double.
double seg1 = Double.parseDouble(segment.getSegmentNo());
double seg2 = Double.parseDouble(((TableBlockInfo) other).segment.getSegmentNo());
if (seg1 - seg2 < 0) {
return -1;
}
if (seg1 - seg2 > 0) {
return 1;
}
// Comparing the time task id of the file to other
// if both the task id of the file is same then we need to compare the
// offset of
// the file
if (CarbonTablePath.isCarbonDataFile(filePath)) {
int compare = ByteUtil.compare(DataFileUtil.getTaskNo(filePath)
.getBytes(Charset.forName(CarbonCommonConstants.DEFAULT_CHARSET)),
DataFileUtil.getTaskNo(((TableBlockInfo) other).filePath)
.getBytes(Charset.forName(CarbonCommonConstants.DEFAULT_CHARSET)));
if (compare != 0) {
return compare;
}
// compare the part no of both block info
int firstPartNo = Integer.parseInt(DataFileUtil.getPartNo(filePath));
int SecondPartNo =
Integer.parseInt(DataFileUtil.getPartNo(((TableBlockInfo) other).filePath));
compareResult = firstPartNo - SecondPartNo;
} else {
compareResult = filePath.compareTo(((TableBlockInfo) other).getFilePath());
}
if (compareResult != 0) {
return compareResult;
}
//compare result is not 0 then return
// if part no is also same then compare the offset and length of the block
if (blockOffset + blockLength
< ((TableBlockInfo) other).blockOffset + ((TableBlockInfo) other).blockLength) {
return -1;
} else if (blockOffset + blockLength
> ((TableBlockInfo) other).blockOffset + ((TableBlockInfo) other).blockLength) {
return 1;
}
return 0;
}
@Override
public int hashCode() {
int result = filePath.hashCode();
result = 31 * result + (int) (blockOffset ^ (blockOffset >>> 32));
result = 31 * result + (int) (blockLength ^ (blockLength >>> 32));
result = 31 * result + segment.hashCode();
result = 31 * result;
return result;
}
@Override
public String[] getLocations() {
return locations;
}
public ColumnarFormatVersion getVersion() {
return version;
}
public void setVersion(ColumnarFormatVersion version) {
this.version = version;
}
public String[] getDeletedDeltaFilePath() {
return deletedDeltaFilePath;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
public long getFileSize() {
return fileSize;
}
public void setFileSize(long fileSize) {
this.fileSize = fileSize;
}
public BlockletDetailInfo getDetailInfo() {
return detailInfo;
}
public void setDetailInfo(BlockletDetailInfo detailInfo) {
this.detailInfo = detailInfo;
}
public String getIndexWriterPath() {
return indexWriterPath;
}
public void setIndexWriterPath(String indexWriterPath) {
this.indexWriterPath = indexWriterPath;
}
public DataFileFooter getDataFileFooter() {
return dataFileFooter;
}
public void setDataFileFooter(DataFileFooter dataFileFooter) {
this.dataFileFooter = dataFileFooter;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("TableBlockInfo{");
sb.append("filePath='").append(filePath).append('\'');
sb.append(", blockOffset=").append(blockOffset);
sb.append(", blockLength=").append(blockLength);
sb.append(", segment='").append(segment.toString()).append('\'');
sb.append(", locations=").append(Arrays.toString(locations));
sb.append('}');
return sb.toString();
}
}