Storm中RotatingMap的理解

来源:互联网 发布:腾讯新闻无法连接网络 编辑:程序博客网 时间:2024/06/14 18:28

RotatingMap主要用于storm内部消息超时的处理,在Storm被多处使用,包括:Ack的超时处理以及Spout的pending消息的处理,可以理解为对HashMap的一种重构。
RotatingMap的前身是TimeCacheMap,删除了其中的清理线程以及锁机制。
代码:

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>());//向end加入        }        _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)) {//遍历每一个桶中是否含有这个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;    }    }

RotatingMap可以独立于Storm使用,用于消息超时的处理,并在超时时调用实现ExpiredCallback接口时重写的expire()方法对超时的消息进行处理。

在Storm发布版本自带的Join示例中,两个流的聚合中就用到了RotatingMap来存储聚合时要存储的关键字。

0 0
原创粉丝点击