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. http://my.oschina.net/joanfen/blog/160156

    http://my.oschina.net/joanfen/blog/160156 http://code4app.com/ios/iOS7-Sampler/5254b2186803faba0d000 ...

  2. 小学生都能学会的python(函数)

    小学生都能学会的python(函数) 神马是函数 函数: 对功能或者动作的封装 函数的定义 def 函数名(形参列表): 函数体(return) ret = 函数名(实参列表) 函数的返回值 retu ...

  3. 小学生绞尽脑汁也学不会的python(异常,约束,MD5加密,日志处理)

    小学生绞尽脑汁也学不会的python(异常,约束,MD5加密,日志处理) 异常处理(处理) 1.产生异常.raise 异常类(),抛出异常2. 处理异常: try: xxxxx # 尝试执行的代码. ...

  4. C# 发布APP修改APP图标以及名称

    很多时候,我们用C#编程后,都要对我们的上位机生成的图标跟名字进行修改,下面我就 VS2015 怎么修改做个说明. 1.打开项目属性 2.打开应用程序的属性界面,对相应的地方进行修改就可以了 3.修改 ...

  5. Apache Mahout 0.9、10.1、11. CardinalityException: Required cardinality 60 but got 29

      我们可以使用Apache Mahout来快速创建高效扩展性又好的机器学习应用.Mahout结合了诸如H2O算法.Scala.Spark和Hadoop MapReduce等模块,为开发人员提供了一个 ...

  6. HDU 3240

    求卡特兰数前N项的和模M. 直接求必定是不可能的,卡特兰数太大了.想了好久,本打算把位数拆成素数相乘,然后记录下各素数的个数计算.可惜,TLE....因为N太大了. 除法必定是要用到逆元的,但分母与M ...

  7. 【IPC进程间通讯之三】内存映射文件Mapping File

    IPC进程间通信+共享内存Mapping                IPC(Inter-Process Communication.进程间通信).         文件映射(Mapping)是一种 ...

  8. POJ 2041 Unreliable Message

    简单模拟.依照题意处理一下字符串就可以. 应该是写题号写错了,本来我在VirtualJudge是加入的POJ 并查集与生成树的题. #include<cstdio> #include< ...

  9. nyist oj 138 找球号(二)(hash 表+位运算)

    找球号(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:5 描写叙述 在某一国度里流行着一种游戏.游戏规则为:现有一堆球中.每一个球上都有一个整数编号i(0<=i< ...

  10. QT中|Qt::Tool类型窗口自动退出消息循环问题解决(setQuitOnLastWindowClosed必须设置为false,最后一个窗口不显示的时候,程序会退出消息循环)

    为application 设置setQuitOnLastWindowClosed属性,确实为true: 将其显示为false; 退出该应该程序不能调用QDialog的close消息槽,只能调用qApp ...