Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1// Copyright (c) 2011 The LevelDB Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file. See the AUTHORS file for names of contributors.5#include "db/version_edit.h"7#include "db/version_set.h"8#include "util/coding.h"10namespace leveldb {12// Tag numbers for serialized VersionEdit. These numbers are written to13// disk and should not be changed.14enum Tag {15kComparator = 1,16kLogNumber = 2,17kNextFileNumber = 3,18kLastSequence = 4,19kCompactPointer = 5,20kDeletedFile = 6,21kNewFile = 7,22// 8 was used for large value refs23kPrevLogNumber = 924};26void VersionEdit::Clear() {27comparator_.clear();28log_number_ = 0;29prev_log_number_ = 0;30last_sequence_ = 0;31next_file_number_ = 0;32has_comparator_ = false;33has_log_number_ = false;34has_prev_log_number_ = false;35has_next_file_number_ = false;36has_last_sequence_ = false;37deleted_files_.clear();38new_files_.clear();39}41void VersionEdit::EncodeTo(std::string* dst) const {42if (has_comparator_) {43PutVarint32(dst, kComparator);44PutLengthPrefixedSlice(dst, comparator_);45}46if (has_log_number_) {47PutVarint32(dst, kLogNumber);48PutVarint64(dst, log_number_);49}50if (has_prev_log_number_) {51PutVarint32(dst, kPrevLogNumber);52PutVarint64(dst, prev_log_number_);53}54if (has_next_file_number_) {55PutVarint32(dst, kNextFileNumber);56PutVarint64(dst, next_file_number_);57}58if (has_last_sequence_) {59PutVarint32(dst, kLastSequence);60PutVarint64(dst, last_sequence_);61}63for (size_t i = 0; i < compact_pointers_.size(); i++) {64PutVarint32(dst, kCompactPointer);65PutVarint32(dst, compact_pointers_[i].first); // level66PutLengthPrefixedSlice(dst, compact_pointers_[i].second.Encode());67}69for (const auto& deleted_file_kvp : deleted_files_) {70PutVarint32(dst, kDeletedFile);71PutVarint32(dst, deleted_file_kvp.first); // level72PutVarint64(dst, deleted_file_kvp.second); // file number73}75for (size_t i = 0; i < new_files_.size(); i++) {76const FileMetaData& f = new_files_[i].second;77PutVarint32(dst, kNewFile);78PutVarint32(dst, new_files_[i].first); // level79PutVarint64(dst, f.number);80PutVarint64(dst, f.file_size);81PutLengthPrefixedSlice(dst, f.smallest.Encode());82PutLengthPrefixedSlice(dst, f.largest.Encode());83}84}86static bool GetInternalKey(Slice* input, InternalKey* dst) {87Slice str;88if (GetLengthPrefixedSlice(input, &str)) {89return dst->DecodeFrom(str);90} else {91return false;92}93}95static bool GetLevel(Slice* input, int* level) {96uint32_t v;97if (GetVarint32(input, &v) && v < config::kNumLevels) {98*level = v;99return true;100} else {101return false;102}103}105Status VersionEdit::DecodeFrom(const Slice& src) {106Clear();107Slice input = src;108const char* msg = nullptr;109uint32_t tag;111// Temporary storage for parsing112int level;113uint64_t number;114FileMetaData f;115Slice str;116InternalKey key;118while (msg == nullptr && GetVarint32(&input, &tag)) {119switch (tag) {120case kComparator:121if (GetLengthPrefixedSlice(&input, &str)) {122comparator_ = str.ToString();123has_comparator_ = true;124} else {125msg = "comparator name";126}127break;129case kLogNumber:130if (GetVarint64(&input, &log_number_)) {131has_log_number_ = true;132} else {133msg = "log number";134}135break;137case kPrevLogNumber:138if (GetVarint64(&input, &prev_log_number_)) {139has_prev_log_number_ = true;140} else {141msg = "previous log number";142}143break;145case kNextFileNumber:146if (GetVarint64(&input, &next_file_number_)) {147has_next_file_number_ = true;148} else {149msg = "next file number";150}151break;153case kLastSequence:154if (GetVarint64(&input, &last_sequence_)) {155has_last_sequence_ = true;156} else {157msg = "last sequence number";158}159break;161case kCompactPointer:162if (GetLevel(&input, &level) && GetInternalKey(&input, &key)) {163compact_pointers_.push_back(std::make_pair(level, key));164} else {165msg = "compaction pointer";166}167break;169case kDeletedFile:170if (GetLevel(&input, &level) && GetVarint64(&input, &number)) {171deleted_files_.insert(std::make_pair(level, number));172} else {173msg = "deleted file";174}175break;177case kNewFile:178if (GetLevel(&input, &level) && GetVarint64(&input, &f.number) &&179GetVarint64(&input, &f.file_size) &&180GetInternalKey(&input, &f.smallest) &&181GetInternalKey(&input, &f.largest)) {182new_files_.push_back(std::make_pair(level, f));183} else {184msg = "new-file entry";185}186break;188default:189msg = "unknown tag";190break;191}192}194if (msg == nullptr && !input.empty()) {195msg = "invalid tag";196}198Status result;199if (msg != nullptr) {200result = Status::Corruption("VersionEdit", msg);201}202return result;203}205std::string VersionEdit::DebugString() const {206std::string r;207r.append("VersionEdit {");208if (has_comparator_) {209r.append("\n Comparator: ");210r.append(comparator_);211}212if (has_log_number_) {213r.append("\n LogNumber: ");214AppendNumberTo(&r, log_number_);215}216if (has_prev_log_number_) {217r.append("\n PrevLogNumber: ");218AppendNumberTo(&r, prev_log_number_);219}220if (has_next_file_number_) {221r.append("\n NextFile: ");222AppendNumberTo(&r, next_file_number_);223}224if (has_last_sequence_) {225r.append("\n LastSeq: ");226AppendNumberTo(&r, last_sequence_);227}228for (size_t i = 0; i < compact_pointers_.size(); i++) {229r.append("\n CompactPointer: ");230AppendNumberTo(&r, compact_pointers_[i].first);231r.append(" ");232r.append(compact_pointers_[i].second.DebugString());233}234for (const auto& deleted_files_kvp : deleted_files_) {235r.append("\n DeleteFile: ");236AppendNumberTo(&r, deleted_files_kvp.first);237r.append(" ");238AppendNumberTo(&r, deleted_files_kvp.second);239}240for (size_t i = 0; i < new_files_.size(); i++) {241const FileMetaData& f = new_files_[i].second;242r.append("\n AddFile: ");243AppendNumberTo(&r, new_files_[i].first);244r.append(" ");245AppendNumberTo(&r, f.number);246r.append(" ");247AppendNumberTo(&r, f.file_size);248r.append(" ");249r.append(f.smallest.DebugString());250r.append(" .. ");
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.