So far, basically the main functional components of LEVELDB have been analyzed, how to combine them together to form an efficient and stable database, which is the work of the Dbimpl class and compact process.
To balance the efficiency of reading and writing, the Sstable file is managed hierarchically (level), and the DB has predefined the maximum levels value. The compact is responsible for persisting memtable into sstable and balancing the sstable of each level in the entire DB.
When compaction is executed once, LEVELDB will create a new version based on the current version, and the current version will become a historical version. In Leveldb, version represents a release that includes all the file information in the current disk and in memory. Versionset is a collection of all version, which is a version of the governing body. Of all the version, only one is current.
These two parts of the specific operation or in the source of the fine talk about it.
Static DoubleMaxbytesforlevel (intLevel) {//Note:the result for level zero are not really used since we set //The level-0 compaction threshold based on number of files. Doubleresult =Ten*1048576.0;//Result for both level-0 and Level-1 while(Level >1) {result *=Ten; level--; }returnResult;}Staticuint64_t Maxfilesizeforlevel (intLevel) {returnKtargetfilesize;//We could vary per level to reduce number of files?}
For the maximum size of the sstable file in different level, the ktargetfilesize is a static constant, set to 2 * 1048576.
Version
LEVELDB defines the latest data state after each compact as version, which is the current DB information and the Sstable collection with the latest data state on each level.
classversion{versionset* vset_;//Versionset to which this Version belongs//indicates that the owning versionset,version is the version of the database, and that Versionset is the collection of versionversion* Next_;//Next version in linked listversion* prev_;//Previous version in linked list//Pointer to front and back versions intRefs_;//Number of live refs to this version //List of files per level STD:: vector<FileMetaData*>Files_[config::knumlevels];//All sstable information for each level //Next file to the compact based on seek stats.filemetadata* file_to_compact_;intFile_to_compact_level_;//Documents requiring compact //level that should is compacted next and its compaction score. //Score < 1 means compaction is not strictly needed. These fields //is initialized by Finalize (). DoubleCompaction_score_;intCompaction_level_;}
But because at some point the compact will add or remove some sstable at a certain level, if this time, these sstable are being read, in order to deal with such read and write competition, based on sstable once generated will not change the characteristics, Each version adds a reference count of Refs_, so that more than one version of the DB may exist simultaneously, and they are connected through a chain table. When version has a reference count of 0 and is not currently the latest version, he will be removed from the list, corresponding to the sstable of the version.
Version does not modify its managed sstable file, only the read operation. First look at a structure, Filemetadata structure: Save sstable meta-information.
struct FileMetaData { int refs; int allowed_seeks; // Seeks allowed until compaction uint64_t number; uint64_t file_size; // File size in bytes InternalKey smallest; // Smallest internal key served by table InternalKey largest; // Largest internal key served by table FileMetaData() : refs(0), allowed_seeks(130), file_size(0) { }};
Smallest, largest can help locate the file where target resides. Traverse the Version::file_ container array to find the file where the target keyword resides.
The iterator class Levelfilenumiterator is defined in version, and the file iterator is returned through the Newconcatenatingiterator member function, which is typically used to represent the results of the lookup.
int FindFile(const InternalKeyComparator& icmp, conststd::vector<FileMetaData*>& files, const Slice& key)
is done in a level lookup (using dichotomy), which is called by the function in version for locating the file.
The Somefileoverlapsrange function is used to determine whether the Sstable key range overflows between the Smallest_user_key and Largest_user_key ranges.
bool SomeFileOverlapsRange( const InternalKeyComparator& icmp, bool disjoint_sorted_files, conststd::vector<FileMetaData*>& files, const Slice* smallest_user_key, const Slice* largest_user_key)
Get function, the key query operation within version, first look at the declaration
Status Version::Get(const ReadOptions& options, const LookupKey& k, std::stringvalue, GetStats* stats)
Since Level-0 's sstable is memtable direct dump to disk, so may overlap, and level-0 above all is generated by the compact, there is no overlap, that is, different sstable stored data, the range of key does not intersect, The aim is to improve reading performance. So in the function, level-0 and level-n are treated differently:
level-0: The level-0 filemetadata array is traversed, and the sstable file found Use_key is sorted from new to old
Level-n: The FindFile function is called to process and the result is returned.
When a key is found in a sstable, it goes to the memory cache of the table without it and loads it into memory.
s = vset_->table_cache_->GetSaveValue);
The Get function has a getstats parameter, which is a structure that holds the result of finding a keyword, containing the entry key and value and the sstable information. Leveldb will make a record of each search and update version with the search results.
Version update function
BOOL Version:: UpdateStats(Const getstats&Stats) {Filemetadata*F=Stats.Seek_file;if(f!= NULL) {F -Allowed_seeks--;if(f -Allowed_seeks<= 0 &&File_to_compact_== NULL) {file_to_compact_=F File_to_compact_level_=Stats.Seek_file_level;return true; } }return false;}
If a sstable is frequently queried for access (up to Allowed_seeks times), the level of file_to_compact_,sstable that records the sstable as version will also be followed by the new, file_to_ Compact_level_ = Stats.seek_file_level. This strategy is only part of the LEVELDB strategy to keep the levels-sstables structure in disk, related functions recordreadsample, foreachoverlapping.
Other functions:
Ref, unref is the reference counting feature that solves the read-write competition before. When Refs_ is 0 o'clock, this version can be deleted.
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Version of LEVELDB Learning