ConcurrentSkipListMap原始碼分析

2022-08-21 15:51:13 字數 2779 閱讀 9009

看一下跳躍表的示意圖,途中藍色的為頭節點,頭節點指向的是普通索引節點

通過上圖可以看到跳躍表的基本結構,下面分析一下普通索引節點和頭節點的原始碼,可以發現頭節點和普通索引節點的區別就是頭節點有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是乙個抽象類,我們需要建立子...