欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

重构HashTable

程序员文章站 2022-05-12 10:58:02
...
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;
		}
	}
	
	@Override
	public synchronized void clear() {
		removeFromOutSide(TABLE_FLAG);
		super.clear();
	}

	@Override
	public synchronized boolean contains(Object value) {
		return super.contains(value) || this.outsideMap.contains(value);
	}

	@Override
	public synchronized boolean containsKey(Object key) {
		return super.containsKey(key) || this.outsideMap.containsKey(key);
	}

	@Override
	public boolean containsValue(Object value) {
		return super.containsValue(value) || this.outsideMap.containsValue(value);
	}

	@Override
	public synchronized Enumeration elements() {
		return getUniteTable().elements();
	}

	@Override
	public Set entrySet() {
		return getUniteTable().entrySet();
	}

	@Override
	public synchronized V get(Object key) {
		V result = super.get(key);
		result = result==null?outsideMap.get(key):result;
		return result;
	}

	@Override
	public synchronized boolean isEmpty() {
		return super.isEmpty() && outsideMap.isEmpty();
	}

	@Override
	public synchronized Enumeration keys() {
		return getUniteTable().keys();
	}

	@Override
	public Set keySet() {
		return getUniteTable().keySet();
	}

	@Override
	public 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填充新数据后再更新memcached
			V rtn = outsideMap.put(key,value);
			putToOutSide();
			return rtn;
		}else{
			return super.put(key, value);
		}
	}

	@Override
	public synchronized void putAll(Map t) {
		super.putAll(t);
	}

	@Override
	public 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);
			//new
			V o = outsideMap.remove(key);
			//如果没有对象放缓存里了,那么清除缓存
			if(outsideMap.size()==0){
				removeFromOutSide(TABLE_FLAG);
			}else{
				//否则把删除后的outsideMap放到缓存
				putToOutSide();
			}
			return o;
		}
	}

	@Override
	public 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;
	}
	
}
相关标签: HashTable