LightWeightGSet的作用用一个数组来存储元素,而且用链表来解决冲突。不能rehash。所以内部数组永远不用改变大小。此类不支持空元素。

此类也不是线程安全的。有两个类型參数。第一个用于查找元素,第二个类型參数必须是第一个类型參数的子类,而且必须实现LinkedElement接口。

/**
* A low memory footprint {@link GSet} implementation,
* which uses an array for storing the elements
* and linked lists for collision resolution.
*
* No rehash will be performed.
* Therefore, the internal array will never be resized.
*
* This class does not support null element.
*
* This class is not thread safe.
*
* @param <K> Key type for looking up the elements
* @param <E> Element type, which must be
* (1) a subclass of K, and
* (2) implementing {@link LinkedElement} interface.
*/

里面各组件都很好理解,唯一不好理解的是Iterator,

public class SetIterator implements Iterator<E> {
/** The starting modification for fail-fast. */
private int iterModification = modification;
/** The current index of the entry array. */
private int index = -1;
private LinkedElement cur = null;//
private LinkedElement next = nextNonemptyEntry();//next总是指向下一个元素,在初始化时就完毕指下第一个元素。 //在调用next()方法之后,next置为空。直到调用 ensureNext()方法。
 private boolean trackModification = true; /** Find the next nonempty entry starting at (index + 1). */
private LinkedElement nextNonemptyEntry() {
for(index++; index < entries.length && entries[index] == null; index++);
return index < entries.length? entries[index]: null;
} private void ensureNext() {
if (trackModification && modification != iterModification) {
throw new ConcurrentModificationException("modification=" + modification
+ " != iterModification = " + iterModification);
}
if (next != null) {
return;
}
if (cur == null) {
return;
}
next = cur.getNext();
if (next == null) {
next = nextNonemptyEntry();
}
} @Override
public boolean hasNext() {
ensureNext();
return next != null;
} @Override
public E next() {
ensureNext();
if (next == null) {
throw new IllegalStateException("There are no more elements");
}
cur = next;
next = null;
return convert(cur);
} @SuppressWarnings("unchecked")
@Override
public void remove() {
ensureNext();
if (cur == null) {
throw new IllegalStateException("There is no current element " +
"to remove");
}
LightWeightGSet.this.remove((K)cur);
iterModification++;
cur = null;
} public void setTrackModification(boolean trackModification) {
this.trackModification = trackModification;
}
}</span>

computeCapacity()是一个工具方法,用于一定比例的内存的容器,能够存储多少对象。

參数,第一个是占最大内存的百分比,第二个是名称。没有什么用,仅仅用作日志输出。

/**
* Let t = percentage of max memory.
* Let e = round(log_2 t).
* Then, we choose capacity = 2^e/(size of reference),
* unless it is outside the close interval [1, 2^30].
*/
public static int computeCapacity(double percentage, String mapName) {
return computeCapacity(Runtime.getRuntime().maxMemory(), percentage,
mapName);
} @VisibleForTesting
static int computeCapacity(long maxMemory, double percentage,
String mapName) {
if (percentage > 100.0 || percentage < 0.0) {
throw new HadoopIllegalArgumentException("Percentage " + percentage
+ " must be greater than or equal to 0 "
+ " and less than or equal to 100");
}
if (maxMemory < 0) {
throw new HadoopIllegalArgumentException("Memory " + maxMemory
+ " must be greater than or equal to 0");
}
if (percentage == 0.0 || maxMemory == 0) {
return 0;
}
//VM detection
//See http://java.sun.com/docs/hotspot/HotSpotFAQ.html#64bit_detection
final String vmBit = System.getProperty("sun.arch.data.model"); //Percentage of max memory
final double percentDivisor = 100.0/percentage;
final double percentMemory = maxMemory/percentDivisor; //compute capacity
/*
具体描写叙述例如以下:e1应该是以2为base的对数。如percentMemory为1024,结果为10。由于Math类不提供以2为base的对数,
所以採用了间接的方法,先求自然对数,再除以2的自然对数。例System.out.println(Math.log(1024)/Math.log(2));结果为10。
+0.5是为了四舍五入。
假设占用内存为1G,则e1为30.
e2的值,假设系统为32位,则减2,由于2,e2为28,c为2的28次方,为256M个对象,每一个对象指针在32位系统中占4字节。总共1G.
假设系统为64位,e2为27,即对象个数为128M,每一个对象指针为8字节。所以共占1G.
*/
 final int e1 = (int)(Math.log(percentMemory)/Math.log(2.0) + 0.5);
    final int e2 = e1 - ("32".equals(vmBit)? 2: 3);
    final int exponent = e2 < 0? 0: e2 > 30? 30: e2;
    final int c = 1 << exponent;     LOG.info("Computing capacity for map " + mapName);
    LOG.info("VM type       = " + vmBit + "-bit");
    LOG.info(percentage + "% max memory "
        + StringUtils.TraditionalBinaryPrefix.long2String(maxMemory, "B", 1)
        + " = "
        + StringUtils.TraditionalBinaryPrefix.long2String((long) percentMemory,
            "B", 1));
    LOG.info("capacity      = 2^" + exponent + " = " + c + " entries");
    return c;
  }

hadoop 2.6.0 LightWeightGSet源码分析的更多相关文章

  1. jQuery 2.0.3 源码分析Sizzle引擎解析原理

    jQuery 2.0.3 源码分析Sizzle引擎 - 解析原理 声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 先来回答博友的提问: 如何解析 div > p + ...

  2. Spark2.1.0之源码分析——事件总线

    阅读提示:阅读本文前,最好先阅读<Spark2.1.0之源码分析——事件总线>.<Spark2.1.0事件总线分析——ListenerBus的继承体系>及<Spark2. ...

  3. jQuery 2.0.3 源码分析 Deferred(最细的实现剖析,带图)

    Deferred的概念请看第一篇 http://www.cnblogs.com/aaronjs/p/3348569.html ******************构建Deferred对象时候的流程图* ...

  4. jQuery 2.0.3 源码分析 Deferred概念

    JavaScript编程几乎总是伴随着异步操作,传统的异步操作会在操作完成之后,使用回调函数传回结果,而回调函数中则包含了后续的工作.这也是造成异步编程困难的主要原因:我们一直习惯于“线性”地编写代码 ...

  5. jQuery 2.0.3 源码分析 事件绑定 - bind/live/delegate/on

    事件(Event)是JavaScript应用跳动的心脏,通过使用JavaScript ,你可以监听特定事件的发生,并规定让某些事件发生以对这些事件做出响应 事件的基础就不重复讲解了,本来是定位源码分析 ...

  6. jQuery 2.0.3 源码分析 事件体系结构

    那么jQuery事件处理机制能帮我们处理那些问题? 毋容置疑首先要解决浏览器事件兼容问题 可以在一个事件类型上添加多个事件处理函数,可以一次添加多个事件类型的事件处理函数 提供了常用事件的便捷方法 支 ...

  7. jQuery 2.0.3 源码分析 Deferrred概念

    转载http://www.cnblogs.com/aaronjs/p/3348569.html JavaScript编程几乎总是伴随着异步操作,传统的异步操作会在操作完成之后,使用回调函数传回结果,而 ...

  8. hadoop自带例子SecondarySort源码分析MapReduce原理

    这里分析MapReduce原理并没用WordCount,目前没用过hadoop也没接触过大数据,感觉,只是感觉,在项目中,如果真的用到了MapReduce那待排序的肯定会更加实用. 先贴上源码 pac ...

  9. jQuery 2.0.3 源码分析core - 整体架构

    拜读一个开源框架,最想学到的就是设计的思想和实现的技巧. 废话不多说,jquery这么多年了分析都写烂了,老早以前就拜读过, 不过这几年都是做移动端,一直御用zepto, 最近抽出点时间把jquery ...

随机推荐

  1. hadoop 使用java操作hdfs

    1.创建目录 import java.io.IOException; import org.apache.hadoop.conf.Configuration; import org.apache.ha ...

  2. Android开发进度02

    1,今日:目标:创建第一个android项目,创建android虚拟机 2,昨天:完成eclipseandroid环境的搭建 3,收获:修改.xml文件,将出错地方解决 4,问题:版本问题

  3. Unity的Json解析<一>--读取Json文件

    本文章由cartzhang编写,转载请注明出处. 所有权利保留. 文章链接:http://blog.csdn.net/cartzhang/article/details/50373558 作者:car ...

  4. php安装redis扩展 windows

    官方php_redis.dll 找了很久,感谢热心的网友,这是php官方的 php_redis.dll http://windows.php.net/downloads/pecl/releases/r ...

  5. WinServer-AD操作常用powershell命令

    powershell 操作AD常用命令 查询AD中默认的密码策略 Get-ADDefaultDomainPasswordPolicy 查询AD中密码永不过期的用户 Get-ADUser -Filter ...

  6. jquery-常用插件集合

    001.弹出消息插件toastr https://github.com/CodeSeven/toastr 002.弹出页面全屏插件 https://github.com/sindresorhus/sc ...

  7. pcap网络抓包 无法import pcap

    坑爹的不知道从哪里看到说仅仅有pcap最多仅仅支持到python2.5,然后又是easy install又是安装pip就是无法成功import pcap... 我的python版本号是2.7.8. s ...

  8. 晋IT分享成长沙龙集锦

    第一期"晋IT"分享成长沙龙于2014年7月19日圆满结束.下面是相关内容整理和第二期预告. 各位伙伴认真的介绍自己,介绍自己的业务,分析自己眼下存在的问题,大家一起探讨,真诚出谋 ...

  9. Android语音播报、后台播报、语音识别

    Android语音播报.后台播报.语音识别 本文介绍使用讯飞语音实现语音播报.语音识别功能. 讯飞开放平台:http://www.xfyun.cn/index.php/default/index 程序 ...

  10. Spark技术在京东智能供应链预测的应用——按照业务进行划分,然后利用scikit learn进行单机训练并预测

    3.3 Spark在预测核心层的应用 我们使用Spark SQL和Spark RDD相结合的方式来编写程序,对于一般的数据处理,我们使用Spark的方式与其他无异,但是对于模型训练.预测这些需要调用算 ...