/* @param i a position known NOT to hold a stale entry. The
-
scan starts at the element after i.
-
@param n scan control: {@code log2(n)} cells are scanned,
-
unless a stale entry is found, in which case
-
{@code log2(table.length)-1} additional cells are scanned.
-
When called from insertions, this parameter is the number
-
of elements, but when from replaceStaleEntry, it is the
-
table length. (Note: all this could be changed to be either
-
more or less aggressive by weighting n instead of just
-
using straight log n. But this version is simple, fast, and
-
seems to work well.)
-
@return true if any stale entries have been removed.
*/
private boolean cleanSomeSlots(int i, int n) 《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》无偿开源 威信搜索公众号【编程进阶路】 {
boolean removed = false;
Entry[] tab = table;
int len = tab.length;
do {
i = nextIndex(i, len);
Entry e = tab[i];
if (e != null && e.get() == null) {
n = len;
removed = true;
i = expungeStaleEntry(i);
}
} while ( (n >>>= 1) != 0);
return removed;
}
入参:
-
i表示:插入entry的位置i,很显然在上述情况2(table[i]==null)中,entry刚插入后该位置i很显然不是脏entry;
-
参数n
2.1. n的用途
主要用于扫描控制(scan control),从while中是通过n来进行条件判断的说明n就是用来控制扫描趟数(循环次数)的。在扫描过程中,如果没有遇到脏entry就整个扫描过程持续log2(n)次,log2(n)的得来是因为n >>>= 1
,每次n右移一位相当于n除以2。如果在扫描过程中遇到脏entry的话就会令n为当前hash表的长度(n=len
),再扫描log2(n)趟,注意此时n增加无非就是多增加了循环次数从而通过nextIndex往后搜索的范围扩大,示意图如下
按照n的初始值,搜索范围为黑线,当遇到了脏entry,此时n变成了哈希数组的长度(n取值增大),搜索范围log2(n)增大,红线表示。如果在整个搜索过程没遇到脏entry的话,搜索结束,采用这种方式的主要是用于时间效率上的平衡。
2.2. n的取值
如果是在set方法插入新的entry后调用(上述情况2ÿ