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.4//5// WriteBatch::rep_ :=6// sequence: fixed647// count: fixed328// data: record[count]9// record :=10// kTypeValue varstring varstring |11// kTypeDeletion varstring12// varstring :=13// len: varint3214// data: uint8[len]16#include "leveldb/write_batch.h"18#include "db/dbformat.h"19#include "db/memtable.h"20#include "db/write_batch_internal.h"21#include "leveldb/db.h"22#include "util/coding.h"24namespace leveldb {26// WriteBatch header has an 8-byte sequence number followed by a 4-byte count.27static const size_t kHeader = 12;29WriteBatch::WriteBatch() { Clear(); }31WriteBatch::~WriteBatch() = default;33WriteBatch::Handler::~Handler() = default;35void WriteBatch::Clear() {36rep_.clear();37rep_.resize(kHeader);38}40size_t WriteBatch::ApproximateSize() const { return rep_.size(); }42Status WriteBatch::Iterate(Handler* handler) const {43Slice input(rep_);44if (input.size() < kHeader) {45return Status::Corruption("malformed WriteBatch (too small)");46}48input.remove_prefix(kHeader);49Slice key, value;50int found = 0;51while (!input.empty()) {52found++;53char tag = input[0];54input.remove_prefix(1);55switch (tag) {56case kTypeValue:57if (GetLengthPrefixedSlice(&input, &key) &&58GetLengthPrefixedSlice(&input, &value)) {59handler->Put(key, value);60} else {61return Status::Corruption("bad WriteBatch Put");62}63break;64case kTypeDeletion:65if (GetLengthPrefixedSlice(&input, &key)) {66handler->Delete(key);67} else {68return Status::Corruption("bad WriteBatch Delete");69}70break;71default:72return Status::Corruption("unknown WriteBatch tag");73}74}75if (found != WriteBatchInternal::Count(this)) {76return Status::Corruption("WriteBatch has wrong count");77} else {78return Status::OK();79}80}82int WriteBatchInternal::Count(const WriteBatch* b) {83return DecodeFixed32(b->rep_.data() + 8);84}86void WriteBatchInternal::SetCount(WriteBatch* b, int n) {87EncodeFixed32(&b->rep_[8], n);88}90SequenceNumber WriteBatchInternal::Sequence(const WriteBatch* b) {91return SequenceNumber(DecodeFixed64(b->rep_.data()));92}94void WriteBatchInternal::SetSequence(WriteBatch* b, SequenceNumber seq) {95EncodeFixed64(&b->rep_[0], seq);96}98void WriteBatch::Put(const Slice& key, const Slice& value) {99WriteBatchInternal::SetCount(this, WriteBatchInternal::Count(this) + 1);100rep_.push_back(static_cast<char>(kTypeValue));101PutLengthPrefixedSlice(&rep_, key);102PutLengthPrefixedSlice(&rep_, value);103}105void WriteBatch::Delete(const Slice& key) {106WriteBatchInternal::SetCount(this, WriteBatchInternal::Count(this) + 1);107rep_.push_back(static_cast<char>(kTypeDeletion));108PutLengthPrefixedSlice(&rep_, key);109}111void WriteBatch::Append(const WriteBatch& source) {112WriteBatchInternal::Append(this, &source);113}115namespace {116class MemTableInserter : public WriteBatch::Handler {117public:118SequenceNumber sequence_;119MemTable* mem_;121void Put(const Slice& key, const Slice& value) override {122mem_->Add(sequence_, kTypeValue, key, value);123sequence_++;124}125void Delete(const Slice& key) override {126mem_->Add(sequence_, kTypeDeletion, key, Slice());127sequence_++;128}129};130} // namespace132Status WriteBatchInternal::InsertInto(const WriteBatch* b, MemTable* memtable) {133MemTableInserter inserter;134inserter.sequence_ = WriteBatchInternal::Sequence(b);135inserter.mem_ = memtable;136return b->Iterate(&inserter);137}139void WriteBatchInternal::SetContents(WriteBatch* b, const Slice& contents) {140assert(contents.size() >= kHeader);141b->rep_.assign(contents.data(), contents.size());142}144void WriteBatchInternal::Append(WriteBatch* dst, const WriteBatch* src) {145SetCount(dst, Count(dst) + Count(src));146assert(src->rep_.size() >= kHeader);147dst->rep_.append(src->rep_.data() + kHeader, src->rep_.size() - kHeader);148}150} // namespace leveldb
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.