LEVELDB source analysis of the eight: memtable

Source: Internet
Author: User

To read this article, refer to:

LEVELDB Source Analysis One: coding

LEVELDB Source Analysis of the second: comparator

LEVELDB source Analysis of the third: Arena

LEVELDB source analysis of the four: Atomicpointer

LEVELDB source analysis of the Five: skiplist (1)

LEVELDB source analysis of the Six: Skiplist (2)

LEVELDB source analysis of the seven: Random

All KV data in Leveldb is stored in memtable,immutable memtable and sstable, immutable memtable is structurally and memtable exactly the same, except that it is read-only, Write operations are not allowed, while Memtable is allowed to write and read. When the data written by memtable reaches a specified amount of memory, it is automatically converted to immutable memtable, waits for dump to disk, the system automatically generates a new memtable for write operations to write new data, and understands memtable, then immutable         Memtable Nature is a cinch. LEVELDB's memtable provides an operational interface for writing KV data, deleting and reading KV records, but in fact memtable does not have a real delete operation, and the value of deleting a key is implemented as a record insertion in memtable, However, the deletion of the key will be hit, the actual deletion is deferred, will be removed in the subsequent compaction process of this kv. It is important to note that the KV pair in the Leveldb memtable is stored sequentially according to the key size, and when the system is plugged into a new kv, the LEVELDB is to plug the kv into the appropriate position to maintain the key ordering. In fact, Leveldb's memtable class is just an interface class, the real operation is done through the skiplist behind, including insert operations and read operations, so memtable core data structure is a skiplist.

Memtable main function is to Skiplist, arena, comparator combination and management, interface function shielding the bottom operation, the user more elegant.

I. Constructors

Memtable::memtable (const internalkeycomparator& CMP)
    : COMPARATOR_ (CMP),
      refs_ (0),
      table_ ( Comparator_, &arena_) {
}
The constructor initializes the private member variable, Table_ is the skiplist type, &aerna_ is passed as key, and Arena_ is the arena type.

two. Memory Estimation function

size_t Memtable::approximatememoryusage () {return Arena_. Memoryusage (); }
The direct call here is the Memoryusage method of the Arena class, which returns the total size (imprecise) of memory used by the entire memory pool.

three. Add a function

void Memtable::add (SequenceNumber s, ValueType type, const slice& key, const SLI ce& value) {//Format of an entry is concatenation of://Key_size:varint32 of Internal_key.size ()//K EY bytes:char[internal_key.size ()]//Value_size:varint32 of Value.size ()//value Bytes:char[value.size
  ()] size_t key_size = Key.size ();
  size_t val_size = Value.size (); Reference LEVELDB Source Analysis II: Comparator about internal key,//Because internal key consists of User_key, sequence and type three fields, User_key//That is the key here
  , sequence and type are packaged into a uint64_t type of data,//So the length here is key_size+8 size_t internal_key_size = key_size + 8; Reference Leveldb One of the source code analysis: coding, in order to save space, the numbers are encoded storage,//Varintlength method to find out the length of the encoding.
  The composition of Encoded_len is described in the following figure. Const size_t Encoded_len = Varintlength (internal_key_size) + internal_key_size + varintlength (val_size) + Val_
  Size Allocate memory char* BUF = Arena_.
  Allocate (Encoded_len); Encoded internal_key_size, encoded and stored in BUF, p points to internal_key_sizeEnd char* p = EncodeVarint32 (buf, internal_key_size);
  Copy key to BUF, occupy key_size size memcpy (p, Key.data (), key_size);
  p + = key_size;
  The sequence and type are packaged and stored in the BUF, with a size of 8 bytes, and the ENCODEFIXED64 is simply copied (considering the big or small end).
  ENCODEFIXED64 (P, (S << 8) | type);
  p + = 8;
  Encoding val_size, encoded and stored in BUF, p points to the end of val_size p = EncodeVarint32 (P, val_size);
  Copy value to buf, occupying val_size size memcpy (p, Value.data (), val_size);
  Determines whether the amount of memory after storage is equal to the size of the initial calculation assert ((P + val_size)-buf = = Encoded_len); Insert into skiplist in Table_.
Insert (BUF); }
A complete BUF content is shown in the following figure.


four. Get the function

If you can find the value corresponding to key, store the value in the *value parameter, and the return value is true.
If there is a delete identity in this key, a notfound () error is stored in the *status parameter, and the return value is true. Otherwise the return value is false bool Memtable::get (const lookupkey& key, std::string* value, status* s) {//Get Memkey,memkey actually contains KL
  Ength|userkey|tag, which means it contains internal_key_size//and Internal_key Slice Memkey = Key.memtable_key ();
  Table::iterator iter (&table_); Find the node ITER in skiplist greater than or equal to Memkey.
  Seek (Memkey.data ()); If you find this node if (ITER.    Valid ()) {//The structure of a node is as follows//entry format is:///Klength Varint32//UserKey Char[klength]// Tag UInt64//Vlength Varint32//value char[vlength]//Check that it belongs to same user key  . We don't check the//sequence number since the Seek () call above should has skipped//all entries with overly
    Large sequence numbers.
    Const char* Entry = Iter.key ();
	uint32_t key_length; Remove the klength, and point key_ptr to klength after//why add 5. Reference Leveldb One of the source code analysis: Coding const char* KEY_PTR = GeTvarint32ptr (Entry, entry+5, &key_length);
    Compares the UserKey in the UserKey and LookupKey in the node, and if it is equal, the node is found. if (Comparator_.comparator.user_comparator ()->compare (Slice (Key_ptr, key_length-8), Key.user  _key ()) = = 0) {//Get Tag,tag equals (sequence<<8) |type const uint64_t tag = DECODEFIXED64 (Key_ptr + key_length
	  -8); 
          Remove type and determine switch (static_cast<valuetype> (tag & 0xff)) {case Ktypevalue: {//Remove the size and contents of value
          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; }

}
The first parameter to get a function is the LookupKey type, and LookupKey is a helper class that makes it easier to manipulate memtable. Since LookupKey's official notes are particularly detailed, this is not an analysis.


Reference Link: http://www.360doc.com/content/14/0325/16/15064667_363619194.shtml









Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.