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 "table/merger.h"7#include "leveldb/comparator.h"8#include "leveldb/iterator.h"9#include "table/iterator_wrapper.h"11namespace leveldb {13namespace {14class MergingIterator : public Iterator {15public:16MergingIterator(const Comparator* comparator, Iterator** children, int n)17: comparator_(comparator),18children_(new IteratorWrapper[n]),19n_(n),20current_(nullptr),21direction_(kForward) {22for (int i = 0; i < n; i++) {23children_[i].Set(children[i]);24}25}27~MergingIterator() override { delete[] children_; }29bool Valid() const override { return (current_ != nullptr); }31void SeekToFirst() override {32for (int i = 0; i < n_; i++) {33children_[i].SeekToFirst();34}35FindSmallest();36direction_ = kForward;37}39void SeekToLast() override {40for (int i = 0; i < n_; i++) {41children_[i].SeekToLast();42}43FindLargest();44direction_ = kReverse;45}47void Seek(const Slice& target) override {48for (int i = 0; i < n_; i++) {49children_[i].Seek(target);50}51FindSmallest();52direction_ = kForward;53}55void Next() override {56assert(Valid());58// Ensure that all children are positioned after key().59// If we are moving in the forward direction, it is already60// true for all of the non-current_ children since current_ is61// the smallest child and key() == current_->key(). Otherwise,62// we explicitly position the non-current_ children.63if (direction_ != kForward) {64for (int i = 0; i < n_; i++) {65IteratorWrapper* child = &children_[i];66if (child != current_) {67child->Seek(key());68if (child->Valid() &&69comparator_->Compare(key(), child->key()) == 0) {70child->Next();71}72}73}74direction_ = kForward;75}77current_->Next();78FindSmallest();79}81void Prev() override {82assert(Valid());84// Ensure that all children are positioned before key().85// If we are moving in the reverse direction, it is already86// true for all of the non-current_ children since current_ is87// the largest child and key() == current_->key(). Otherwise,88// we explicitly position the non-current_ children.89if (direction_ != kReverse) {90for (int i = 0; i < n_; i++) {91IteratorWrapper* child = &children_[i];92if (child != current_) {93child->Seek(key());94if (child->Valid()) {95// Child is at first entry >= key(). Step back one to be < key()96child->Prev();97} else {98// Child has no entries >= key(). Position at last entry.99child->SeekToLast();100}101}102}103direction_ = kReverse;104}106current_->Prev();107FindLargest();108}110Slice key() const override {111assert(Valid());112return current_->key();113}115Slice value() const override {116assert(Valid());117return current_->value();118}120Status status() const override {121Status status;122for (int i = 0; i < n_; i++) {123status = children_[i].status();124if (!status.ok()) {125break;126}127}128return status;129}131private:132// Which direction is the iterator moving?133enum Direction { kForward, kReverse };135void FindSmallest();136void FindLargest();138// We might want to use a heap in case there are lots of children.139// For now we use a simple array since we expect a very small number140// of children in leveldb.141const Comparator* comparator_;142IteratorWrapper* children_;143int n_;144IteratorWrapper* current_;145Direction direction_;146};148void MergingIterator::FindSmallest() {149IteratorWrapper* smallest = nullptr;150for (int i = 0; i < n_; i++) {151IteratorWrapper* child = &children_[i];152if (child->Valid()) {153if (smallest == nullptr) {154smallest = child;155} else if (comparator_->Compare(child->key(), smallest->key()) < 0) {156smallest = child;157}158}159}160current_ = smallest;161}163void MergingIterator::FindLargest() {164IteratorWrapper* largest = nullptr;165for (int i = n_ - 1; i >= 0; i--) {166IteratorWrapper* child = &children_[i];167if (child->Valid()) {168if (largest == nullptr) {169largest = child;170} else if (comparator_->Compare(child->key(), largest->key()) > 0) {171largest = child;172}173}174}175current_ = largest;176}177} // namespace179Iterator* NewMergingIterator(const Comparator* comparator, Iterator** children,180int n) {181assert(n >= 0);182if (n == 0) {183return NewEmptyIterator();184} else if (n == 1) {185return children[0];186} else {187return new MergingIterator(comparator, children, n);188}189}191} // 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.