blob: 560fc0af7d9efb0047cde8c8dc181c43386fa609 [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.phoenix.schema.stats;
import java.util.Collections;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HRegionInfo;
import org.apache.phoenix.query.QueryServices;
import org.apache.phoenix.query.QueryServicesOptions;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
/**
* Singleton that is used to track state associated with regions undergoing stats collection at the
* region server's JVM level.
*/
public class StatisticsCollectionRunTracker {
private static volatile StatisticsCollectionRunTracker INSTANCE;
private final Set<HRegionInfo> updateStatsRegions = Collections
.newSetFromMap(new ConcurrentHashMap<HRegionInfo, Boolean>());
private final Set<HRegionInfo> compactingRegions = Collections
.newSetFromMap(new ConcurrentHashMap<HRegionInfo, Boolean>());
private final ExecutorService executor;
// Constants added for testing purposes
public static final long CONCURRENT_UPDATE_STATS_ROW_COUNT = -100l;
public static final long COMPACTION_UPDATE_STATS_ROW_COUNT = -200l;
public static StatisticsCollectionRunTracker getInstance(Configuration config) {
StatisticsCollectionRunTracker result = INSTANCE;
if (result == null) {
synchronized (StatisticsCollectionRunTracker.class) {
result = INSTANCE;
if (result == null) {
INSTANCE = result = new StatisticsCollectionRunTracker(config);
}
}
}
return result;
}
private StatisticsCollectionRunTracker(Configuration config) {
int poolSize =
config.getInt(QueryServices.STATS_SERVER_POOL_SIZE,
QueryServicesOptions.DEFAULT_STATS_POOL_SIZE);
ThreadFactoryBuilder builder =
new ThreadFactoryBuilder().setDaemon(true).setNameFormat(
"phoenix-update-statistics-%s");
executor = Executors.newFixedThreadPool(poolSize, builder.build());
}
/**
* @param regionInfo for the region that should be marked as undergoing stats collection via
* major compaction.
* @return true if the region wasn't already marked for stats collection via compaction, false
* otherwise.
*/
public boolean addCompactingRegion(HRegionInfo regionInfo) {
return compactingRegions.add(regionInfo);
}
/**
* @param regionInfo for the region that should be unmarked as undergoing stats collection via
* major compaction.
* @return true if the region was marked for stats collection via compaction, false otherwise.
*/
public boolean removeCompactingRegion(HRegionInfo regionInfo) {
return compactingRegions.remove(regionInfo);
}
/**
* @param regionInfo for the region to check for.
* @return true if stats are being collected for the region via major compaction, false
* otherwise.
*/
public boolean areStatsBeingCollectedOnCompaction(HRegionInfo regionInfo) {
return compactingRegions.contains(regionInfo);
}
/**
* @param regionInfo for the region to run UPDATE STATISTICS command on.
* @return true if UPDATE STATISTICS wasn't already running on the region, false otherwise.
*/
public boolean addUpdateStatsCommandRegion(HRegionInfo regionInfo) {
return updateStatsRegions.add(regionInfo);
}
/**
* @param regionInfo for the region to mark as not running UPDATE STATISTICS command on.
* @return true if UPDATE STATISTICS was running on the region, false otherwise.
*/
public boolean removeUpdateStatsCommandRegion(HRegionInfo regionInfo) {
return updateStatsRegions.remove(regionInfo);
}
/**
* Enqueues the task for execution.
* @param <T>
* @param c task to execute
*/
public <T> Future<T> runTask(Callable<T> c) {
return executor.submit(c);
}
}