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 <stdio.h>6#include <stdlib.h>7#include <sys/types.h>9#include "leveldb/cache.h"10#include "leveldb/db.h"11#include "leveldb/env.h"12#include "leveldb/filter_policy.h"13#include "leveldb/write_batch.h"14#include "port/port.h"15#include "util/crc32c.h"16#include "util/histogram.h"17#include "util/mutexlock.h"18#include "util/random.h"19#include "util/testutil.h"21// Comma-separated list of operations to run in the specified order22// Actual benchmarks:23// fillseq -- write N values in sequential key order in async mode24// fillrandom -- write N values in random key order in async mode25// overwrite -- overwrite N values in random key order in async mode26// fillsync -- write N/100 values in random key order in sync mode27// fill100K -- write N/1000 100K values in random order in async mode28// deleteseq -- delete N keys in sequential order29// deleterandom -- delete N keys in random order30// readseq -- read N times sequentially31// readreverse -- read N times in reverse order32// readrandom -- read N times in random order33// readmissing -- read N missing keys in random order34// readhot -- read N times in random order from 1% section of DB35// seekrandom -- N random seeks36// open -- cost of opening a DB37// crc32c -- repeated crc32c of 4K of data38// Meta operations:39// compact -- Compact the entire DB40// stats -- Print DB stats41// sstables -- Print sstable info42// heapprofile -- Dump a heap profile (if supported by this port)43static const char* FLAGS_benchmarks =44"fillseq,"45"fillsync,"46"fillrandom,"47"overwrite,"48"readrandom,"49"readrandom," // Extra run to allow previous compactions to quiesce50"readseq,"51"readreverse,"52"compact,"53"readrandom,"54"readseq,"55"readreverse,"56"fill100K,"57"crc32c,"58"snappycomp,"59"snappyuncomp,";61// Number of key/values to place in database62static int FLAGS_num = 1000000;64// Number of read operations to do. If negative, do FLAGS_num reads.65static int FLAGS_reads = -1;67// Number of concurrent threads to run.68static int FLAGS_threads = 1;70// Size of each value71static int FLAGS_value_size = 100;73// Arrange to generate values that shrink to this fraction of74// their original size after compression75static double FLAGS_compression_ratio = 0.5;77// Print histogram of operation timings78static bool FLAGS_histogram = false;80// Number of bytes to buffer in memtable before compacting81// (initialized to default value by "main")82static int FLAGS_write_buffer_size = 0;84// Number of bytes written to each file.85// (initialized to default value by "main")86static int FLAGS_max_file_size = 0;88// Approximate size of user data packed per block (before compression.89// (initialized to default value by "main")90static int FLAGS_block_size = 0;92// Number of bytes to use as a cache of uncompressed data.93// Negative means use default settings.94static int FLAGS_cache_size = -1;96// Maximum number of files to keep open at the same time (use default if == 0)97static int FLAGS_open_files = 0;99// Bloom filter bits per key.100// Negative means use default settings.101static int FLAGS_bloom_bits = -1;103// If true, do not destroy the existing database. If you set this104// flag and also specify a benchmark that wants a fresh database, that105// benchmark will fail.106static bool FLAGS_use_existing_db = false;108// If true, reuse existing log/MANIFEST files when re-opening a database.109static bool FLAGS_reuse_logs = false;111// Use the db with the following name.112static const char* FLAGS_db = nullptr;114namespace leveldb {116namespace {117leveldb::Env* g_env = nullptr;119// Helper for quickly generating random data.120class RandomGenerator {121private:122std::string data_;123int pos_;125public:126RandomGenerator() {127// We use a limited amount of data over and over again and ensure128// that it is larger than the compression window (32KB), and also129// large enough to serve all typical value sizes we want to write.130Random rnd(301);131std::string piece;132while (data_.size() < 1048576) {133// Add a short fragment that is as compressible as specified134// by FLAGS_compression_ratio.135test::CompressibleString(&rnd, FLAGS_compression_ratio, 100, &piece);136data_.append(piece);137}138pos_ = 0;139}141Slice Generate(size_t len) {142if (pos_ + len > data_.size()) {143pos_ = 0;144assert(len < data_.size());145}146pos_ += len;147return Slice(data_.data() + pos_ - len, len);148}149};151#if defined(__linux)152static Slice TrimSpace(Slice s) {153size_t start = 0;154while (start < s.size() && isspace(s[start])) {155start++;156}157size_t limit = s.size();158while (limit > start && isspace(s[limit - 1])) {159limit--;160}161return Slice(s.data() + start, limit - start);162}163#endif165static void AppendWithSpace(std::string* str, Slice msg) {166if (msg.empty()) return;167if (!str->empty()) {168str->push_back(' ');169}170str->append(msg.data(), msg.size());171}173class Stats {174private:175double start_;176double finish_;177double seconds_;178int done_;179int next_report_;180int64_t bytes_;181double last_op_finish_;182Histogram hist_;183std::string message_;185public:186Stats() { Start(); }188void Start() {189next_report_ = 100;190hist_.Clear();191done_ = 0;192bytes_ = 0;193seconds_ = 0;194message_.clear();195start_ = finish_ = last_op_finish_ = g_env->NowMicros();196}198void Merge(const Stats& other) {199hist_.Merge(other.hist_);200done_ += other.done_;201bytes_ += other.bytes_;202seconds_ += other.seconds_;203if (other.start_ < start_) start_ = other.start_;204if (other.finish_ > finish_) finish_ = other.finish_;206// Just keep the messages from one thread207if (message_.empty()) message_ = other.message_;208}210void Stop() {211finish_ = g_env->NowMicros();212seconds_ = (finish_ - start_) * 1e-6;213}215void AddMessage(Slice msg) { AppendWithSpace(&message_, msg); }217void FinishedSingleOp() {218if (FLAGS_histogram) {219double now = g_env->NowMicros();220double micros = now - last_op_finish_;221hist_.Add(micros);222if (micros > 20000) {223fprintf(stderr, "long op: %.1f micros%30s\r", micros, "");224fflush(stderr);225}226last_op_finish_ = now;227}229done_++;230if (done_ >= next_report_) {231if (next_report_ < 1000)232next_report_ += 100;233else if (next_report_ < 5000)234next_report_ += 500;235else if (next_report_ < 10000)236next_report_ += 1000;237else if (next_report_ < 50000)238next_report_ += 5000;239else if (next_report_ < 100000)240next_report_ += 10000;241else if (next_report_ < 500000)242next_report_ += 50000;243else244next_report_ += 100000;245fprintf(stderr, "... finished %d ops%30s\r", done_, "");246fflush(stderr);247}248}250void AddBytes(int64_t n) { bytes_ += n; }
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.