| /* |
| * 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; |
| } |
| } |