phoenix二級索引源碼閱讀
Phoenix二級索引建立源碼
Phoenix二級索引建立在hbase的coprocess功能,建立索引的時候使用是
二級索引建立過程,索引rowkey的構建是一個數據流,不停在後面追加,最後生成最終的rowkey形式
public byte[] buildRowKey(ValueGetter valueGetter, ImmutableBytesWritable rowKeyPtr, byte[] regionStartKey, byte[] regionEndKey, long ts) { ImmutableBytesWritable ptr = new ImmutableBytesWritable(); //判斷是否是構建本地索引,考慮兩個條件:1.本地索引是否開啟 2.startRK 是否傳進來了 //如果開啟本地索引,則在數據前面添加前綴,判斷startRK是否是region起始startRK,如果是則使用該region的EndRK // 構建數據流對象,對數據進行put
|
如果是本地索引,則在rowkey前加入startrowkey索引
// For local indexes, we must prepend the row key with the start region key // 如果startRK為null,則其實使用的endRK } |
判斷是否有加鹽,如果有,則增加一個標誌位,後面再更改這個標誌位
if (isIndexSalted) {
|
如果在索引視圖id不為null,會在索引rowkey中加入視圖id
if (viewIndexId != null) {
|
判斷是否啟動多租戶,如果啟動多租戶的場景,添加多租戶信息;
if (isMultiTenant) {
|
dataRowKeySchema是數據表的信息,忽略在視圖變量的中常量值,並標記出原表pk的rowkey的offset 和 length,方便後面定位數據表rowkey插入。
for (int i = dataPosOffset; i < dataRowKeySchema.getFieldCount(); i++) {
|
考慮索引的數據的順序,考慮索引的順序等
// 獲取表達式索引,表達式索引默認值都為1,未開啟的時候isNullAble為true Iterator<Expression> expressionIterator = indexedExpressions.iterator(); // nIndexedColumns 的構成是索引列+主鍵 如果是組合索引,則循環多個索引列 // dataPkPosition為-1則表示為表達式索引,否則為屬性索引 // 主鍵pk 走這個分支 // 考慮列值的順序,考慮字節的比較,考慮索引列的順序 // 判斷查詢是否desc,默認為asc。 // 獲取索引列的的數據類型,詳情看後面getIndexColumnDataType函數 //根據數據列返回不同的datatype,判斷該列是否可比較。不可比較的列有decimal,varchar,boolean,Binary // 獲取列是否是逆序的 // 讓不可比較的類型具有可比性 // 按位取異或值,二進制數比較肯定是字典序,從最高位開始比較,直到遇到第一個不一樣的位,這個位上哪個數等於1哪個數就較大。 // 判斷數據是不是一個固定長度的字段,如果不是根據數據的正序逆序添加一個標誌位 } } |
//填充開始的加鹽部分的字節位,規則是根據數據做hash,然後再對nIndexSaltBuckets取余
if (isIndexSalted) {
|
返回所有的生成的rowkey
return indexRowKey.length == length ? indexRowKey : Arrays.copyOf(indexRowKey, length);
|
根據數據列返回不同的datatype,判斷該列是否可比較。不可比較的列有decimal,varchar,boolean,Binary等
// Since we cannot have nullable fixed length in a row key
|
讓數據有可比性
protected static int toBytes(BigDecimal v, byte[] result, final int offset, int length) { |
phoenix二級索引源碼閱讀