当写数据的时候,写完log,再写内存,内存指的就是这里的MemTable,整个MemTable是一个skip list结构;
【数据成员介绍】
arena_:一个管理内存的对象;
comparator_:比较器;
refs_:引用次数;
table_:skip list表,数据就是存在这里面;
【方法成员介绍】
void MemTable::Add(SequenceNumber s, ValueType type,const Slice& key,const Slice& value)
作用:增加数据到table_;s代表序列号,type代表是插入还是删除,所以别看名字是add,它包含了删除和添加两种行为,key,value就是要插入的key value;那么把这些数据是怎么放到table_的呢?
首先按照上面的格式,拼装数据到buf,然后调 table_.Insert(buf)插入数据;
bool MemTable::Get(const LookupKey& key, std::string* value, Status* s)
作用:查询key,并将值保存到value,状态保存到s;
首先memkey = key.memtable_key();也就是说查找的时候,又是一种格式,如下:
iter.Seek(memkey.data());找到的是比memkey小于或等于的node->key中最大的,然后再看看用户key的部分是不是相等的,如果相等,说明找到了,再看ValueType是kTypeValue(说明真的找到了),还是kTypeDeletion(说明没找到)
几个值得思考的问题?
1、为什么在Add的时候,把key value拼装在一起作为一个整体,而不是分开?
分开的话,得多一个指针去指向value,这样节省内存,而且放在一起也不影响内存的查询。
2、SequenceNumber有什么用?
快照就是根据这个神奇的数字来实现的,有了这个数字,就可以保证,读到的值就是一定的。
key value sequencenumber
a 1 3
a 2 4
a 3 5
如果指定了sequencenumber=4,那么读到a的值就是2,而不是3;