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) 2019 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 <cstdint>6#include <cstdlib>7#include <iostream>8#include <memory>9#include <string>10#include <vector>12#include "leveldb/db.h"13#include "leveldb/write_batch.h"14#include "util/testharness.h"16namespace leveldb {18namespace {20// Creates a random number in the range of [0, max).21int GenerateRandomNumber(int max) { return std::rand() % max; }23std::string CreateRandomString(int32_t index) {24static const size_t len = 1024;25char bytes[len];26size_t i = 0;27while (i < 8) {28bytes[i] = 'a' + ((index >> (4 * i)) & 0xf);29++i;30}31while (i < sizeof(bytes)) {32bytes[i] = 'a' + GenerateRandomNumber(26);33++i;34}35return std::string(bytes, sizeof(bytes));36}38} // namespace40class Issue320 {};42TEST(Issue320, Test) {43std::srand(0);45bool delete_before_put = false;46bool keep_snapshots = true;48std::vector<std::unique_ptr<std::pair<std::string, std::string>>> test_map(4910000);50std::vector<Snapshot const*> snapshots(100, nullptr);52DB* db;53Options options;54options.create_if_missing = true;56std::string dbpath = test::TmpDir() + "/leveldb_issue320_test";57ASSERT_OK(DB::Open(options, dbpath, &db));59uint32_t target_size = 10000;60uint32_t num_items = 0;61uint32_t count = 0;62std::string key;63std::string value, old_value;65WriteOptions writeOptions;66ReadOptions readOptions;67while (count < 200000) {68if ((++count % 1000) == 0) {69std::cout << "count: " << count << std::endl;70}72int index = GenerateRandomNumber(test_map.size());73WriteBatch batch;75if (test_map[index] == nullptr) {76num_items++;77test_map[index].reset(new std::pair<std::string, std::string>(78CreateRandomString(index), CreateRandomString(index)));79batch.Put(test_map[index]->first, test_map[index]->second);80} else {81ASSERT_OK(db->Get(readOptions, test_map[index]->first, &old_value));82if (old_value != test_map[index]->second) {83std::cout << "ERROR incorrect value returned by Get" << std::endl;84std::cout << " count=" << count << std::endl;85std::cout << " old value=" << old_value << std::endl;86std::cout << " test_map[index]->second=" << test_map[index]->second87<< std::endl;88std::cout << " test_map[index]->first=" << test_map[index]->first89<< std::endl;90std::cout << " index=" << index << std::endl;91ASSERT_EQ(old_value, test_map[index]->second);92}94if (num_items >= target_size && GenerateRandomNumber(100) > 30) {95batch.Delete(test_map[index]->first);96test_map[index] = nullptr;97--num_items;98} else {99test_map[index]->second = CreateRandomString(index);100if (delete_before_put) batch.Delete(test_map[index]->first);101batch.Put(test_map[index]->first, test_map[index]->second);102}103}105ASSERT_OK(db->Write(writeOptions, &batch));107if (keep_snapshots && GenerateRandomNumber(10) == 0) {108int i = GenerateRandomNumber(snapshots.size());109if (snapshots[i] != nullptr) {110db->ReleaseSnapshot(snapshots[i]);111}112snapshots[i] = db->GetSnapshot();113}114}116for (Snapshot const* snapshot : snapshots) {117if (snapshot) {118db->ReleaseSnapshot(snapshot);119}120}122delete db;123DestroyDB(dbpath, options);124}126} // namespace leveldb128int main(int argc, char** argv) { return leveldb::test::RunAllTests(); }
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.