儲存系統實現-跳躍表實現索引檢索
這一篇是我所實現的一個通過跳躍表的方式進行索引的檢索。跳躍表的基本思路把單步檢索擴充套件到多步檢索,這樣依賴減少檢索的步驟來升效能。
先用一張流程圖來闡述我檢索的步驟。
讀索引整體流程圖:
這裡舉一個具體的例子來說一下檢索的步驟。這裡說一種檢索到的情況,假設整個檔案表10萬條,id是連續自增,檢索id=2312的值
第一步:走快取(這裡是第一次檢索肯定不能命中快取)
第二步:走千步長
1)id=1000,小於2312,繼續
2)id=2000,小於2312,繼續
3) id=3000,大於2312,回退到id=2000的值
第三步:走百步長
1)id=2100,小於2312,繼續
2)id=2200,小於2312,繼續
3)id=2300,小於2312,繼續
4)id=2400,大於2312,回退到id=2300的值
第四步:走十步長
1)id=2310,小於2312,繼續
2)id=2320,大於2312,回退到id=2310的值
第五步:走單步長
1)id=2311,小於2312,繼續
2)id=2312,等於2312,定位到該值,返回資料
從這裡可以看出檢索這樣一個值,最多隻需要11步,如果快取命中的話只需要一步就找到值,而如果順序檢索的話則需要2312步才能檢索到值,這樣檢索效能得到極大的提升。
下面把兩程式碼程式碼給貼出來。
/**
* 先走一級步長,如果id>key,回退,走二級步長,id>key,一步一步走
*
* @param id
* @return
*/
public synchronized DataOffset read(int id) {
DataOffset offset = getPosFromCache(id);
if(offset!=null){
return offset;
}
long len;
try {
len = reader.length();
//如果長度大於兩倍一級步長,先走一級步長
int key = goByStepLevel(len, 0, id, 0, stepLevel_1000);
if (key != 0) {
key = goByStepLevel(len, reader.getFilePointer(), id, 0, stepLevel_100);
if (key != 0) {
key = goByStepLevel(len, reader.getFilePointer(), id, 0, stepLevel_10);
if (key != 0) {
//直接走0級步長
System.out.println("[IndexFileReader.read]key="+key);
key = goByStepLevel(len, reader.getFilePointer(), id, 0, skip);
}
}
}
System.out.println("[IndexFileReader.read]key2="+key);
if (key == 0) {
//拿到偏移量
reader.readInt();
offset = new DataOffset();
offset.setStartPos(reader.readLong());
//offset.setEndPos(reader.readLong());
//byte[] bytes = ByteUtil.longToByte(offset.getStartPos(),offset.getEndPos());
lruCache.put(indexPath + id, offset.getStartPos());
return offset;
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
這個方法是一個私有方法,是一個遞迴方法,走步長的時候通過遞迴走步長。
/**
* @param len
* @param nowStep
* @param id
* @param key
* @param stepLevel
* @return 1:代表值還在後面,0:代表該節點即為值,-1:值在前面
* @throws IOException
*/
private int goByStepLevel(long len, long nowStep, int id, int key, long stepLevel)
throws IOException {
//如果後面的步驟已經小於一級步長
if (len > nowStep + stepLevel) {
//如果值仍然在後面,走一級步長
if (id > key) {
nowStep = nowStep + stepLevel;
reader.seek(nowStep);
//這裡已經讀出一個值了,需要回退
key = reader.readInt();
return goByStepLevel(len, nowStep, id, key, stepLevel);
} else if (id < key) {
//退出,走二級步長
reader.seek(nowStep - stepLevel);
return 1;
} else {
//相等,找到值直接定位到該值
reader.seek(nowStep);
return 0;
}
} else {
//如果值仍然在後面,走二級步長
if (id > key) {
reader.seek(nowStep);
return -1;
} else if (id < key) {
long preStep = nowStep - stepLevel;
if (preStep > 0) {
reader.seek(preStep);
} else {
//如果小於,則直接歸0,走二級步長
reader.seek(0);
}
return 1;
} else {
//相等,如果找到值,直接seek到該偏移
reader.seek(nowStep);
return 0;
}
}
}
總結:這裡跳躍表的實現就寫完了。歡迎大家拍磚
相關文章
- 【轉】跳躍表-原理及Java實現Java
- 儲存系統實現-構建自己的儲存系統(一)
- 儲存系統實現-資料刪除之索引的刪除索引
- 【Java】跳躍表的實現以及用例測試Java
- 實現鍵值對儲存(五):雜湊表實現
- 【Redis】跳躍表原理分析與基本程式碼實現(java)RedisJava
- 儲存系統實現-如何刪除資料
- 儲存系統實現-資料檔案格式
- elasticsearch的實現全文檢索Elasticsearch
- 基於ElasticSearch實現商品的全文檢索檢索Elasticsearch
- php + MongoDB + Sphinx 實現全文檢索PHPMongoDB
- 實現報表資料分庫儲存
- 5分鐘瞭解Redis的內部實現跳躍表(skiplist)Redis
- 如何實現檔案傳輸系統的多儲存
- ElasticSearch 實現分詞全文檢索 - 概述Elasticsearch分詞
- css3實現div簡單跳躍效果CSSS3
- 現代IM系統中訊息推送和儲存架構的實現架構
- 分散式塊儲存系統Ursa的設計與實現分散式
- 使用LocalStorage實現Form表單內容本地儲存ORM
- 如何快速實現高併發短文檢索
- PHP+redis實現超迷你全文檢索PHPRedis
- 作業系統——c++實現頁式虛擬儲存管理作業系統C++
- 資料庫儲存與索引技術(三)LSM樹實現案例資料庫索引
- ElasticSearch 實現分詞全文檢索 - delete-by-queryElasticsearch分詞delete
- 跳錶實現
- vertica 如何實現儲存過程?儲存過程
- InnoDB儲存引擎MVCC實現原理儲存引擎MVC
- 雲端儲存系統的安全威脅的五點表現
- 帶貨直播系統,實現簡單的換頭像並儲存
- 使用Java實現在SQLserver中實現圖片的儲存JavaSQLServer
- 區塊鏈資訊儲存是如何實現安全儲存區塊鏈
- 線性表的順序儲存C++程式碼實現C++
- redis 跳躍表Redis
- Mysql 如何實現全文檢索,關鍵詞跑分MySql
- OpenCV特徵提取與影像檢索實現(附程式碼)OpenCV特徵
- 板橋大人,首頁的google全文檢索如何實現Go
- abp(net core)+easyui+efcore實現倉儲管理系統——展現層實現增刪改查之列表檢視(七)UI
- 自研資料庫CynosDB儲存系統如何實現即時恢復資料庫