org.diqube.executionenv.DefaultExecutionEnvironment.java Source code

Java tutorial

Introduction

Here is the source code for org.diqube.executionenv.DefaultExecutionEnvironment.java

Source

/**
 * 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.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.diqube.data.column.ColumnShard;
import org.diqube.data.table.TableShard;
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.cache.ColumnShardCache;
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.Sets;

/**
 * Default implementation of a {@link ExecutionEnvironment} which is based on the resources of a {@link TableShard} if
 * it is used on a query remote.
 * 
 * <p>
 * This implementation is {@link ColumnShardCache}-aware. This means that it will provide columns that are stored in the
 * {@link ColumnShardCache} for the corresponding {@link TableShard}.
 * 
 * If a {@link ColumnShard} is found to be cached, it is put directly into this {@link DefaultExecutionEnvironment} as
 * "temporary" column (just like when somebody calls {@link #storeTemporaryDoubleColumnShard(DoubleColumnShard)} etc).
 * This is because (1) the ColumnShard might be evicted from the cache while we're executing the plan - but the plan
 * relies on a column that was available once to be available in the future. And (2) it makes it easier to identify the
 * (new?) columns that should be cached after executing the plan this {@link DefaultExecutionEnvironment} belongs to.
 *
 * @author Bastian Gloeckle
 */
public class DefaultExecutionEnvironment extends AbstractExecutionEnvironment {
    /** could be <code>null</code> */
    private TableShard tableShard;
    private ColumnShardCache columnShardCache;

    /**
     * @param tableShard
     *          <code>null</code> for Query Master.
     * @param columnShardCache
     *          The cache to read ColumnShards from. This needs to be that cache that is responsible for the given
     *          tableShard. Cannot be set if parameter tableShard == null. Can be <code>null</code>.
     */
    public DefaultExecutionEnvironment(QueryRegistry queryRegistry, TableShard tableShard,
            ColumnShardCache columnShardCache) {
        super(queryRegistry);
        this.tableShard = tableShard;
        this.columnShardCache = columnShardCache;

        if (columnShardCache != null && tableShard == null)
            throw new IllegalArgumentException();
    }

    @Override
    public long getFirstRowIdInShard() {
        if (tableShard != null)
            return tableShard.getLowestRowId();

        // execution on query master -> we're looking at the whole table here.
        return 0L;
    }

    @Override
    public long getNumberOfRowsInShard() {
        if (tableShard != null)
            return tableShard.getNumberOfRowsInShard();
        return -1L;
    }

    @Override
    public long getLastRowIdInShard() {
        if (tableShard != null)
            return tableShard.getLowestRowId() + tableShard.getNumberOfRowsInShard() - 1;

        return -1L;
    }

    @Override
    protected QueryableLongColumnShard delegateGetLongColumnShard(String name) {
        LongColumnShard sourceColumnShard = null;
        if (tableShard != null)
            sourceColumnShard = tableShard.getLongColumns().get(name);

        if (sourceColumnShard == null && columnShardCache != null) {
            ColumnShard cachedShard = columnShardCache.get(tableShard.getLowestRowId(), name);
            if (cachedShard != null && cachedShard instanceof LongColumnShard) {
                sourceColumnShard = (LongColumnShard) cachedShard;
                // store col shard directly in our "temporary columns". see class comment.
                queryRegistry.getOrCreateCurrentStatsManager().incNumberOfTemporaryColumnShardsFromCache();
                internalStoreTemporaryLongColumnShard(sourceColumnShard);
            }
        }

        if (sourceColumnShard != null)
            return new QueryableLongColumnShardFacade(sourceColumnShard, false, queryRegistry);
        return null;
    }

    @Override
    protected QueryableStringColumnShard delegateGetStringColumnShard(String name) {
        StringColumnShard sourceColumnShard = null;
        if (tableShard != null)
            sourceColumnShard = tableShard.getStringColumns().get(name);

        if (sourceColumnShard == null && columnShardCache != null) {
            ColumnShard cachedShard = columnShardCache.get(tableShard.getLowestRowId(), name);
            if (cachedShard != null && cachedShard instanceof StringColumnShard) {
                sourceColumnShard = (StringColumnShard) cachedShard;
                // store col shard directly in our "temporary columns". see class comment.
                queryRegistry.getOrCreateCurrentStatsManager().incNumberOfTemporaryColumnShardsFromCache();
                internalStoreTemporaryStringColumnShard(sourceColumnShard);
            }
        }

        if (sourceColumnShard != null)
            return new QueryableStringColumnShardFacade(sourceColumnShard, false, queryRegistry);
        return null;
    }

    @Override
    protected QueryableDoubleColumnShard delegateGetDoubleColumnShard(String name) {
        DoubleColumnShard sourceColumnShard = null;
        if (tableShard != null)
            sourceColumnShard = tableShard.getDoubleColumns().get(name);

        if (sourceColumnShard == null && columnShardCache != null) {
            ColumnShard cachedShard = columnShardCache.get(tableShard.getLowestRowId(), name);
            if (cachedShard != null && cachedShard instanceof DoubleColumnShard) {
                sourceColumnShard = (DoubleColumnShard) cachedShard;
                // store col shard directly in our "temporary columns". see class comment.
                queryRegistry.getOrCreateCurrentStatsManager().incNumberOfTemporaryColumnShardsFromCache();
                internalStoreTemporaryDoubleColumnShard(sourceColumnShard);
            }
        }

        if (sourceColumnShard != null)
            return new QueryableDoubleColumnShardFacade(sourceColumnShard, false, queryRegistry);
        return null;
    }

    @Override
    public String toString() {
        return this.getClass().getSimpleName() + "[tableShard="
                + ((tableShard == null) ? "null" : tableShard.toString()) + "]";
    }

    @Override
    protected boolean delegateIsTemporaryColumns(String colName) {
        // delegate loads from tableShard, so "no", this col is no temp col.
        return false;
    }

    @Override
    protected Map<String, List<QueryableColumnShard>> delegateGetAllTemporaryColumnShards() {
        return new HashMap<>();
    }

    @Override
    protected Map<String, QueryableColumnShard> delegateGetAllNonTemporaryColumnShards() {
        Map<String, QueryableColumnShard> res = new HashMap<>();

        Set<String> allColNames = new HashSet<>();

        if (tableShard != null) {
            allColNames.addAll(Sets.union(
                    Sets.union(tableShard.getDoubleColumns().keySet(), tableShard.getLongColumns().keySet()),
                    tableShard.getStringColumns().keySet()));
        }

        for (String colName : allColNames) {
            QueryableColumnShard colShard = getColumnShard(colName);
            res.put(colName, colShard);
        }

        return res;
    }

}