/*
* JEF - Copyright 2009-2010 Jiyi (mr.jiyi@gmail.com)
*
* Licensed 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 jef.common;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.LinkedHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import jef.tools.IOUtils;
import jef.tools.StringUtils;
/**
* 用于存放固定大小缓存的Map,线程安全(仅限get,set两个方法)
* @author Administrator
* @param <K>
* @param <V>
*/
public class StringCacheMap extends LinkedHashMap<String, String> {
private static final long serialVersionUID = 2428383992533927687L;
private static final float DEFAULT_LOAD_FACTOR = 1f;
private final int maxCapacity;
private final Lock lock = new ReentrantLock();
private final File folder;
/**
* 构造一个高级缓存Map
* @param size
* @param name
*/
public StringCacheMap(int size,String name) {
super(size, DEFAULT_LOAD_FACTOR, true);
if(name==null)throw new NullPointerException("The input name must not null!");
this.maxCapacity = size;
this.folder=IOUtils.createTempDirectory(name);
}
protected final boolean removeEldestEntry(java.util.Map.Entry<String, String> eldest) {
boolean flag=size() > maxCapacity;
if(flag){
saveEntry(eldest);
}
return flag;
}
@Override
protected void finalize() throws Throwable {
close();
}
private void close() {
if(folder!=null){
IOUtils.deleteAllChildren(folder);
}
this.clear();
}
private void saveEntry(java.util.Map.Entry<String, String> eldest) {
String fileName=StringUtils.toFilename(eldest.getKey(), "_");
fileName=fileName.replace(' ', '.');
try{
File file=new File(folder,fileName);
if(file.exists())return;
IOUtils.saveAsFile(file, Charset.defaultCharset(),eldest.getValue());
}catch(IOException e){
throw new IllegalStateException(e);
}
}
private String loadEntry(Object keyObj) {
String key=String.valueOf(keyObj);
String fileName=StringUtils.toFilename(key, "_");
fileName=fileName.replace(' ', '.');
File file=new File(folder,fileName);
if(file.exists()){
try {
return IOUtils.asString(file, Charset.defaultCharset().name());
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
return null;
}
public String get(Object key) {
try {
lock.lock();
String v= super.get(key);
if(v==null){
v=loadEntry(key);
if(v!=null){
put(String.valueOf(key),v);
}
}
return v;
} finally {
lock.unlock();
}
}
public String put(String key, String value) {
try {
lock.lock();
if(value==null){//不允许插入null值
throw new NullPointerException("The value of "+ String.valueOf(key)+" can not be null!");
}
return super.put(key, value);
} finally {
lock.unlock();
}
}
}