/**
* 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.execution;
import org.diqube.data.column.ColumnShard;
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.DelegatingExecutionEnvironment;
import org.diqube.executionenv.ExecutionEnvironment;
import org.diqube.executionenv.ExecutionEnvironmentFactory;
import org.diqube.executionenv.VersionedExecutionEnvironment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This {@link ColumnVersionManager} handles creation of intermediate {@link VersionedExecutionEnvironment} which hold
* different versions of columns during execution of a {@link ExecutablePlan} on the query master.
*
* <p>
* Using this manager ensures that {@link VersionedExecutionEnvironment} with a higher version has the same or more
* information available than smaller versions. It will never happen that a {@link VersionedExecutionEnvironment} with
* higher version number has less information than one with lower version.
*
* <p>
* "More information" hereby means, that the newer {@link VersionedExecutionEnvironment} has information about more
* columns, more rows in a column etc.
*
* @author Bastian Gloeckle
*/
public class ColumnVersionManager {
private static final Logger logger = LoggerFactory.getLogger(ColumnVersionManager.class);
private ExecutionEnvironmentFactory executionEnvironmentFactory;
private ExecutionEnvironment defaultEnv;
private VersionedExecutionEnvironment lastVersionedExecutionEnvironment = null;
public ColumnVersionManager(ExecutionEnvironmentFactory executionEnvironmentFactory,
ExecutionEnvironment defaultEnv) {
this.executionEnvironmentFactory = executionEnvironmentFactory;
this.defaultEnv = defaultEnv;
}
/**
* Create a new version of an intermediary {@link ExecutionEnvironment} with the given updated columns.
*
* @param updatedColShard
* The columns that have new values. These columns will override the values the previous intermediary
* {@link ExecutionEnvironment} had of those columns.
* @return a new {@link VersionedExecutionEnvironment} that has strictly more data than the previous one. The returned
* {@link VersionedExecutionEnvironment} will be unmodifiable and calls to the store* methods will throw a
* corresponding exception.
*/
public synchronized VersionedExecutionEnvironment createNewVersion(ColumnShard... updatedColShard) {
DelegatingExecutionEnvironment res;
if (lastVersionedExecutionEnvironment == null)
res = executionEnvironmentFactory.createDelegatingExecutionEnvironment(defaultEnv, Integer.MIN_VALUE);
else
res = executionEnvironmentFactory.createDelegatingExecutionEnvironment(lastVersionedExecutionEnvironment,
lastVersionedExecutionEnvironment.getVersion() + 1);
if (updatedColShard != null) {
for (ColumnShard newShard : updatedColShard) {
logger.trace("New ExecutionEnvironment, version {}, updated col {}", res.getVersion(), newShard.getName());
switch (newShard.getColumnType()) {
case STRING:
res.storeTemporaryStringColumnShard((StringColumnShard) newShard);
break;
case LONG:
res.storeTemporaryLongColumnShard((LongColumnShard) newShard);
break;
case DOUBLE:
res.storeTemporaryDoubleColumnShard((DoubleColumnShard) newShard);
break;
}
}
}
res.makeUnmodifiable();
lastVersionedExecutionEnvironment = res;
return res;
}
/** The last created {@link VersionedExecutionEnvironment}, if any. */
public VersionedExecutionEnvironment getLastVersionedExecutionEnvironment() {
return lastVersionedExecutionEnvironment;
}
}