看一下跳躍表的示意圖,途中藍色的為頭節點,頭節點指向的是普通索引節點
通過上圖可以看到跳躍表的基本結構,下面分析一下普通索引節點和頭節點的原始碼,可以發現頭節點和普通索引節點的區別就是頭節點有level的概念,而普通索引節點沒有
static class index//cas更新右側索引
final boolean casright(indexcmp, indexval)
//判斷當前節點是否是刪除節點
final boolean indexesdeletednode()
//將newsucc節點插入到當前節點與succ節點之間
final boolean link(indexsucc, indexnewsucc)
//刪除succ
final boolean unlink(indexsucc)
private static final sun.misc.unsafe unsafe;
private static final long rightoffset;
static catch (exception e) }}
//頭節點,只有頭節點才有層級概念
static final class headindexextends index
}
public v put(k key, v value)private v doput(k key, v value, boolean onlyifabsent)
//如果b節點被刪除則跳出迴圈
if (b.value == null || v == n)
break;
//如果key大於n節點的key則繼續向後找
if ((c = cpr(cmp, key, n.key)) > 0)
//如果找到了key相等的節點
if (c == 0)
break; //cas競爭失敗則繼續
}// else c < 0; fall through
}//如果後繼節點為null則可以直接新增
z = new node(key, value, n);
//cas設定失敗則跳出內層迴圈,繼續執行
if (!b.casnext(n, z))
break;
//cas成功則跳出外層迴圈
break outer;}}
int rnd = threadlocalrandom.nextsecondaryseed();
//與10000000000000000000000000000001按位與的結果為0,表示最高位和最低位不為1
if ((rnd & 0x80000001) == 0)
else }}
// 找到插入點,並插入資料
splice: for (int insertionlevel = level;;)
//如果key>n.key 則繼續向後查詢
if (c > 0)
}// 表示r為null,即找到該層的最後
//如果是需要插入的層級
if (j == insertionlevel)
//如果到最低層則跳出外層迴圈
if (--insertionlevel == 0)
break splice;
}//如果 --j 大於等於insertlevel則繼續處理下一層
if (--j >= insertionlevel && j < level)
t = t.down;
q = q.down;
r = q.right;}}
}return null;
}
private nodefindpredecessor(object key, comparator super k> cmp)//r節點不是刪除節點則比較key大小,r索引持有的key小於新插入的key則繼續向右移
if (cpr(cmp, key, k) > 0)
}//表示r為null或者r節點持有的資料key大於新插入資料的key
//如果q下一層為null則直接返回q持有的資料節點
if ((d = q.down) == null)
return q.node;
//如果q.down不為null,則向下一層查詢
q = d;
r = d.right;}}
}
public v get(object key)private v doget(object key)
//如果b節點是刪除節點重新開始
if (b.value == null || v == n)
break;
//和n節點的key對比,如果相等則返回值
if ((c = cpr(cmp, key, n.key)) == 0)
//如果小於n節點的key則返回null( 因為key>p.key)
if (c < 0)
break outer;
//否則繼續向後查詢
b = n;
n = f;}}
return null;
}
Cartographer原始碼篇 原始碼分析 1
在安裝編譯cartographer 1.0.0的時候,我們可以看到 主要包括cartorgarpher ros cartographer ceres sover三個部分。其中,ceres solver用於非線性優化,求解最小二乘問題 cartographer ros為ros平台的封裝,獲取感測器資料...
AbstractListView原始碼分析3
normal list that does not indicate choices public static final int choice mode none 0 the list allows up to one choice public static final int choice ...
Android AsyncTask原始碼分析
android中只能在主線程中進行ui操作,如果是其它子執行緒,需要借助非同步訊息處理機制handler。除此之外,還有個非常方便的asynctask類,這個類內部封裝了handler和執行緒池。本文先簡要介紹asynctask的用法,然後分析具體實現。asynctask是乙個抽象類,我們需要建立子...