/* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * 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 org.dashbuilder.dataset.engine.index; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.dashbuilder.dataset.group.Interval; import org.dashbuilder.dataset.engine.group.IntervalList; import org.dashbuilder.dataset.engine.index.visitor.DataSetIndexVisitor; import org.dashbuilder.dataset.group.ColumnGroup; /** * A DataSet group operation index */ public class DataSetGroupIndex extends DataSetIndexNode implements DataSetIntervalIndexHolder { // The group index is composed by a set of interval indexes. ColumnGroup columnGroup = null; List<DataSetIntervalIndex> intervalIndexList = null; String intervalType = null; Object minValue = null; Object maxValue = null; // And can (optionally) contains a subset of interval selections. List<DataSetGroupIndex> selectIndexList = null; // When the group represents a selection it has a selection key. String selectKey = null; public DataSetGroupIndex(ColumnGroup columnGroup) { super(); this.columnGroup = columnGroup; this.intervalIndexList = new ArrayList<DataSetIntervalIndex>(); this.intervalType = columnGroup != null ? columnGroup.getIntervalSize() : null; } public DataSetGroupIndex(ColumnGroup columnGroup, IntervalList intervalList) { this(columnGroup); intervalType = intervalList.getIntervalType(); minValue = intervalList.getMinValue(); maxValue = intervalList.getMaxValue(); for (Interval interval : intervalList) { intervalIndexList.add(new DataSetIntervalIndex(this, interval)); } } public DataSetGroupIndex(String selectKey, List<DataSetIntervalIndex> intervalIndexes) { this(null); this.selectKey = selectKey; for (DataSetIntervalIndex index : intervalIndexes) { addIntervalIndex(index); } } public void addIntervalIndex(DataSetIntervalIndex index) { intervalType = index.getIntervalType(); Comparable min = (Comparable) index.getMinValue(); Comparable max = (Comparable) index.getMaxValue(); if (minValue == null || ((Comparable) minValue).compareTo(min) > 0) minValue = min; if (maxValue == null || ((Comparable) maxValue).compareTo(max) < 0) maxValue = max; intervalIndexList.add(index); } public String getIntervalType() { return intervalType; } public Object getMinValue() { return minValue; } public Object getMaxValue() { return maxValue; } public void setIntervalType(String intervalType) { this.intervalType = intervalType; } public void setMinValue(Object minValue) { this.minValue = minValue; } public void setMaxValue(Object maxValue) { this.maxValue = maxValue; } public List<DataSetIntervalIndex> getIntervalIndexes() { return intervalIndexList; } public List<DataSetIntervalIndex> getIntervalIndexes(List<Interval> intervalList) { List<DataSetIntervalIndex> result = new ArrayList<DataSetIntervalIndex>(); for (Interval interval : intervalList) { DataSetIntervalIndex idx = getIntervalIndex(interval.getName()); if (idx != null) { result.add(idx); } } return result; } public DataSetIntervalIndex getIntervalIndex(String name) { for (DataSetIntervalIndex idx : intervalIndexList) { String idxName = idx.getName(); if (idxName != null && idxName.equals(name)) { return idx; } if (idxName == null && name == null) { return idx; } } return null; } public int indexOfIntervalIndex(DataSetIntervalIndex target) { for (int i = 0; i < intervalIndexList.size(); i++) { DataSetIntervalIndex idx = intervalIndexList.get(i); String idxName = idx.getName(); String targetName = target.getName(); if (idxName != null && idxName.equals(targetName)) { return i; } if (idxName == null && targetName == null) { return i; } } return -1; } public DataSetGroupIndex getSelectionIndex(List<Interval> intervalList) { if (selectIndexList == null) { return null; } String targetKey = buildSelectKey(intervalList); for (DataSetGroupIndex idx : selectIndexList) { if (idx.selectKey.equals(targetKey)) { idx.reuseHit(); return idx; } } return null; } public DataSetGroupIndex indexSelection(List<Interval> intervalList, List<DataSetIntervalIndex> intervalIndexes) { if (selectIndexList == null) { selectIndexList = new ArrayList<DataSetGroupIndex>(); } String key = buildSelectKey(intervalList); DataSetGroupIndex index = new DataSetGroupIndex(key, intervalIndexes); index.setParent(this); index.setBuildTime(buildTime); selectIndexList.add(index); return index; } protected String buildSelectKey(List<Interval> intervalList) { StringBuilder out = new StringBuilder(); for (int i=0; i<intervalList.size(); i++) { if (i > 0) out.append(", "); out.append(intervalList.get(i).getName()); } return out.toString(); } public List<Integer> getRows() { if (intervalIndexList == null || intervalIndexList.isEmpty()) { return null; } List<Integer> results = new ArrayList<Integer>(); for (DataSetIntervalIndex intervalIndex : intervalIndexList) { results.addAll(intervalIndex.getRows()); } return results; } public void indexIntervals(Collection<DataSetIntervalIndex> intervalsIdxs) { for (DataSetIntervalIndex idx : intervalsIdxs) { indexInterval(idx); } } public void indexInterval(DataSetIntervalIndex intervalIdx) { String intervalName = intervalIdx.getName(); DataSetIntervalIndex existing = getIntervalIndex(intervalName); if (existing == null) { addIntervalIndex(intervalIdx); } else { if (existing instanceof DataSetIntervalSetIndex) { ((DataSetIntervalSetIndex) existing).addIntervalIndex(intervalIdx); } else if (existing != intervalIdx){ int i = indexOfIntervalIndex(existing); DataSetIntervalSetIndex indexSet = new DataSetIntervalSetIndex(this, intervalName); indexSet.addIntervalIndex(existing); indexSet.addIntervalIndex(intervalIdx); intervalIndexList.set(i, indexSet); } } } public void acceptVisitor(DataSetIndexVisitor visitor) { super.acceptVisitor(visitor); for (DataSetIntervalIndex index : intervalIndexList) { index.acceptVisitor(visitor); } } public String toString() { StringBuilder out = new StringBuilder(super.toString()); if (columnGroup != null) out.append(" column=").append(columnGroup.getColumnId()); if (selectKey != null) out.append(" select=").append(selectKey); return out.toString(); } }