blob: af02cdf89868f2eee804c2f92bda99d3cbe40aa6 [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.kylin.query.enumerator;
import java.util.Iterator;
import java.util.List;
import org.apache.calcite.linq4j.Enumerator;
import org.apache.kylin.common.annotation.Clarification;
import org.apache.kylin.common.util.Dictionary;
import org.apache.kylin.cube.CubeInstance;
import org.apache.kylin.metadata.model.TblColRef;
import org.apache.kylin.metadata.realization.IRealization;
import org.apache.kylin.metadata.tuple.Tuple;
import org.apache.kylin.query.relnode.OLAPContext;
import org.apache.kylin.storage.hybrid.HybridInstance;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
@Clarification(deprecated = true, msg = "Only for HBase storage")
public class DictionaryEnumerator implements Enumerator<Object[]> {
private final static Logger logger = LoggerFactory.getLogger(DictionaryEnumerator.class);
private List<Dictionary<String>> dictList;
private final Object[] current;
private final TblColRef dictCol;
private final int dictColIdx;
private Iterator<String> currentDict;
private Iterator<Dictionary<String>> iterator;
public DictionaryEnumerator(OLAPContext olapContext) {
Preconditions.checkArgument(olapContext.allColumns.size() == 1, "The query should only relate to one column");
dictCol = olapContext.allColumns.iterator().next();
Preconditions.checkArgument(ifColumnHaveDictionary(dictCol, olapContext.realization, false),
"The column " + dictCol + " should be encoded as dictionary for " + olapContext.realization);
dictList = getAllDictionaries(dictCol, olapContext.realization);
current = new Object[olapContext.returnTupleInfo.size()];
dictColIdx = olapContext.returnTupleInfo.getColumnIndex(dictCol);
reset();
logger.info("Will use DictionaryEnumerator to answer query which is only related to column " + dictCol);
}
public static boolean ifDictionaryEnumeratorEligible(OLAPContext olapContext) {
if (olapContext.allColumns.size() != 1) {
return false;
}
TblColRef dictCol = olapContext.allColumns.iterator().next();
if (!ifColumnHaveDictionary(dictCol, olapContext.realization, true)) {
return false;
}
return true;
}
private static boolean ifColumnHaveDictionary(TblColRef col, IRealization realization, boolean enableCheck) {
if (realization instanceof CubeInstance) {
final CubeInstance cube = (CubeInstance) realization;
boolean ifEnabled = !enableCheck || cube.getConfig().isDictionaryEnumeratorEnabled();
return ifEnabled && cube.getDescriptor().getAllDimsHaveDictionary().contains(col);
} else if (realization instanceof HybridInstance) {
final HybridInstance hybridInstance = (HybridInstance) realization;
for (IRealization entry : hybridInstance.getRealizations()) {
if (!ifColumnHaveDictionary(col, entry, enableCheck)) {
return false;
}
}
return true;
}
return false;
}
public static List<Dictionary<String>> getAllDictionaries(TblColRef col, IRealization realization) {
// Set<Dictionary<String>> result = Sets.newHashSet();
// if (realization instanceof CubeInstance) {
// final CubeInstance cube = (CubeInstance) realization;
// for (CubeSegment segment : cube.getSegments(SegmentStatusEnum.READY)) {
// result.add(segment.getDictionary(col));
// }
// } else if (realization instanceof HybridInstance) {
// final HybridInstance hybridInstance = (HybridInstance) realization;
// for (IRealization entry : hybridInstance.getRealizations()) {
// result.addAll(getAllDictionaries(col, entry));
// }
// } else {
// throw new IllegalStateException("All leaf realizations should be CubeInstance");
// }
return Lists.newArrayList();
}
@Override
public boolean moveNext() {
while (currentDict == null || !currentDict.hasNext()) {
if (!iterator.hasNext()) {
return false;
}
final Dictionary<String> dict = iterator.next();
currentDict = dict.enumeratorValues().iterator();
}
current[dictColIdx] = Tuple.convertOptiqCellValue(currentDict.next(), dictCol.getDatatype());
return true;
}
@Override
public Object[] current() {
return current;
}
@Override
public void reset() {
iterator = dictList.iterator();
}
@Override
public void close() {
}
}