Jstorm TimeCacheMap源代码分析
/*** Eclipse Class Decompiler plugin, copyright (c) 2016 Chen Chao (cnfree2000@hotmail.com) ***/
package com.alibaba.jstorm.utils; import com.alibaba.jstorm.callback.AsyncLoopRunnable;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicBoolean; public class TimeCacheMap<K, V> implements TimeOutMap<K, V> {
private static final int DEFAULT_NUM_BUCKETS = 3;
private LinkedList<HashMap<K, V>> _buckets;
private final Object _lock;
private Thread _cleaner;
private ExpiredCallback _callback; public TimeCacheMap(int expirationSecs, int numBuckets, ExpiredCallback<K, V> callback) {
this._lock = new Object(); if (numBuckets < 2) {
throw new IllegalArgumentException("numBuckets must be >= 2");
}
this._buckets = new LinkedList();
for (int i = 0; i < numBuckets; ++i) {
this._buckets.add(new HashMap());
} this._callback = callback;
long expirationMillis = expirationSecs * 1000L;
long sleepTime = expirationMillis / (numBuckets - 1);
this._cleaner = new Thread(new Runnable(sleepTime) {
public void run() {
while (!(AsyncLoopRunnable.getShutdown().get())) {
Map dead = null;
JStormUtils.sleepMs(this.val$sleepTime);
synchronized (TimeCacheMap.this._lock) {
dead = (Map) TimeCacheMap.this._buckets.removeLast();
TimeCacheMap.this._buckets.addFirst(new HashMap());
}
if (TimeCacheMap.this._callback != null)
for (Map.Entry entry : dead.entrySet())
TimeCacheMap.this._callback.expire(entry.getKey(), entry.getValue());
}
}
});
this._cleaner.setDaemon(true);
this._cleaner.start();
} public TimeCacheMap(int expirationSecs, ExpiredCallback<K, V> callback) {
this(expirationSecs, 3, callback);
} public TimeCacheMap(int expirationSecs) {
this(expirationSecs, 3);
} public TimeCacheMap(int expirationSecs, int numBuckets) {
this(expirationSecs, numBuckets, null);
} public boolean containsKey(K key) {
synchronized (this._lock) {
for (HashMap bucket : this._buckets) {
if (bucket.containsKey(key)) {
return true;
}
}
return false;
}
} public V get(K key) {
synchronized (this._lock) {
for (HashMap bucket : this._buckets) {
if (bucket.containsKey(key)) {
return bucket.get(key);
}
}
return null;
}
} public void putHead(K key, V value) {
synchronized (this._lock) {
((HashMap) this._buckets.getFirst()).put(key, value);
}
} public void put(K key, V value) {
synchronized (this._lock) {
Iterator it = this._buckets.iterator();
HashMap bucket = (HashMap) it.next();
bucket.put(key, value);
while (it.hasNext()) {
bucket = (HashMap) it.next();
bucket.remove(key);
}
}
} public Object remove(K key) {
synchronized (this._lock) {
for (HashMap bucket : this._buckets) {
if (bucket.containsKey(key)) {
return bucket.remove(key);
}
}
return null;
}
} public int size() {
synchronized (this._lock) {
int size = 0;
for (HashMap bucket : this._buckets) {
size += bucket.size();
}
return size;
}
} public void cleanup() {
this._cleaner.interrupt();
} public Map<K, V> buildMap() {
Map ret = new HashMap();
synchronized (this._lock) {
for (HashMap bucket : this._buckets) {
ret.putAll(bucket);
}
return ret;
}
}
}
总体思路,linkList下默认带有3个hashmap,每次新加数据加到第一个hashmap内,同时删除后面map同样key的数据,里面一个线程定时清理过期数据,sleep后,删除list最后一个hashmap,新建一个空的hashmap放到linklist第一个的位置,下一个时间窗口添加数据就添加到该hashmap内,原有的第一个hashmap变为第二个,原有的第二个变为第三个,下次删除就清除最后一个hashmap, 依次循环。
sleep时间 如果默认为30秒参数, 根据代码公式,计算窗口移动时间为15秒, 第一个窗口最后一秒添加数据,30秒后删除,如果是第一个窗口第一秒添加,则需要45秒后删除
long expirationMillis = expirationSecs * 1000L;
long sleepTime = expirationMillis / (numBuckets - 1);
取数据则是遍历list下所有hashmap拿取数据
Jstorm TimeCacheMap源代码分析的更多相关文章
- android-plugmgr源代码分析
android-plugmgr是一个Android插件加载框架,它最大的特点就是对插件不需要进行任何约束.关于这个类库的介绍见作者博客,市面上也有一些插件加载框架,但是感觉没有这个好.在这篇文章中,我 ...
- Twitter Storm源代码分析之ZooKeeper中的目录结构
徐明明博客:Twitter Storm源代码分析之ZooKeeper中的目录结构 我们知道Twitter Storm的所有的状态信息都是保存在Zookeeper里面,nimbus通过在zookeepe ...
- 转:SDL2源代码分析
1:初始化(SDL_Init()) SDL简介 有关SDL的简介在<最简单的视音频播放示例7:SDL2播放RGB/YUV>以及<最简单的视音频播放示例9:SDL2播放PCM>中 ...
- 转:RTMPDump源代码分析
0: 主要函数调用分析 rtmpdump 是一个用来处理 RTMP 流媒体的开源工具包,支持 rtmp://, rtmpt://, rtmpe://, rtmpte://, and rtmps://. ...
- 转:ffdshow 源代码分析
ffdshow神奇的功能:视频播放时显示运动矢量和QP FFDShow可以称得上是全能的解码.编码器.最初FFDShow只是mpeg视频解码器,不过现在他能做到的远不止于此.它能够解码的视频格式已经远 ...
- UiAutomator源代码分析之UiAutomatorBridge框架
上一篇文章<UIAutomator源代码分析之启动和执行>我们描写叙述了uitautomator从命令行执行到载入測试用例执行測试的整个流程.过程中我们也描写叙述了UiAutomatorB ...
- MyBatis架构设计及源代码分析系列(一):MyBatis架构
如果不太熟悉MyBatis使用的请先参见MyBatis官方文档,这对理解其架构设计和源码分析有很大好处. 一.概述 MyBatis并不是一个完整的ORM框架,其官方首页是这么介绍自己 The MyBa ...
- hostapd源代码分析(三):管理帧的收发和处理
hostapd源代码分析(三):管理帧的收发和处理 原文链接:http://blog.csdn.net/qq_21949217/article/details/46004379 这篇文章我来讲解一下h ...
- hostapd源代码分析(二):hostapd的工作机制
[转]hostapd源代码分析(二):hostapd的工作机制 原文链接:http://blog.csdn.net/qq_21949217/article/details/46004433 在我的上一 ...
随机推荐
- idea快捷键、常用设置
代码提示: code completion :ALT + / 选用Eclipse的keymap. 设置代码助手快捷键(keymap-basic) 代码上下行复制(Ctrl + Alt + Down ...
- Javascript之for循环该注意的问题
很多时候我们都用到for循环,而用到for循环部门往往对一个数组进行循环,其中我们很多时候都是这样写的: // 次佳的循环 for (var i = 0; i < myarray.length; ...
- vim命令“=”、“d”、“y”的用法(结合光标移动命令,一些场合会非常方便)
vim有许多命令,网上搜有一堆贴子.文章列举出各种功能的命令. 对于“=”.“d”.“y”,我在无意中发现了它们所具有的相同的一些用法,先举以下三个例子: =nG dnG ynG 其中,n为行号.注意 ...
- maven父子项目
maven搭建父子项目 1.先建立一个父项目,建立项目的时候,选择 Create a simple project 点击 next,填写以下信息 点击finish就可以了. 2.接下来要建立一个子项 ...
- Luogu4234:最小差值生成树
题面 luogu Sol 好久没写\(LCT\) 然而写跪了\(TAT\) 把边从小到大加入森林 如果形成环,就替换最小的边 如果已经是树,更新答案 \(LCT\)维护 # include <b ...
- 洛谷P2831 愤怒的小鸟(状压dp)
题意 题目链接 Sol 这题....我样例没过就A了??..算了,就当是样例卡精度吧.. 直接状压dp一下,\(f[sta]\)表示干掉\(sta\)这个集合里面的鸟的最小操作数 转移的时候判断一下一 ...
- Python爬虫教程-13-爬虫使用cookie爬取登录后的页面(人人网)(下)
Python爬虫教程-13-爬虫使用cookie爬取登录后的页面(下) 自动使用cookie的方法,告别手动拷贝cookie http模块包含一些关于cookie的模块,通过他们我们可以自动的使用co ...
- idea 多项目部署碰到的问题
在使用idea部署多个maven项目的时候,出现了各种坑.一天的时间有一半的时间花在了部署环境.运行环境上.把遇到的坑记录下 1.引入maven的依赖包 当项目多的时候,为了加速项目的开发,习惯性的把 ...
- 基于以太坊的Token开发步骤
Token开发步骤 一.准备工具1.安装以太坊brew tap ethereum/ethereumbrew install ethereum2.node:brew install nodejs3.安装 ...
- 快速替换dll命名空间 z
Step1:使用ildasm将代码反编译成il中间语言. 名字存贮为你想要的名字. Step2:用记事本打开il文件全局替换命名空间. Step3:使用ilasm将il文件编译成dll 按下回车即可生 ...