/**
* Copyright (C) 2014-2016 LinkedIn Corp. (pinot-core@linkedin.com)
*
* Licensed 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 com.linkedin.pinot.core.realtime.converter;
import com.linkedin.pinot.common.data.StarTreeIndexSpec;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import com.linkedin.pinot.common.data.Schema;
import com.linkedin.pinot.common.data.TimeFieldSpec;
import com.linkedin.pinot.common.data.TimeGranularitySpec;
import com.linkedin.pinot.core.indexsegment.generator.SegmentGeneratorConfig;
import com.linkedin.pinot.core.indexsegment.generator.SegmentVersion;
import com.linkedin.pinot.core.realtime.converter.stats.RealtimeSegmentSegmentCreationDataSource;
import com.linkedin.pinot.core.realtime.impl.RealtimeSegmentImpl;
import com.linkedin.pinot.core.segment.creator.impl.SegmentIndexCreationDriverImpl;
public class RealtimeSegmentConverter {
private RealtimeSegmentImpl realtimeSegmentImpl;
private String outputPath;
private Schema dataSchema;
private String tableName;
private String segmentName;
private String sortedColumn;
private List<String> invertedIndexColumns;
private List<String> noDictionaryColumns;
private StarTreeIndexSpec starTreeIndexSpec;
public RealtimeSegmentConverter(RealtimeSegmentImpl realtimeSegment, String outputPath, Schema schema,
String tableName, String segmentName, String sortedColumn, List<String> invertedIndexColumns,
List<String> noDictionaryColumns, StarTreeIndexSpec starTreeIndexSpec) {
if (new File(outputPath).exists()) {
throw new IllegalAccessError("path already exists:" + outputPath);
}
TimeFieldSpec original = schema.getTimeFieldSpec();
// Use outgoing granularity for creating segment
TimeGranularitySpec outgoing = original.getOutgoingGranularitySpec();
TimeFieldSpec newTimeSpec = new TimeFieldSpec(outgoing);
Schema newSchema = new Schema();
for (String dimension : schema.getDimensionNames()) {
newSchema.addField(schema.getFieldSpecFor(dimension));
}
for (String metric : schema.getMetricNames()) {
newSchema.addField(schema.getFieldSpecFor(metric));
}
newSchema.addField(newTimeSpec);
this.realtimeSegmentImpl = realtimeSegment;
this.outputPath = outputPath;
this.invertedIndexColumns = new ArrayList<>(invertedIndexColumns);
if (sortedColumn != null && this.invertedIndexColumns.contains(sortedColumn)) {
this.invertedIndexColumns.remove(sortedColumn);
}
this.dataSchema = newSchema;
this.sortedColumn = sortedColumn;
this.tableName = tableName;
this.segmentName = segmentName;
this.noDictionaryColumns = noDictionaryColumns;
this.starTreeIndexSpec = starTreeIndexSpec;
}
public RealtimeSegmentConverter(RealtimeSegmentImpl realtimeSegment, String outputPath, Schema schema,
String tableName, String segmentName, String sortedColumn) {
this(realtimeSegment, outputPath, schema, tableName, segmentName, sortedColumn, new ArrayList<String>(),
new ArrayList<String>(), null/*StarTreeIndexSpec*/);
}
public void build(SegmentVersion segmentVersion) throws Exception {
// lets create a record reader
RealtimeSegmentRecordReader reader;
if (sortedColumn == null) {
reader = new RealtimeSegmentRecordReader(realtimeSegmentImpl, dataSchema);
} else {
reader = new RealtimeSegmentRecordReader(realtimeSegmentImpl, dataSchema, sortedColumn);
}
SegmentGeneratorConfig genConfig = new SegmentGeneratorConfig(dataSchema);
if (invertedIndexColumns != null && !invertedIndexColumns.isEmpty()) {
for (String column : invertedIndexColumns) {
genConfig.createInvertedIndexForColumn(column);
}
}
if (noDictionaryColumns != null) {
genConfig.setRawIndexCreationColumns(noDictionaryColumns);
}
// Presence of the spec enables star tree generation.
if (starTreeIndexSpec != null) {
genConfig.setEnableStarTreeIndex(true);
genConfig.setStarTreeIndexSpec(starTreeIndexSpec);
}
genConfig.setTimeColumnName(dataSchema.getTimeFieldSpec().getOutgoingTimeColumnName());
genConfig.setSegmentTimeUnit(dataSchema.getTimeFieldSpec().getOutgoingGranularitySpec().getTimeType());
genConfig.setSegmentVersion(segmentVersion);
genConfig.setTableName(tableName);
genConfig.setOutDir(outputPath);
genConfig.setSegmentName(segmentName);
genConfig.setSegmentPartitionConfig(realtimeSegmentImpl.getSegmentPartitionConfig());
final SegmentIndexCreationDriverImpl driver = new SegmentIndexCreationDriverImpl();
driver.init(genConfig, new RealtimeSegmentSegmentCreationDataSource(realtimeSegmentImpl, reader, dataSchema));
driver.build();
}
}