当前位置:网站首页>Application of skiplist in leveldb
Application of skiplist in leveldb
2022-04-23 15:04:00 【Mrpre】
What is jump Watch
Specific reference http://zhangtielei.com/posts/blog-redis-skiplist.html
Leveldb Why use a skip watch
First skiplist As memtable
Data structure of , If light is for storage kv, Then any data structure can be used , image Redis Of dict. however LevelDB There is a characteristic , Namely put 2 A the same key, that 2 Share the same key Will exist at the same time memtable
in , Instead of using new... As people usually understand value Take the old value Replace . That means ,get It is necessary to ensure that what you get is new value Not the old . here , Simple tree There is no guarantee of order .
- Be careful : LevelDB Of delete It won't delete memtable in kv Of , But and put equally , Insert nodes , Mark as yes "delete".
How to ensure the order of jump table
First , Of course, a simple jump table can only handle key In the case of numbers , But users put Of key, Must be random binary , for example “mykey”."mykey" Can't be used as a jump watch key Did you? , Not really . Because you can set the skip table “ Comparison function ” A comparison used instead of numbers .
for example ,Level Specified in the :
mykey > mykeyb
mykey < myke
mykey == mykey
Second, consider how to ensure order .LevelDB in , For each user key All give a seq, It's globally increasing . Simply describe , Deposit in Jump table key, yes “key+seq”, With seq, that “ Comparison function ” In addition to comparing the above users key outside , We need to compare seq, User input at different times key Although the same , however seq Dissimilarity , Naturally, there are different sizes .
mykey$2 > mykey$1
int InternalKeyComparator::Compare(const Slice& akey, const Slice& bkey) const {
// Order by:
// increasing user key (according to user-supplied comparator)
// decreasing sequence number
// decreasing type (though sequence# should be enough to disambiguate)
int r = user_comparator_->Compare(ExtractUserKey(akey), ExtractUserKey(bkey));
if (r == 0) {
const uint64_t anum = DecodeFixed64(akey.data() + akey.size() - 8);
const uint64_t bnum = DecodeFixed64(bkey.data() + bkey.size() - 8);
if (anum > bnum) {
r = -1;
} else if (anum < bnum) {
r = +1;
}
}
return r;
}
Find out how to ensure the latest value
Suppose the user put 了 2 Time "key", however value Different , So the second time put Of "key", Because of his seq Than the first time put Of "key" Of seq Big , natural , In the jump table, the position is in the first "key" after . hypothesis seq Namely 1 and 2, So what's stored in the jump table key by “key$1” “key$2”.
here , user get With this key, It's operated by key Of seq Must be greater than or equal to 2, The assumption is 100( For example, in the middle put Other key, indicating contrast seq Added ).
LevelDB, At this time, you will query in the skip table "key$100". because Of the query key yes “key$100”, A normal jump table must be the result of missing , Because there is only... In the jump table "key$1" and “key$2”.
Let's see how the following query function handles .
iter.Seek(memkey.data())
Perform a search , Only when Skip one of the tables kv When none of them exist ,iter.Valid()
It's just NULL, Other situations ,iter.Valid()
All set up . iter.key()
Saved the previous search "key$100" Small jump table node . And here it is comparator_.comparator.user_comparator()->Compare
This scene .
bool MemTable::Get(const LookupKey& key, std::string* value, Status* s) {
Slice memkey = key.memtable_key();
Table::Iterator iter(&table_);
iter.Seek(memkey.data());
if (iter.Valid()) {
// entry format is:
// klength varint32
// userkey char[klength]
// tag uint64
// vlength varint32
// value char[vlength]
// Check that it belongs to same user key. We do not check the
// sequence number since the Seek() call above should have skipped
// all entries with overly large sequence numbers.
const char* entry = iter.key();
uint32_t key_length;
const char* key_ptr = GetVarint32Ptr(entry, entry+5, &key_length);
if (comparator_.comparator.user_comparator()->Compare(
Slice(key_ptr, key_length - 8),
key.user_key()) == 0) {
// Correct user key
const uint64_t tag = DecodeFixed64(key_ptr + key_length - 8);
switch (static_cast<ValueType>(tag & 0xff)) {
case kTypeValue: {
Slice v = GetLengthPrefixedSlice(key_ptr + key_length);
value->assign(v.data(), v.size());
return true;
}
case kTypeDeletion:
*s = Status::NotFound(Slice());
return true;
}
}
}
return false;
}
In fact, the overall logic is very simple , Is to find a greater than the current seq Of the same "key". It's a search "iter.key()", Or xx$zz
Either or key$yy
, The former , Explain what we are searching for key Not at all , Because it's better than us key The nearest one is actually others key; If the latter , explain key$yy
This seq by yy Is the most recently inserted / Delete the key.
Is it possible The order in which the jump table appears is as follows
“key$1” > “ke$1” > “key$2” > “ke$2”, If so , We search "key$100" when , The previous value may be "ke$2", This causes the search to fail . Of course, reality is impossible ," Comparison function " This is guaranteed . same "key" It must be in accordance with seq Sort of .
summary
That's why we often say LevelDB The data is in order . Just imagine , If image Redis equally , hold kv Stored in the dictionary , Then naturally there is no order . That's why LevelDB Delete as a skip table Node, All operations are in sequence .
版权声明
本文为[Mrpre]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204231409587746.html
边栏推荐
- Async void caused the program to crash
- Detailed explanation of C language knowledge points -- data types and variables [1] - carry counting system
- What is the effect of Zhongfu Jinshi wealth class 29800? Walk with professional investors to make investment easier
- C语言超全学习路线(收藏让你少走弯路)
- Explain TCP's three handshakes in detail
- nuxt项目:全局获取process.env信息
- JS -- realize click Copy function
- UML project example -- UML diagram description of tiktok
- Share 20 tips for ES6 that should not be missed
- Swift: entry of program, swift calls OC@_ silgen_ Name, OC calls swift, dynamic, string, substring
猜你喜欢
Provided by Chengdu control panel design_ It's detailed_ Introduction to the definition, compilation and quotation of single chip microcomputer program header file
The win10 taskbar notification area icon is missing
1n5408-asemi rectifier diode
Tencent has written a few words, Ali has written them all for a month
How does eolink help telecommuting
Five data types of redis
免费在upic中设置OneDrive或Google Drive作为图床
My raspberry PI zero 2W tossing notes record some problems encountered and solutions
We reference My97DatePicker to realize the use of time plug-in
UML learning_ Day2
随机推荐
For 22 years, you didn't know the file contained vulnerabilities?
封面和标题中的关键词怎么写?做自媒体为什么视频没有播放量
Leetcode149 - maximum number of points on a line - Math - hash table
买卖股票的最佳时机系列问题
[untitled]
Provided by Chengdu control panel design_ It's detailed_ Introduction to the definition, compilation and quotation of single chip microcomputer program header file
多语言通信基础 06 go实现grpc的四种数据流模式实现
牛客网数据库SQL实战详细剖析(26-30)
Sword finger offer II 019 Delete at most one character to get palindrome (simple)
PSYNC synchronization of redis source code analysis
Realization of four data flow modes of grpc based on Multilingual Communication
Ffmpeg installation error: NASM / yasm not found or too old Use --disable-x86asm for a clipped build
Practice of unified storage technology of oppo data Lake
Leetcode151 - invert words in string - String - simulation
填充每个节点的下一个右侧节点指针 II [经典层次遍历 | 视为链表 ]
Introduction to Arduino for esp8266 serial port function
LeetCode162-寻找峰值-二分-数组
Comment eolink facilite le télétravail
Thread synchronization, life cycle
Set up an AI team in the game world and start the super parametric multi-agent "chaos fight"