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 在我的上一 ...
随机推荐
- MyBatis入门篇
一.什么是MyBatis MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改 ...
- sql: Compare Tables
---使用 UNION.INTERSECT 或 EXCEPT 运算符合并的所有查询必须在其目标列表中有相同数目的表达式 select * from BookInfoList --存在不同的 selec ...
- Bzoj1492: [NOI2007]货币兑换Cash(不单调的斜率优化)
题面 传送门 Sol 题目都说了 必然存在一种最优的买卖方案满足: 每次买进操作使用完所有的人民币: 每次卖出操作卖出所有的金券. 设\(f[i]\)表示第\(i\)天可以有的最大钱数 枚举\(j&l ...
- Spring 框架(一)
1 spring框架概述 1.1 什么是spring l Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert ...
- Spring boot配置注意事项
SpringBoot项目的Bean装配默认规则是根据Application类所在的包位置从上往下扫描! “Application类”是指SpringBoot项目入口类.这个类的位置很关键: 如果App ...
- 仿照jQuery进行一些简单的框架封装(欢迎指教~)
(function(window,undefined){ var arr = [], push = arr.push, slice = arr.slice; //首先要做的就是封装一个parseHtm ...
- nodejs + redis/mysql 连接池问题
nodejs + redis/mysql 连接池问题 需不需要连接池 连接池的作用主要是较少每次临时建立连接所带来的开销.初步一看,nodejs运行单线程上,它不能同时使用多个连接,乍一看是不需要连接 ...
- SQL Server 2016 ->> T-SQL新特性
1) TRUNCATE表分区而不是整表 CREATE TABLE dbo.TruncatePartitionTest ( PrtCol INT, Col2 ) ) ON [myPS1](PrtCol) ...
- 遍历查询结果集,update数据
select NULL mykey, * into #mytemp from dbo.DIM_DISTRIBUTOR declare @i int begin ) print @i )) where ...
- Linux 服务器性能问题排查思路
一个基于 Linux 操作系统的服务器运行的同时,也会表征出各种各样参数信息.通常来说运维人员.系统管理员会对这些数据会极为敏感,但是这些参数对于开发者来说也十分重要,尤其当你的程序非正常工作的时候, ...