zhuangjiaju
5 years ago
17 changed files with 539 additions and 64 deletions
@ -0,0 +1,36 @@ |
|||||||
|
package com.alibaba.excel.cache; |
||||||
|
|
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
|
||||||
|
/** |
||||||
|
* Default cache |
||||||
|
* |
||||||
|
* @author zhuangjiaju |
||||||
|
*/ |
||||||
|
public class Ehcache2 implements Cache { |
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(Ehcache2.class); |
||||||
|
|
||||||
|
int index = 0; |
||||||
|
// private org.ehcache.Cache<Integer, String> cache;
|
||||||
|
|
||||||
|
private Map<Integer, String> cache = new HashMap<Integer, String>(); |
||||||
|
|
||||||
|
public Ehcache2() {} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void put(Integer key, String value) { |
||||||
|
cache.put(key, value); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String get(Integer key) { |
||||||
|
return cache.get(key); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void finish() {} |
||||||
|
} |
@ -0,0 +1,123 @@ |
|||||||
|
package com.alibaba.excel.cache; |
||||||
|
|
||||||
|
import java.io.File; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.HashSet; |
||||||
|
import java.util.Iterator; |
||||||
|
import java.util.Map; |
||||||
|
import java.util.Set; |
||||||
|
import java.util.TreeMap; |
||||||
|
|
||||||
|
import org.ehcache.PersistentCacheManager; |
||||||
|
import org.ehcache.config.builders.CacheConfigurationBuilder; |
||||||
|
import org.ehcache.config.builders.CacheManagerBuilder; |
||||||
|
import org.ehcache.config.builders.ResourcePoolsBuilder; |
||||||
|
import org.ehcache.config.units.MemoryUnit; |
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
|
||||||
|
import com.alibaba.excel.util.POITempFile; |
||||||
|
import com.alibaba.excel.util.StringUtils; |
||||||
|
|
||||||
|
/** |
||||||
|
* Default cache |
||||||
|
* |
||||||
|
* @author zhuangjiaju |
||||||
|
*/ |
||||||
|
public class EhcacheFile implements Cache { |
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(EhcacheFile.class); |
||||||
|
private static final int BATCH = 500; |
||||||
|
int index = 0; |
||||||
|
int expirekey = 0; |
||||||
|
private org.ehcache.Cache<Integer, String> cache; |
||||||
|
// private Map<Integer, String> cache = new HashMap<Integer, String>();
|
||||||
|
private Map<Integer, Map<Integer, String>> cacheMap = new HashMap<Integer, Map<Integer, String>>(); |
||||||
|
private TreeMap<Integer, Integer> expire = new TreeMap<Integer, Integer>(); |
||||||
|
private StringBuilder sb = new StringBuilder(); |
||||||
|
private Set<Integer> count = new HashSet<Integer>(); |
||||||
|
private int getCount = 1; |
||||||
|
|
||||||
|
public EhcacheFile() { |
||||||
|
File file = POITempFile.createCacheTmpFile(); |
||||||
|
PersistentCacheManager persistentCacheManager = |
||||||
|
CacheManagerBuilder.newCacheManagerBuilder().with(CacheManagerBuilder.persistence(file)) |
||||||
|
.withCache("cache", CacheConfigurationBuilder.newCacheConfigurationBuilder(Integer.class, String.class, |
||||||
|
ResourcePoolsBuilder.newResourcePoolsBuilder().disk(10, MemoryUnit.GB))) |
||||||
|
.build(true); |
||||||
|
this.cache = persistentCacheManager.getCache("cache", Integer.class, String.class); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void put(Integer key, String value) { |
||||||
|
sb.append(index++).append(":").append(value).append(","); |
||||||
|
if (index != 0 && index % BATCH == 0) { |
||||||
|
int key1 = index / BATCH; |
||||||
|
cache.put(key1, sb.toString()); |
||||||
|
// LOGGER.info("put:key:{},{}", key1, sb.toString());
|
||||||
|
sb = new StringBuilder(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String get(Integer key) { |
||||||
|
int route = key / BATCH; |
||||||
|
route++; |
||||||
|
if (!cacheMap.containsKey(route)) { |
||||||
|
// LOGGER.info("key:{},route:{},missing", key, route);
|
||||||
|
Map<Integer, String> map = new HashMap<Integer, String>(10000 / 3 * 4 + 1); |
||||||
|
String s = cache.get(route); |
||||||
|
String[] values = s.split(","); |
||||||
|
for (String value : values) { |
||||||
|
String[] vv = value.split(":"); |
||||||
|
map.put(Integer.valueOf(vv[0]), vv[1]); |
||||||
|
} |
||||||
|
cacheMap.put(route, map); |
||||||
|
expire.put(expirekey++, route); |
||||||
|
} |
||||||
|
count.add(route); |
||||||
|
|
||||||
|
if (getCount++ % 1000 == 0) { |
||||||
|
Iterator<Map.Entry<Integer, Map<Integer, String>>> iterator = cacheMap.entrySet().iterator(); |
||||||
|
// LOGGER.info("size:{}", cacheMap.size());
|
||||||
|
while (iterator.hasNext()) { |
||||||
|
Map.Entry<Integer, Map<Integer, String>> entry = iterator.next(); |
||||||
|
if (!count.contains(entry.getKey())) { |
||||||
|
// LOGGER.info("route:{},remove", entry.getKey());
|
||||||
|
iterator.remove(); |
||||||
|
Iterator<Map.Entry<Integer, Integer>> ex = expire.entrySet().iterator(); |
||||||
|
while (ex.hasNext()) { |
||||||
|
Map.Entry<Integer, Integer> e = ex.next(); |
||||||
|
if (e.getValue().equals(entry.getKey())) { |
||||||
|
ex.remove(); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
count.clear(); |
||||||
|
} |
||||||
|
|
||||||
|
if (expire.size() > 10) { |
||||||
|
int value1 = expire.firstEntry().getValue(); |
||||||
|
int key1 = expire.firstEntry().getKey(); |
||||||
|
cacheMap.remove(value1); |
||||||
|
expire.remove(key1); |
||||||
|
} |
||||||
|
|
||||||
|
return cacheMap.get(route).get(key); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void finish() { |
||||||
|
if (StringUtils.isEmpty(sb.toString())) { |
||||||
|
return; |
||||||
|
} |
||||||
|
int key1 = index / BATCH; |
||||||
|
if (index % BATCH != 0) { |
||||||
|
key1++; |
||||||
|
} |
||||||
|
|
||||||
|
cache.put(key1, sb.toString()); |
||||||
|
// LOGGER.info("put:key:{},{}", key1 + 1, sb.toString());
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,123 @@ |
|||||||
|
package com.alibaba.excel.cache; |
||||||
|
|
||||||
|
import java.io.File; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.HashSet; |
||||||
|
import java.util.Iterator; |
||||||
|
import java.util.Map; |
||||||
|
import java.util.Set; |
||||||
|
import java.util.TreeMap; |
||||||
|
|
||||||
|
import org.ehcache.PersistentCacheManager; |
||||||
|
import org.ehcache.config.builders.CacheConfigurationBuilder; |
||||||
|
import org.ehcache.config.builders.CacheManagerBuilder; |
||||||
|
import org.ehcache.config.builders.ResourcePoolsBuilder; |
||||||
|
import org.ehcache.config.units.MemoryUnit; |
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
|
||||||
|
import com.alibaba.excel.util.POITempFile; |
||||||
|
import com.alibaba.excel.util.StringUtils; |
||||||
|
|
||||||
|
/** |
||||||
|
* Default cache |
||||||
|
* |
||||||
|
* @author zhuangjiaju |
||||||
|
*/ |
||||||
|
public class EhcacheMix implements Cache { |
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(EhcacheMix.class); |
||||||
|
private static final int BATCH = 500; |
||||||
|
int index = 0; |
||||||
|
int expirekey = 0; |
||||||
|
private org.ehcache.Cache<Integer, String> cache; |
||||||
|
private Map<Integer, Map<Integer, String>> cacheMap = new HashMap<Integer, Map<Integer, String>>(); |
||||||
|
private TreeMap<Integer, Integer> expire = new TreeMap<Integer, Integer>(); |
||||||
|
private StringBuilder sb = new StringBuilder(); |
||||||
|
private Set<Integer> count = new HashSet<Integer>(); |
||||||
|
private int getCount = 1; |
||||||
|
|
||||||
|
private int countRead = 0; |
||||||
|
|
||||||
|
public EhcacheMix() { |
||||||
|
File file = POITempFile.createCacheTmpFile(); |
||||||
|
PersistentCacheManager persistentCacheManager = CacheManagerBuilder.newCacheManagerBuilder() |
||||||
|
.with(CacheManagerBuilder.persistence(file)) |
||||||
|
.withCache("cache", CacheConfigurationBuilder.newCacheConfigurationBuilder(Integer.class, String.class, |
||||||
|
ResourcePoolsBuilder.newResourcePoolsBuilder().heap(20, MemoryUnit.MB).disk(2, MemoryUnit.GB, false))) |
||||||
|
.build(true); |
||||||
|
this.cache = persistentCacheManager.getCache("cache", Integer.class, String.class); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void put(Integer key, String value) { |
||||||
|
sb.append(index++).append(":").append(value).append(","); |
||||||
|
if (index != 0 && index % BATCH == 0) { |
||||||
|
int key1 = index / BATCH; |
||||||
|
cache.put(key1, sb.toString()); |
||||||
|
// LOGGER.info("put:key:{},{}", key1, sb.toString());
|
||||||
|
sb = new StringBuilder(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String get(Integer key) { |
||||||
|
int route = key / BATCH; |
||||||
|
route++; |
||||||
|
if (!cacheMap.containsKey(route)) { |
||||||
|
Map<Integer, String> map = new HashMap<Integer, String>(10000 / 3 * 4 + 1); |
||||||
|
String s = cache.get(route); |
||||||
|
String[] values = s.split(","); |
||||||
|
for (String value : values) { |
||||||
|
String[] vv = value.split(":"); |
||||||
|
map.put(Integer.valueOf(vv[0]), vv[1]); |
||||||
|
} |
||||||
|
cacheMap.put(route, map); |
||||||
|
expire.put(expirekey++, route); |
||||||
|
} |
||||||
|
count.add(route); |
||||||
|
|
||||||
|
if (getCount++ % 1000 == 0) { |
||||||
|
Iterator<Map.Entry<Integer, Map<Integer, String>>> iterator = cacheMap.entrySet().iterator(); |
||||||
|
// LOGGER.info("size:{}", cacheMap.size());
|
||||||
|
while (iterator.hasNext()) { |
||||||
|
Map.Entry<Integer, Map<Integer, String>> entry = iterator.next(); |
||||||
|
if (!count.contains(entry.getKey())) { |
||||||
|
// LOGGER.info("route:{},remove", entry.getKey());
|
||||||
|
iterator.remove(); |
||||||
|
Iterator<Map.Entry<Integer, Integer>> ex = expire.entrySet().iterator(); |
||||||
|
while (ex.hasNext()) { |
||||||
|
Map.Entry<Integer, Integer> e = ex.next(); |
||||||
|
if (e.getValue().equals(entry.getKey())) { |
||||||
|
ex.remove(); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
count.clear(); |
||||||
|
} |
||||||
|
|
||||||
|
if (expire.size() > 10) { |
||||||
|
int value1 = expire.firstEntry().getValue(); |
||||||
|
int key1 = expire.firstEntry().getKey(); |
||||||
|
cacheMap.remove(value1); |
||||||
|
expire.remove(key1); |
||||||
|
} |
||||||
|
|
||||||
|
return cacheMap.get(route).get(key); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void finish() { |
||||||
|
if (StringUtils.isEmpty(sb.toString())) { |
||||||
|
return; |
||||||
|
} |
||||||
|
int key1 = index / BATCH; |
||||||
|
if (index % BATCH != 0) { |
||||||
|
key1++; |
||||||
|
} |
||||||
|
|
||||||
|
cache.put(key1, sb.toString()); |
||||||
|
// LOGGER.info("put:key:{},{}", key1 + 1, sb.toString());
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,8 @@ |
|||||||
|
package com.alibaba.excel.event; |
||||||
|
|
||||||
|
/** |
||||||
|
* Interface to listen for processing results |
||||||
|
* |
||||||
|
* @author zhuangjiaju |
||||||
|
*/ |
||||||
|
public interface Listener {} |
@ -0,0 +1,37 @@ |
|||||||
|
package com.alibaba.excel.event; |
||||||
|
|
||||||
|
import com.alibaba.excel.context.AnalysisContext; |
||||||
|
|
||||||
|
/** |
||||||
|
* Interface to listen for read results |
||||||
|
* |
||||||
|
* @author zhuangjiaju |
||||||
|
*/ |
||||||
|
public interface ReadListener<T> extends Listener { |
||||||
|
/** |
||||||
|
* All listeners receive this method when any one Listener does an error report. If an exception is thrown here, the |
||||||
|
* * entire read will terminate. |
||||||
|
* |
||||||
|
* @param exception |
||||||
|
* @param context |
||||||
|
* @throws Exception |
||||||
|
*/ |
||||||
|
void onException(Exception exception, AnalysisContext context) throws Exception; |
||||||
|
|
||||||
|
/** |
||||||
|
* when analysis one row trigger invoke function |
||||||
|
* |
||||||
|
* @param object |
||||||
|
* one row value |
||||||
|
* @param context |
||||||
|
* analysis context |
||||||
|
*/ |
||||||
|
void invoke(T object, AnalysisContext context); |
||||||
|
|
||||||
|
/** |
||||||
|
* if have something to do after all analysis |
||||||
|
* |
||||||
|
* @param context |
||||||
|
*/ |
||||||
|
void doAfterAllAnalysed(AnalysisContext context); |
||||||
|
} |
Loading…
Reference in new issue