blob: e9316aca4cf8ae61ceb46b436da755a650a82990 [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.carbondata.core.cache;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;
import org.apache.carbondata.common.logging.LogServiceFactory;
import org.apache.carbondata.core.constants.CarbonCommonConstants;
import org.apache.carbondata.core.indexstore.BlockletIndexStore;
import org.apache.carbondata.core.util.CarbonProperties;
import org.apache.log4j.Logger;
/**
* Cache provider class which will create a cache based on given type
*/
public class CacheProvider {
/**
* cache provider instance
*/
private static CacheProvider cacheProvider = new CacheProvider();
/**
* a map that will hold the entry for cache type to cache object mapping
*/
private Map<CacheType, Cache> cacheTypeToCacheMap =
new HashMap<>(CarbonCommonConstants.DEFAULT_COLLECTION_SIZE);
/**
* object lock instance to be used in synchronization block
*/
private final Object lock = new Object();
/**
* LRU cache instance
*/
private CarbonLRUCache carbonLRUCache;
/**
* instance for CacheProvider LOGGER
*/
private static final Logger LOGGER =
LogServiceFactory.getLogService(CacheProvider.class.getName());
/**
* private constructor to follow singleton design pattern for this class
*/
private CacheProvider() {
}
/**
* @return cache provider instance
*/
public static CacheProvider getInstance() {
return cacheProvider;
}
/**
* This method will check if a cache already exists for given cache type and create in case
* it is not present in the map
*
* @param cacheType type of cache
* @param <K>
* @param <V>
* @return
*/
public <K, V> Cache<K, V> createCache(CacheType cacheType) {
//check if lru cache is null, if null create one
//check if cache is null for given cache type, if null create one
if (!isCacheExists(cacheType)) {
synchronized (lock) {
if (!isCacheExists(cacheType)) {
if (null == carbonLRUCache) {
createLRULevelCacheInstance();
}
createBlockletIndexCache(cacheType);
}
}
}
return cacheTypeToCacheMap.get(cacheType);
}
/**
* This method will check if a cache already exists for given cache type and store
* if it is not present in the map
*/
public <K, V> Cache<K, V> createCache(CacheType cacheType, String cacheClassName)
throws Exception {
//check if lru cache is null, if null create one
//check if cache is null for given cache type, if null create one
if (!isCacheExists(cacheType)) {
synchronized (lock) {
if (!isCacheExists(cacheType)) {
if (null == carbonLRUCache) {
createLRULevelCacheInstance();
}
Class<?> clazz = Class.forName(cacheClassName);
Constructor<?> constructor = clazz.getConstructors()[0];
constructor.setAccessible(true);
Cache cacheObject = (Cache) constructor.newInstance(carbonLRUCache);
cacheTypeToCacheMap.put(cacheType, cacheObject);
}
}
}
return cacheTypeToCacheMap.get(cacheType);
}
/**
* This method will create the cache for given cache type
*
* @param cacheType type of cache
*/
private void createBlockletIndexCache(CacheType cacheType) {
Cache cacheObject = null;
if (cacheType.equals(CacheType.DRIVER_BLOCKLET_INDEX)) {
cacheObject = new BlockletIndexStore(carbonLRUCache);
}
cacheTypeToCacheMap.put(cacheType, cacheObject);
}
/**
* This method will create the lru cache instance based on the given type
*
*/
private void createLRULevelCacheInstance() {
boolean isDriver = Boolean.parseBoolean(CarbonProperties.getInstance()
.getProperty(CarbonCommonConstants.IS_DRIVER_INSTANCE,
CarbonCommonConstants.IS_DRIVER_INSTANCE_DEFAULT));
if (isDriver) {
carbonLRUCache = new CarbonLRUCache(CarbonCommonConstants.CARBON_MAX_DRIVER_LRU_CACHE_SIZE,
CarbonCommonConstants.CARBON_MAX_LRU_CACHE_SIZE_DEFAULT);
} else {
String executorCacheSize = CarbonProperties.getInstance()
.getProperty(CarbonCommonConstants.CARBON_MAX_EXECUTOR_LRU_CACHE_SIZE);
if (null == executorCacheSize) {
String executorCachePercent = CarbonProperties.getInstance()
.getProperty(CarbonCommonConstants.CARBON_EXECUTOR_LRU_CACHE_PERCENT);
long mSizeMB = Runtime.getRuntime().maxMemory() / (1024 * 1024);
long executorLruCache;
if (null != executorCachePercent) {
int percentValue = Integer.parseInt(executorCachePercent);
if (percentValue >= 5 && percentValue <= 95) {
double mPercent = (double) percentValue / 100;
executorLruCache = (long) (mSizeMB * mPercent);
} else {
LOGGER.info("Illegal value provided to Executor LRU cache percent. " +
"Initializing with default executor LRU cache percentage size.");
executorLruCache = (long) (mSizeMB *
CarbonCommonConstants.CARBON_DEFAULT_EXECUTOR_LRU_CACHE_PERCENT);
}
} else {
LOGGER.info("Value of Executor LRU cache percentage is not provided. " +
"Initializing with default executor LRU cache percentage size.");
executorLruCache = (long) (mSizeMB *
CarbonCommonConstants.CARBON_DEFAULT_EXECUTOR_LRU_CACHE_PERCENT);
}
CarbonProperties.getInstance()
.addProperty(CarbonCommonConstants.CARBON_MAX_EXECUTOR_LRU_CACHE_SIZE,
String.valueOf(executorLruCache));
}
carbonLRUCache =
new CarbonLRUCache(CarbonCommonConstants.CARBON_MAX_EXECUTOR_LRU_CACHE_SIZE,
CarbonCommonConstants.CARBON_MAX_LRU_CACHE_SIZE_DEFAULT);
}
}
/**
* This method will check whether the map already has an entry for
* given cache type
*
* @param cacheType
* @return
*/
private boolean isCacheExists(CacheType cacheType) {
return null != cacheTypeToCacheMap.get(cacheType);
}
public CarbonLRUCache getCarbonCache() {
return carbonLRUCache;
}
}