/*** 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源代码分析的更多相关文章

  1. android-plugmgr源代码分析

    android-plugmgr是一个Android插件加载框架,它最大的特点就是对插件不需要进行任何约束.关于这个类库的介绍见作者博客,市面上也有一些插件加载框架,但是感觉没有这个好.在这篇文章中,我 ...

  2. Twitter Storm源代码分析之ZooKeeper中的目录结构

    徐明明博客:Twitter Storm源代码分析之ZooKeeper中的目录结构 我们知道Twitter Storm的所有的状态信息都是保存在Zookeeper里面,nimbus通过在zookeepe ...

  3. 转:SDL2源代码分析

    1:初始化(SDL_Init()) SDL简介 有关SDL的简介在<最简单的视音频播放示例7:SDL2播放RGB/YUV>以及<最简单的视音频播放示例9:SDL2播放PCM>中 ...

  4. 转:RTMPDump源代码分析

    0: 主要函数调用分析 rtmpdump 是一个用来处理 RTMP 流媒体的开源工具包,支持 rtmp://, rtmpt://, rtmpe://, rtmpte://, and rtmps://. ...

  5. 转:ffdshow 源代码分析

    ffdshow神奇的功能:视频播放时显示运动矢量和QP FFDShow可以称得上是全能的解码.编码器.最初FFDShow只是mpeg视频解码器,不过现在他能做到的远不止于此.它能够解码的视频格式已经远 ...

  6. UiAutomator源代码分析之UiAutomatorBridge框架

    上一篇文章<UIAutomator源代码分析之启动和执行>我们描写叙述了uitautomator从命令行执行到载入測试用例执行測试的整个流程.过程中我们也描写叙述了UiAutomatorB ...

  7. MyBatis架构设计及源代码分析系列(一):MyBatis架构

    如果不太熟悉MyBatis使用的请先参见MyBatis官方文档,这对理解其架构设计和源码分析有很大好处. 一.概述 MyBatis并不是一个完整的ORM框架,其官方首页是这么介绍自己 The MyBa ...

  8. hostapd源代码分析(三):管理帧的收发和处理

    hostapd源代码分析(三):管理帧的收发和处理 原文链接:http://blog.csdn.net/qq_21949217/article/details/46004379 这篇文章我来讲解一下h ...

  9. hostapd源代码分析(二):hostapd的工作机制

    [转]hostapd源代码分析(二):hostapd的工作机制 原文链接:http://blog.csdn.net/qq_21949217/article/details/46004433 在我的上一 ...

随机推荐

  1. 流畅的python和cookbook学习笔记(九)

    1.减少可调用对象的参数个数,使用functools.partial冻结参数 使用functools.partial(),可以固定一个或者多个值,减少调用参数. >>> def sp ...

  2. c#之静态构造函数和单例模式

    1.静态构造函数:在创建第一个实例或引用任何静态成员之前,将自动调用静态构造函数来初始化类 public class A { ; : private static A instance_; publi ...

  3. 小白学flask之hello,world

    from flask import Flask app = Flask(__name__) @app.route("/") def hello(): return "He ...

  4. CSS之inline和inline-block

    inline-block 控制台-代码: PS:inline-block是让元素以内联形式存在,也就是不是块级,但是表现起来(又具有块级元素的高度)--也就是可以调高度(margin或者padding ...

  5. cf1043F. Make It One(dp 容斥原理)

    题意 题目链接 给出\(n\)个数,问最少选几个数,使他们的\(gcd = 1\) Sol 好神仙啊qwq. 首先,如果答案存在,那么最多为\(7\)(因为前\(7\)个质数乘起来\(>= 3e ...

  6. css3动画基础详解(@keyframes和animation)

    我们经常会看到CSS3能制作出很炫酷的动画效果,但是自己却只能做一些简单的.原因是对CSS3动画只知其一,不知其二.最近正好有做动画的项目,于是花时间将css3动画做了一个探究之旅,记录在册. 动画是 ...

  7. CSS性能优化新属性:will-change

    ---恢复内容开始--- will-change属性通过告诉浏览器什么属性.什么元素将会发生变化,可以对这些操作进行可能性的优化,由此提高CSS动画的执行效率. 这个属性可以有4个值: auto: 实 ...

  8. JavaScript Event 事件 事件流 事件对象 事件处理程序 回调函数 error和try...catch和throw

    参考资料: 慕课网 DOM事件探秘    js事件对象 处理 事件驱动: JS是采用事件驱动的机制来响应用户操作的,也就是说当用户对某个html元素进行操作的时候,会产生一个事件,该事件会驱动某些函数 ...

  9. java模拟post提交

    package javapost; import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.IOE ...

  10. SQL Server ->> 尝试优化ETL中优化Merge性能

    这几天突发想到在ETL中Merge性能的问题.思路的出发点是Merge到目标表需要扫描的数据太多,而现实情况下,假设应该是只有一小部分会被更新,而且这部分数据也应该是比较新的数据,比方说对于想Fact ...