参考storm中的RotatingMap实现key超时处理

storm0.8.1以后的RotatingMap完全可以独立于storm用来实现hashmap的key超时删除,并调用回调函数

RotatingMap.java:

 

import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.Map.Entry;

/**
 * Expires keys that have not been updated in the configured number of seconds.
 * The algorithm used will take between expirationSecs and
 * expirationSecs * (1 + 1 / (numBuckets-1)) to actually expire the message.
 *
 * get, put, remove, containsKey, and size take O(numBuckets) time to run.
 *
 * The advantage of this design is that the expiration thread only locks the object
 * for O(1) time, meaning the object is essentially always available for gets/puts.
 */
public class RotatingMap<K, V> {
    //this default ensures things expire at most 50% past the expiration time
    private static final int DEFAULT_NUM_BUCKETS = 3;

    public static interface ExpiredCallback<K, V> {
        public void expire(K key, V val);
    }

    private LinkedList<HashMap<K, V>> _buckets;

    private ExpiredCallback _callback;
    
    public RotatingMap(int numBuckets, ExpiredCallback<K, V> callback) {
        if(numBuckets<2) {
            throw new IllegalArgumentException("numBuckets must be >= 2");
        }
        _buckets = new LinkedList<HashMap<K, V>>();
        for(int i=0; i<numBuckets; i++) {
            _buckets.add(new HashMap<K, V>());
        }

        _callback = callback;
    }

    public RotatingMap(ExpiredCallback<K, V> callback) {
        this(DEFAULT_NUM_BUCKETS, callback);
    }

    public RotatingMap(int numBuckets) {
        this(numBuckets, null);
    }   
    
    public Map<K, V> rotate() {
        Map<K, V> dead = _buckets.removeLast();
        _buckets.addFirst(new HashMap<K, V>());
        if(_callback!=null) {
            for(Entry<K, V> entry: dead.entrySet()) {
                _callback.expire(entry.getKey(), entry.getValue());
            }
        }
        return dead;
    }

    public boolean containsKey(K key) {
        for(HashMap<K, V> bucket: _buckets) {
            if(bucket.containsKey(key)) {
                return true;
            }
        }
        return false;
    }

    public V get(K key) {
        for(HashMap<K, V> bucket: _buckets) {
            if(bucket.containsKey(key)) {
                return bucket.get(key);
            }
        }
        return null;
    }

    public void put(K key, V value) {
        Iterator<HashMap<K, V>> it = _buckets.iterator();
        HashMap<K, V> bucket = it.next();
        bucket.put(key, value);
        while(it.hasNext()) {
            bucket = it.next();
            bucket.remove(key);
        }
    }
    
    
    public Object remove(K key) {
        for(HashMap<K, V> bucket: _buckets) {
            if(bucket.containsKey(key)) {
                return bucket.remove(key);
            }
        }
        return null;
    }

    public int size() {
        int size = 0;
        for(HashMap<K, V> bucket: _buckets) {
            size+=bucket.size();
        }
        return size;
    }    
}


EventHandler.java

public class EventHandler<k, v> implements RotatingMap.ExpiredCallback<k, v>
{

 @Override
 public void expire(Object key, Object val)
 {
  System.out.println("key=" + key + ",val=" + val);
 }

}


 

RotatingMapStarter.java:

import java.sql.Date;
import java.text.SimpleDateFormat;

public class RotatingMapStarter
{
 RotatingMap<String, String> m_rotatingMap = null;
 RotatingMap.ExpiredCallback<String, String> m_eventHandler = null;
 long m_lastRotate = System.currentTimeMillis();
 long m_rotateTime;

 @SuppressWarnings(
 { "unchecked", "rawtypes" })
 public RotatingMapStarter(int n, int rotateTime) // rotateTime :rotate for
              // second
 {
  m_eventHandler = new EventHandler<String, String>();
  m_rotatingMap = new RotatingMap<String, String>(4, m_eventHandler);
  m_lastRotate = System.currentTimeMillis();
  m_rotateTime = 1000L * rotateTime; // millisecond
 }

 public RotatingMap<String, String> getM_rotatingMap()
 {
  return m_rotatingMap;
 }

 public void setM_rotatingMap(RotatingMap<String, String> m_rotatingMap)
 {
  this.m_rotatingMap = m_rotatingMap;
 }

 public void StartConnMonitor()
 {
  Thread thread = new Thread("Server Monitor")
  {
   @SuppressWarnings("static-access")
   public void run()
   {
    while (true)
    {
     try
     {
      Thread.currentThread().sleep(1000);
     }
     catch (InterruptedException e)
     {
      e.printStackTrace();
     }
     
     long now = System.currentTimeMillis();
     if (now - m_lastRotate > m_rotateTime)
     {
      m_rotatingMap.rotate();
      m_lastRotate = now;
      
      
     }
     else
     {
      //System.out.println(now - m_lastRotate);
      SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
      System.out.println(df.format(new Date(now)));// new Date()为获取当前系统时间
     }
    }
   }
  };

  thread.start();
 }

 /**
  * @param args
  */
 public static void main(String[] args)
 {
  RotatingMapStarter rotatingMapStarter = new RotatingMapStarter(4, 10);
  String value = "001";
  String key = "value";
  rotatingMapStarter.getM_rotatingMap().put(key, value);
  rotatingMapStarter.StartConnMonitor();
 }

}



 

 


 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值