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 "leveldb/env.h"7#include <algorithm>9#include "port/port.h"10#include "port/thread_annotations.h"11#include "util/mutexlock.h"12#include "util/testharness.h"13#include "util/testutil.h"15namespace leveldb {17static const int kDelayMicros = 100000;19class EnvTest {20public:21EnvTest() : env_(Env::Default()) {}23Env* env_;24};26TEST(EnvTest, ReadWrite) {27Random rnd(test::RandomSeed());29// Get file to use for testing.30std::string test_dir;31ASSERT_OK(env_->GetTestDirectory(&test_dir));32std::string test_file_name = test_dir + "/open_on_read.txt";33WritableFile* writable_file;34ASSERT_OK(env_->NewWritableFile(test_file_name, &writable_file));36// Fill a file with data generated via a sequence of randomly sized writes.37static const size_t kDataSize = 10 * 1048576;38std::string data;39while (data.size() < kDataSize) {40int len = rnd.Skewed(18); // Up to 2^18 - 1, but typically much smaller41std::string r;42test::RandomString(&rnd, len, &r);43ASSERT_OK(writable_file->Append(r));44data += r;45if (rnd.OneIn(10)) {46ASSERT_OK(writable_file->Flush());47}48}49ASSERT_OK(writable_file->Sync());50ASSERT_OK(writable_file->Close());51delete writable_file;53// Read all data using a sequence of randomly sized reads.54SequentialFile* sequential_file;55ASSERT_OK(env_->NewSequentialFile(test_file_name, &sequential_file));56std::string read_result;57std::string scratch;58while (read_result.size() < data.size()) {59int len = std::min<int>(rnd.Skewed(18), data.size() - read_result.size());60scratch.resize(std::max(len, 1)); // at least 1 so &scratch[0] is legal61Slice read;62ASSERT_OK(sequential_file->Read(len, &read, &scratch[0]));63if (len > 0) {64ASSERT_GT(read.size(), 0);65}66ASSERT_LE(read.size(), len);67read_result.append(read.data(), read.size());68}69ASSERT_EQ(read_result, data);70delete sequential_file;71}73TEST(EnvTest, RunImmediately) {74struct RunState {75port::Mutex mu;76port::CondVar cvar{&mu};77bool called = false;79static void Run(void* arg) {80RunState* state = reinterpret_cast<RunState*>(arg);81MutexLock l(&state->mu);82ASSERT_EQ(state->called, false);83state->called = true;84state->cvar.Signal();85}86};88RunState state;89env_->Schedule(&RunState::Run, &state);91MutexLock l(&state.mu);92while (!state.called) {93state.cvar.Wait();94}95}97TEST(EnvTest, RunMany) {98struct RunState {99port::Mutex mu;100port::CondVar cvar{&mu};101int last_id = 0;102};104struct Callback {105RunState* state_; // Pointer to shared state.106const int id_; // Order# for the execution of this callback.108Callback(RunState* s, int id) : state_(s), id_(id) {}110static void Run(void* arg) {111Callback* callback = reinterpret_cast<Callback*>(arg);112RunState* state = callback->state_;114MutexLock l(&state->mu);115ASSERT_EQ(state->last_id, callback->id_ - 1);116state->last_id = callback->id_;117state->cvar.Signal();118}119};121RunState state;122Callback callback1(&state, 1);123Callback callback2(&state, 2);124Callback callback3(&state, 3);125Callback callback4(&state, 4);126env_->Schedule(&Callback::Run, &callback1);127env_->Schedule(&Callback::Run, &callback2);128env_->Schedule(&Callback::Run, &callback3);129env_->Schedule(&Callback::Run, &callback4);131MutexLock l(&state.mu);132while (state.last_id != 4) {133state.cvar.Wait();134}135}137struct State {138port::Mutex mu;139port::CondVar cvar{&mu};141int val GUARDED_BY(mu);142int num_running GUARDED_BY(mu);144State(int val, int num_running) : val(val), num_running(num_running) {}145};147static void ThreadBody(void* arg) {148State* s = reinterpret_cast<State*>(arg);149s->mu.Lock();150s->val += 1;151s->num_running -= 1;152s->cvar.Signal();153s->mu.Unlock();154}156TEST(EnvTest, StartThread) {157State state(0, 3);158for (int i = 0; i < 3; i++) {159env_->StartThread(&ThreadBody, &state);160}162MutexLock l(&state.mu);163while (state.num_running != 0) {164state.cvar.Wait();165}166ASSERT_EQ(state.val, 3);167}169TEST(EnvTest, TestOpenNonExistentFile) {170// Write some test data to a single file that will be opened |n| times.171std::string test_dir;172ASSERT_OK(env_->GetTestDirectory(&test_dir));174std::string non_existent_file = test_dir + "/non_existent_file";175ASSERT_TRUE(!env_->FileExists(non_existent_file));177RandomAccessFile* random_access_file;178Status status =179env_->NewRandomAccessFile(non_existent_file, &random_access_file);180ASSERT_TRUE(status.IsNotFound());182SequentialFile* sequential_file;183status = env_->NewSequentialFile(non_existent_file, &sequential_file);184ASSERT_TRUE(status.IsNotFound());185}187TEST(EnvTest, ReopenWritableFile) {188std::string test_dir;189ASSERT_OK(env_->GetTestDirectory(&test_dir));190std::string test_file_name = test_dir + "/reopen_writable_file.txt";191env_->DeleteFile(test_file_name);193WritableFile* writable_file;194ASSERT_OK(env_->NewWritableFile(test_file_name, &writable_file));195std::string data("hello world!");196ASSERT_OK(writable_file->Append(data));197ASSERT_OK(writable_file->Close());198delete writable_file;200ASSERT_OK(env_->NewWritableFile(test_file_name, &writable_file));201data = "42";202ASSERT_OK(writable_file->Append(data));203ASSERT_OK(writable_file->Close());204delete writable_file;206ASSERT_OK(ReadFileToString(env_, test_file_name, &data));207ASSERT_EQ(std::string("42"), data);208env_->DeleteFile(test_file_name);209}211TEST(EnvTest, ReopenAppendableFile) {212std::string test_dir;213ASSERT_OK(env_->GetTestDirectory(&test_dir));214std::string test_file_name = test_dir + "/reopen_appendable_file.txt";215env_->DeleteFile(test_file_name);217WritableFile* appendable_file;218ASSERT_OK(env_->NewAppendableFile(test_file_name, &appendable_file));219std::string data("hello world!");220ASSERT_OK(appendable_file->Append(data));221ASSERT_OK(appendable_file->Close());222delete appendable_file;224ASSERT_OK(env_->NewAppendableFile(test_file_name, &appendable_file));225data = "42";226ASSERT_OK(appendable_file->Append(data));227ASSERT_OK(appendable_file->Close());228delete appendable_file;230ASSERT_OK(ReadFileToString(env_, test_file_name, &data));231ASSERT_EQ(std::string("hello world!42"), data);232env_->DeleteFile(test_file_name);233}235} // namespace leveldb237int 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.