blob: 61f87623c97c0b2fff8ceff1a7b51c3c8d4154b6 [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.impala.common;
import com.google.common.base.Preconditions;
import org.apache.impala.catalog.SideloadTableStats;
import java.util.HashMap;
import java.util.Map;
/**
* Contains runtime-specific parameters such as the number of CPU cores. Currently only
* used in Plan cost estimation. The static RuntimeEnv members can be set so that tests
* can rely on a machine-independent RuntimeEnv.
*/
public class RuntimeEnv {
public static RuntimeEnv INSTANCE = new RuntimeEnv();
private int numCores_;
// Indicates whether this is an environment for testing.
private boolean isTestEnv_;
// Map of <Db,<Table,SideloadTableStats>> that is used to simulate large scale table
// during testing.
private Map<String, Map<String, SideloadTableStats>> sideloadStats_ = null;
// Map of <Db,<Table,ScanRangeLimit>> that is used to inject desired scan range limit
// for specific table scan. Used to simulate larger number of files in a table scan.
private Map<String, Map<String, Long>> tableScanRangeLimit_ = null;
public RuntimeEnv() {
reset();
}
/**
* Resets this RuntimeEnv back to its machine-dependent state.
*/
public void reset() {
numCores_ = Runtime.getRuntime().availableProcessors();
isTestEnv_ = false;
}
public int getNumCores() { return numCores_; }
public void setNumCores(int numCores) { this.numCores_ = numCores; }
public void setTestEnv(boolean v) { isTestEnv_ = v; }
public boolean isTestEnv() { return isTestEnv_; }
public boolean hasTableScanRangeLimit() { return tableScanRangeLimit_ != null; }
/**
* Populate the test stats with given sideloadStats.
* isTestEnv() must be true, and caller must invalidate the table on their own to
* trigger table stats reloading from this RuntimeEnv.
* @param sideloadStats map containing the test stats.
*/
public void setSideloadStats(
Map<String, Map<String, SideloadTableStats>> sideloadStats) {
Preconditions.checkState(isTestEnv_);
sideloadStats_ = sideloadStats;
}
/**
* Check if db.table has SideloadStas declared.
* @param db database name.
* @param table table name.
* @return true if there is a SideloadStas declared for db.table. Otherwise, false.
*/
public boolean hasSideloadStats(String db, String table) {
return sideloadStats_ != null && sideloadStats_.containsKey(db)
&& sideloadStats_.get(db).containsKey(table);
}
/**
* Get SideloadStats for specified db.name.
* @param db database name.
* @param table table name.
* @return SideloadStats or null of there is no SideloadStats specified
* for db.table.
*/
public SideloadTableStats getSideloadStats(String db, String table) {
if (!hasSideloadStats(db, table)) return null;
return sideloadStats_.get(db).get(table);
}
/**
* Drop all test stats that previously set.
* Caller must invalidate the table on their own to trigger table stats reloading
* from Metastore.
*/
public void dropSideloadStats() { sideloadStats_ = null; }
/**
* Add a scan range limit for db.table scan. isTestEnv() must be true.
* @param db database name. Must not null nor empty.
* @param table table name. Must not null nor empty.
* @param scanRangeLimit the scan range limit.
*/
public void addTableScanRangeLimit(String db, String table, long scanRangeLimit) {
Preconditions.checkNotNull(db);
Preconditions.checkNotNull(table);
Preconditions.checkArgument(!db.isEmpty());
Preconditions.checkArgument(!table.isEmpty());
Preconditions.checkArgument(scanRangeLimit > 1);
Preconditions.checkState(isTestEnv_);
if (tableScanRangeLimit_ == null) tableScanRangeLimit_ = new HashMap<>();
if (!tableScanRangeLimit_.containsKey(db)) {
tableScanRangeLimit_.put(db, new HashMap<>());
}
tableScanRangeLimit_.get(db).put(table, scanRangeLimit);
}
/**
* Get scan range limit for db.table.
* @param db database name.
* @param table table name.
* @return scan range limit for db.table or -1 if none were specified.
*/
public long getTableScanRangeLimit(String db, String table) {
long scanRangeLimit = -1;
if (isTestEnv_ && tableScanRangeLimit_ != null && tableScanRangeLimit_.containsKey(db)
&& tableScanRangeLimit_.get(db).containsKey(table)) {
scanRangeLimit = tableScanRangeLimit_.get(db).get(table);
}
return scanRangeLimit;
}
/**
* Drop all scan range limit that previously set.
*/
public void dropTableScanRangeLimit() { tableScanRangeLimit_ = null; }
}