forked from fanruan/easyexcel
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
128 lines
4.4 KiB
128 lines
4.4 KiB
package com.alibaba.excel.cache; |
|
|
|
import java.io.File; |
|
import java.util.ArrayList; |
|
import java.util.UUID; |
|
|
|
import com.alibaba.excel.context.AnalysisContext; |
|
import com.alibaba.excel.util.FileUtils; |
|
import com.alibaba.excel.util.ListUtils; |
|
|
|
import lombok.extern.slf4j.Slf4j; |
|
import org.apache.commons.collections4.CollectionUtils; |
|
import org.ehcache.CacheManager; |
|
import org.ehcache.config.CacheConfiguration; |
|
import org.ehcache.config.builders.CacheConfigurationBuilder; |
|
import org.ehcache.config.builders.CacheManagerBuilder; |
|
import org.ehcache.config.builders.ResourcePoolsBuilder; |
|
import org.ehcache.config.units.MemoryUnit; |
|
|
|
/** |
|
* Default cache |
|
* |
|
* @author Jiaju Zhuang |
|
*/ |
|
@Slf4j |
|
public class Ehcache implements ReadCache { |
|
public static final int BATCH_COUNT = 1000; |
|
/** |
|
* Key index |
|
*/ |
|
private int activeIndex = 0; |
|
public static final int DEBUG_CACHE_MISS_SIZE = 1000; |
|
public static final int DEBUG_WRITE_SIZE = 100 * 10000; |
|
private ArrayList<String> dataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); |
|
private static final CacheManager FILE_CACHE_MANAGER; |
|
private static final CacheConfiguration<Integer, ArrayList> FILE_CACHE_CONFIGURATION; |
|
private static final CacheManager ACTIVE_CACHE_MANAGER; |
|
private final CacheConfiguration<Integer, ArrayList> activeCacheConfiguration; |
|
/** |
|
* Bulk storage data |
|
*/ |
|
private org.ehcache.Cache<Integer, ArrayList> fileCache; |
|
/** |
|
* Currently active cache |
|
*/ |
|
private org.ehcache.Cache<Integer, ArrayList> activeCache; |
|
private String cacheAlias; |
|
/** |
|
* Count the number of cache misses |
|
*/ |
|
private int cacheMiss = 0; |
|
|
|
public Ehcache(int maxCacheActivateSize) { |
|
activeCacheConfiguration = CacheConfigurationBuilder |
|
.newCacheConfigurationBuilder(Integer.class, ArrayList.class, |
|
ResourcePoolsBuilder.newResourcePoolsBuilder().heap(maxCacheActivateSize, MemoryUnit.MB)) |
|
.withSizeOfMaxObjectGraph(1000 * 1000L).withSizeOfMaxObjectSize(maxCacheActivateSize, MemoryUnit.MB) |
|
.build(); |
|
} |
|
|
|
static { |
|
File cacheFile = FileUtils.createCacheTmpFile(); |
|
FILE_CACHE_MANAGER = |
|
CacheManagerBuilder.newCacheManagerBuilder().with(CacheManagerBuilder.persistence(cacheFile)).build(true); |
|
ACTIVE_CACHE_MANAGER = CacheManagerBuilder.newCacheManagerBuilder().build(true); |
|
FILE_CACHE_CONFIGURATION = CacheConfigurationBuilder |
|
.newCacheConfigurationBuilder(Integer.class, ArrayList.class, |
|
ResourcePoolsBuilder.newResourcePoolsBuilder().disk(10, MemoryUnit.GB)) |
|
.withSizeOfMaxObjectGraph(1000 * 1000L).withSizeOfMaxObjectSize(10, MemoryUnit.GB).build(); |
|
} |
|
|
|
@Override |
|
public void init(AnalysisContext analysisContext) { |
|
cacheAlias = UUID.randomUUID().toString(); |
|
fileCache = FILE_CACHE_MANAGER.createCache(cacheAlias, FILE_CACHE_CONFIGURATION); |
|
activeCache = ACTIVE_CACHE_MANAGER.createCache(cacheAlias, activeCacheConfiguration); |
|
} |
|
|
|
@Override |
|
public void put(String value) { |
|
dataList.add(value); |
|
if (dataList.size() >= BATCH_COUNT) { |
|
fileCache.put(activeIndex, dataList); |
|
activeIndex++; |
|
dataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); |
|
} |
|
if (log.isDebugEnabled()) { |
|
int alreadyPut = activeIndex * BATCH_COUNT + dataList.size(); |
|
if (alreadyPut % DEBUG_WRITE_SIZE == 0) { |
|
log.debug("Already put :{}", alreadyPut); |
|
} |
|
} |
|
} |
|
|
|
@Override |
|
public String get(Integer key) { |
|
if (key == null || key < 0) { |
|
return null; |
|
} |
|
int route = key / BATCH_COUNT; |
|
ArrayList<String> dataList = activeCache.get(route); |
|
if (dataList == null) { |
|
dataList = fileCache.get(route); |
|
activeCache.put(route, dataList); |
|
if (log.isDebugEnabled()) { |
|
if (cacheMiss++ % DEBUG_CACHE_MISS_SIZE == 0) { |
|
log.debug("Cache misses count:{}", cacheMiss); |
|
} |
|
} |
|
} |
|
return dataList.get(key % BATCH_COUNT); |
|
} |
|
|
|
@Override |
|
public void putFinished() { |
|
if (CollectionUtils.isEmpty(dataList)) { |
|
return; |
|
} |
|
fileCache.put(activeIndex, dataList); |
|
} |
|
|
|
@Override |
|
public void destroy() { |
|
FILE_CACHE_MANAGER.removeCache(cacheAlias); |
|
ACTIVE_CACHE_MANAGER.removeCache(cacheAlias); |
|
} |
|
|
|
}
|
|
|