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.
751thread->stats.AddBytes(bytes);752}754void ReadReverse(ThreadState* thread) {755Iterator* iter = db_->NewIterator(ReadOptions());756int i = 0;757int64_t bytes = 0;758for (iter->SeekToLast(); i < reads_ && iter->Valid(); iter->Prev()) {759bytes += iter->key().size() + iter->value().size();760thread->stats.FinishedSingleOp();761++i;762}763delete iter;764thread->stats.AddBytes(bytes);765}767void ReadRandom(ThreadState* thread) {768ReadOptions options;769std::string value;770int found = 0;771for (int i = 0; i < reads_; i++) {772char key[100];773const int k = thread->rand.Next() % FLAGS_num;774snprintf(key, sizeof(key), "%016d", k);775if (db_->Get(options, key, &value).ok()) {776found++;777}778thread->stats.FinishedSingleOp();779}780char msg[100];781snprintf(msg, sizeof(msg), "(%d of %d found)", found, num_);782thread->stats.AddMessage(msg);783}785void ReadMissing(ThreadState* thread) {786ReadOptions options;787std::string value;788for (int i = 0; i < reads_; i++) {789char key[100];790const int k = thread->rand.Next() % FLAGS_num;791snprintf(key, sizeof(key), "%016d.", k);792db_->Get(options, key, &value);793thread->stats.FinishedSingleOp();794}795}797void ReadHot(ThreadState* thread) {798ReadOptions options;799std::string value;800const int range = (FLAGS_num + 99) / 100;801for (int i = 0; i < reads_; i++) {802char key[100];803const int k = thread->rand.Next() % range;804snprintf(key, sizeof(key), "%016d", k);805db_->Get(options, key, &value);806thread->stats.FinishedSingleOp();807}808}810void SeekRandom(ThreadState* thread) {811ReadOptions options;812int found = 0;813for (int i = 0; i < reads_; i++) {814Iterator* iter = db_->NewIterator(options);815char key[100];816const int k = thread->rand.Next() % FLAGS_num;817snprintf(key, sizeof(key), "%016d", k);818iter->Seek(key);819if (iter->Valid() && iter->key() == key) found++;820delete iter;821thread->stats.FinishedSingleOp();822}823char msg[100];824snprintf(msg, sizeof(msg), "(%d of %d found)", found, num_);825thread->stats.AddMessage(msg);826}828void DoDelete(ThreadState* thread, bool seq) {829RandomGenerator gen;830WriteBatch batch;831Status s;832for (int i = 0; i < num_; i += entries_per_batch_) {833batch.Clear();834for (int j = 0; j < entries_per_batch_; j++) {835const int k = seq ? i + j : (thread->rand.Next() % FLAGS_num);836char key[100];837snprintf(key, sizeof(key), "%016d", k);838batch.Delete(key);839thread->stats.FinishedSingleOp();840}841s = db_->Write(write_options_, &batch);842if (!s.ok()) {843fprintf(stderr, "del error: %s\n", s.ToString().c_str());844exit(1);845}846}847}849void DeleteSeq(ThreadState* thread) { DoDelete(thread, true); }851void DeleteRandom(ThreadState* thread) { DoDelete(thread, false); }853void ReadWhileWriting(ThreadState* thread) {854if (thread->tid > 0) {855ReadRandom(thread);856} else {857// Special thread that keeps writing until other threads are done.858RandomGenerator gen;859while (true) {860{861MutexLock l(&thread->shared->mu);862if (thread->shared->num_done + 1 >= thread->shared->num_initialized) {863// Other threads have finished864break;865}866}868const int k = thread->rand.Next() % FLAGS_num;869char key[100];870snprintf(key, sizeof(key), "%016d", k);871Status s = db_->Put(write_options_, key, gen.Generate(value_size_));872if (!s.ok()) {873fprintf(stderr, "put error: %s\n", s.ToString().c_str());874exit(1);875}876}878// Do not count any of the preceding work/delay in stats.879thread->stats.Start();880}881}883void Compact(ThreadState* thread) { db_->CompactRange(nullptr, nullptr); }885void PrintStats(const char* key) {886std::string stats;887if (!db_->GetProperty(key, &stats)) {888stats = "(failed)";889}890fprintf(stdout, "\n%s\n", stats.c_str());891}893static void WriteToFile(void* arg, const char* buf, int n) {894reinterpret_cast<WritableFile*>(arg)->Append(Slice(buf, n));895}897void HeapProfile() {898char fname[100];899snprintf(fname, sizeof(fname), "%s/heap-%04d", FLAGS_db, ++heap_counter_);900WritableFile* file;901Status s = g_env->NewWritableFile(fname, &file);902if (!s.ok()) {903fprintf(stderr, "%s\n", s.ToString().c_str());904return;905}906bool ok = port::GetHeapProfile(WriteToFile, file);907delete file;908if (!ok) {909fprintf(stderr, "heap profiling not supported\n");910g_env->DeleteFile(fname);911}912}913};915} // namespace leveldb917int main(int argc, char** argv) {918FLAGS_write_buffer_size = leveldb::Options().write_buffer_size;919FLAGS_max_file_size = leveldb::Options().max_file_size;920FLAGS_block_size = leveldb::Options().block_size;921FLAGS_open_files = leveldb::Options().max_open_files;922std::string default_db_path;924for (int i = 1; i < argc; i++) {925double d;926int n;927char junk;928if (leveldb::Slice(argv[i]).starts_with("--benchmarks=")) {929FLAGS_benchmarks = argv[i] + strlen("--benchmarks=");930} else if (sscanf(argv[i], "--compression_ratio=%lf%c", &d, &junk) == 1) {931FLAGS_compression_ratio = d;932} else if (sscanf(argv[i], "--histogram=%d%c", &n, &junk) == 1 &&933(n == 0 || n == 1)) {934FLAGS_histogram = n;935} else if (sscanf(argv[i], "--use_existing_db=%d%c", &n, &junk) == 1 &&936(n == 0 || n == 1)) {937FLAGS_use_existing_db = n;938} else if (sscanf(argv[i], "--reuse_logs=%d%c", &n, &junk) == 1 &&939(n == 0 || n == 1)) {940FLAGS_reuse_logs = n;941} else if (sscanf(argv[i], "--num=%d%c", &n, &junk) == 1) {942FLAGS_num = n;943} else if (sscanf(argv[i], "--reads=%d%c", &n, &junk) == 1) {944FLAGS_reads = n;945} else if (sscanf(argv[i], "--threads=%d%c", &n, &junk) == 1) {946FLAGS_threads = n;947} else if (sscanf(argv[i], "--value_size=%d%c", &n, &junk) == 1) {948FLAGS_value_size = n;949} else if (sscanf(argv[i], "--write_buffer_size=%d%c", &n, &junk) == 1) {950FLAGS_write_buffer_size = n;951} else if (sscanf(argv[i], "--max_file_size=%d%c", &n, &junk) == 1) {952FLAGS_max_file_size = n;953} else if (sscanf(argv[i], "--block_size=%d%c", &n, &junk) == 1) {954FLAGS_block_size = n;955} else if (sscanf(argv[i], "--cache_size=%d%c", &n, &junk) == 1) {956FLAGS_cache_size = n;957} else if (sscanf(argv[i], "--bloom_bits=%d%c", &n, &junk) == 1) {958FLAGS_bloom_bits = n;959} else if (sscanf(argv[i], "--open_files=%d%c", &n, &junk) == 1) {960FLAGS_open_files = n;961} else if (strncmp(argv[i], "--db=", 5) == 0) {962FLAGS_db = argv[i] + 5;963} else {964fprintf(stderr, "Invalid flag '%s'\n", argv[i]);965exit(1);966}967}969leveldb::g_env = leveldb::Env::Default();971// Choose a location for the test database if none given with --db=<path>972if (FLAGS_db == nullptr) {973leveldb::g_env->GetTestDirectory(&default_db_path);974default_db_path += "/dbbench";975FLAGS_db = default_db_path.c_str();976}978leveldb::Benchmark benchmark;979benchmark.Run();980return 0;981}
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.