重构HashTable
package com.atom.util;import j2ee.core.utils.TextUtils;import java.util.ArrayList;import java.util.Collection;import java.util.Enumeration;import java.util.Hashtable;import java.util.List;import java.util.Map;import java.util.Set;import com.atom.memcache.CacheOperate;public class AtsHashtable<K, V> extends Hashtable<K, V>{private String TABLE_FLAG = TextUtils.getUUID();private Hashtable<K,V> outsideMap;private static List<Class> SINGLE_OBJECT = new ArrayList<Class>();static{SINGLE_OBJECT.add(String.class);}{initOutsideMap();}private void initOutsideMap(){outsideMap = (Hashtable<K,V>)getFromOutSide(TABLE_FLAG);if(outsideMap==null){outsideMap = new Hashtable<K,V>();}}public void initOutsideData(String id){Hashtable<K,V> outsideData = (Hashtable<K,V>)getFromOutSide(id);if(outsideData!=null){TABLE_FLAG = id;outsideMap = outsideData;}}@Overridepublic synchronized void clear() {removeFromOutSide(TABLE_FLAG);super.clear();}@Overridepublic synchronized boolean contains(Object value) {return super.contains(value) || this.outsideMap.contains(value);}@Overridepublic synchronized boolean containsKey(Object key) {return super.containsKey(key) || this.outsideMap.containsKey(key);}@Overridepublic boolean containsValue(Object value) {return super.containsValue(value) || this.outsideMap.containsValue(value);}@Overridepublic synchronized Enumeration elements() {return getUniteTable().elements();}@Overridepublic Set entrySet() {return getUniteTable().entrySet();}@Overridepublic synchronized V get(Object key) {V result = super.get(key);result = result==null?outsideMap.get(key):result;return result;}@Overridepublic synchronized boolean isEmpty() {return super.isEmpty() && outsideMap.isEmpty();}@Overridepublic synchronized Enumeration keys() {return getUniteTable().keys();}@Overridepublic Set keySet() {return getUniteTable().keySet();}@Overridepublic synchronized V put(K key, V value) {if(isOutsideObject(value.getClass())){Object o = super.get(TABLE_FLAG);//判断TABLE_FLAG这个key是否放入过自身if(o==null){super.put((K)TABLE_FLAG, (V)outsideMap);}//old memcached好像会直接拷贝对象数据,所以不能像往常session那样操作//putToOutSide();//return outsideMap.put(key, value);//new 将outsideMap填充新数据后再更新memcachedV rtn = outsideMap.put(key,value);putToOutSide();return rtn;}else{return super.put(key, value);}}@Overridepublic synchronized void putAll(Map t) {super.putAll(t);}@Overridepublic synchronized V remove(Object key) {if(this.containsKey(key)){return super.remove(key);}else{//这么删好像会出问题,因为memcached上保存的是TABLE_FLAG这个key//不是要删除的对象的key//old//removeFromOutSide(key);//return outsideMap.remove(key);//newV o = outsideMap.remove(key);//如果没有对象放缓存里了,那么清除缓存if(outsideMap.size()==0){removeFromOutSide(TABLE_FLAG);}else{//否则把删除后的outsideMap放到缓存putToOutSide();}return o;}}@Overridepublic Collection values() {return getUniteTable().values();}private void putToOutSide(){CacheOperate.addByUser(TABLE_FLAG, outsideMap);}private Object getFromOutSide(String key){return CacheOperate.getByUser(key);}private void removeFromOutSide(Object key){CacheOperate.deleteByUser(String.valueOf(key));}private Hashtable<K,V> getUniteTable(){Hashtable<K,V> _ht = new Hashtable<K, V>();//old 会出现死循环错误//_ht.putAll(this);//new 自己手动的模仿putAll放置Set<Map.Entry<K,V>> entrySet = super.entrySet();for (Map.Entry<? extends K, ? extends V> e : entrySet) _ht.put(e.getKey(), e.getValue());_ht.putAll(outsideMap);return _ht;}private boolean isOutsideObject(Object o){return !SINGLE_OBJECT.contains(o);}public String getTableFlag(){return this.TABLE_FLAG;}}