/** * diqube: Distributed Query Base. * * Copyright (C) 2015 Bastian Gloeckle * * This file is part of diqube. * * diqube is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.diqube.executionenv; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import org.diqube.data.column.ColumnShard; import org.diqube.data.column.ColumnType; import org.diqube.data.column.ConstantColumnShard; import org.diqube.data.column.StandardColumnShard; import org.diqube.data.types.dbl.DoubleColumnShard; import org.diqube.data.types.lng.LongColumnShard; import org.diqube.data.types.str.StringColumnShard; import org.diqube.executionenv.querystats.AbstractQueryableColumnShardFacade; import org.diqube.executionenv.querystats.QueryableColumnShard; import org.diqube.executionenv.querystats.QueryableDoubleColumnShard; import org.diqube.executionenv.querystats.QueryableDoubleColumnShardFacade; import org.diqube.executionenv.querystats.QueryableLongColumnShard; import org.diqube.executionenv.querystats.QueryableLongColumnShardFacade; import org.diqube.executionenv.querystats.QueryableStringColumnShard; import org.diqube.executionenv.querystats.QueryableStringColumnShardFacade; import org.diqube.queries.QueryRegistry; import com.google.common.collect.Iterables; /** * Abstract implementation of an {@link ExecutionEnvironment} containing a separate set of Long, String and Double * columns. * * @author Bastian Gloeckle */ public abstract class AbstractExecutionEnvironment implements ExecutionEnvironment { private Map<String, QueryableLongColumnShardFacade> tempLongColumns = new ConcurrentHashMap<>(); private Map<String, QueryableStringColumnShardFacade> tempStringColumns = new ConcurrentHashMap<>(); private Map<String, QueryableDoubleColumnShardFacade> tempDoubleColumns = new ConcurrentHashMap<>(); protected QueryRegistry queryRegistry; public AbstractExecutionEnvironment(QueryRegistry queryRegistry) { this.queryRegistry = queryRegistry; } @Override public QueryableLongColumnShard getLongColumnShard(String name) { if (tempLongColumns.containsKey(name)) return tempLongColumns.get(name); return delegateGetLongColumnShard(name); } /** * @return <code>null</code> if not available. */ abstract protected QueryableLongColumnShard delegateGetLongColumnShard(String name); @Override public QueryableStringColumnShard getStringColumnShard(String name) { if (tempStringColumns.containsKey(name)) return tempStringColumns.get(name); return delegateGetStringColumnShard(name); } /** * @return <code>null</code> if not available. */ abstract protected QueryableStringColumnShard delegateGetStringColumnShard(String name); @Override public QueryableDoubleColumnShard getDoubleColumnShard(String name) { if (tempDoubleColumns.containsKey(name)) return tempDoubleColumns.get(name); return delegateGetDoubleColumnShard(name); } /** * @return <code>null</code> if not available. */ abstract protected QueryableDoubleColumnShard delegateGetDoubleColumnShard(String name); @Override public ColumnType getColumnType(String colName) { if (getLongColumnShard(colName) != null) return ColumnType.LONG; if (getStringColumnShard(colName) != null) return ColumnType.STRING; if (getDoubleColumnShard(colName) != null) return ColumnType.DOUBLE; return null; } @Override public QueryableColumnShard getColumnShard(String name) { QueryableColumnShard res = getLongColumnShard(name); if (res != null) return res; res = getStringColumnShard(name); if (res != null) return res; return getDoubleColumnShard(name); } @Override public void storeTemporaryLongColumnShard(LongColumnShard column) { queryRegistry.getOrCreateCurrentStatsManager().incNumberOfTemporaryColumnShardsCreated(); internalStoreTemporaryLongColumnShard(column); } protected void internalStoreTemporaryLongColumnShard(LongColumnShard column) { tempLongColumns.put(column.getName(), new QueryableLongColumnShardFacade(column, true, queryRegistry)); } @Override public void storeTemporaryStringColumnShard(StringColumnShard column) { queryRegistry.getOrCreateCurrentStatsManager().incNumberOfTemporaryColumnShardsCreated(); internalStoreTemporaryStringColumnShard(column); } protected void internalStoreTemporaryStringColumnShard(StringColumnShard column) { tempStringColumns.put(column.getName(), new QueryableStringColumnShardFacade(column, true, queryRegistry)); } @Override public void storeTemporaryDoubleColumnShard(DoubleColumnShard column) { queryRegistry.getOrCreateCurrentStatsManager().incNumberOfTemporaryColumnShardsCreated(); internalStoreTemporaryDoubleColumnShard(column); } protected void internalStoreTemporaryDoubleColumnShard(DoubleColumnShard column) { tempDoubleColumns.put(column.getName(), new QueryableDoubleColumnShardFacade(column, true, queryRegistry)); } @Override public StandardColumnShard getPureStandardColumnShard(String name) { ColumnShard colShard = getColumnShard(name); if (colShard == null) return null; if (colShard instanceof QueryableColumnShard) colShard = ((QueryableColumnShard) colShard).getDelegate(); if (colShard instanceof StandardColumnShard) return (StandardColumnShard) colShard; return null; } @Override public ConstantColumnShard getPureConstantColumnShard(String name) { ColumnShard colShard = getColumnShard(name); if (colShard == null) return null; if (colShard instanceof QueryableColumnShard) colShard = ((QueryableColumnShard) colShard).getDelegate(); if (colShard instanceof ConstantColumnShard) return (ConstantColumnShard) colShard; return null; } protected Set<String> getAllColumnNamesDefinedInThisEnv() { Set<String> res = new HashSet<>(); res.addAll(tempDoubleColumns.keySet()); res.addAll(tempLongColumns.keySet()); res.addAll(tempStringColumns.keySet()); return res; } @Override public boolean isTemporaryColumn(String colName) { return tempDoubleColumns.containsKey(colName) || tempLongColumns.containsKey(colName) || tempStringColumns.containsKey(colName) || delegateIsTemporaryColumns(colName); } protected abstract boolean delegateIsTemporaryColumns(String colName); @Override public Map<String, List<QueryableColumnShard>> getAllTemporaryColumnShards() { Map<String, List<QueryableColumnShard>> res = delegateGetAllTemporaryColumnShards(); for (Entry<String, ? extends AbstractQueryableColumnShardFacade> tempEntry : Iterables .concat(tempDoubleColumns.entrySet(), tempLongColumns.entrySet(), tempStringColumns.entrySet())) { if (!res.containsKey(tempEntry.getKey())) res.put(tempEntry.getKey(), new ArrayList<>()); res.get(tempEntry.getKey()).add(tempEntry.getValue()); } return res; } protected abstract Map<String, List<QueryableColumnShard>> delegateGetAllTemporaryColumnShards(); @Override public Map<String, QueryableColumnShard> getAllNonTemporaryColumnShards() { return delegateGetAllNonTemporaryColumnShards(); } protected abstract Map<String, QueryableColumnShard> delegateGetAllNonTemporaryColumnShards(); }