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.
501bool DeleteAnSSTFile() {502std::vector<std::string> filenames;503ASSERT_OK(env_->GetChildren(dbname_, &filenames));504uint64_t number;505FileType type;506for (size_t i = 0; i < filenames.size(); i++) {507if (ParseFileName(filenames[i], &number, &type) && type == kTableFile) {508ASSERT_OK(env_->DeleteFile(TableFileName(dbname_, number)));509return true;510}511}512return false;513}515// Returns number of files renamed.516int RenameLDBToSST() {517std::vector<std::string> filenames;518ASSERT_OK(env_->GetChildren(dbname_, &filenames));519uint64_t number;520FileType type;521int files_renamed = 0;522for (size_t i = 0; i < filenames.size(); i++) {523if (ParseFileName(filenames[i], &number, &type) && type == kTableFile) {524const std::string from = TableFileName(dbname_, number);525const std::string to = SSTTableFileName(dbname_, number);526ASSERT_OK(env_->RenameFile(from, to));527files_renamed++;528}529}530return files_renamed;531}533private:534// Sequence of option configurations to try535enum OptionConfig { kDefault, kReuse, kFilter, kUncompressed, kEnd };537const FilterPolicy* filter_policy_;538int option_config_;539};541TEST(DBTest, Empty) {542do {543ASSERT_TRUE(db_ != nullptr);544ASSERT_EQ("NOT_FOUND", Get("foo"));545} while (ChangeOptions());546}548TEST(DBTest, EmptyKey) {549do {550ASSERT_OK(Put("", "v1"));551ASSERT_EQ("v1", Get(""));552ASSERT_OK(Put("", "v2"));553ASSERT_EQ("v2", Get(""));554} while (ChangeOptions());555}557TEST(DBTest, EmptyValue) {558do {559ASSERT_OK(Put("key", "v1"));560ASSERT_EQ("v1", Get("key"));561ASSERT_OK(Put("key", ""));562ASSERT_EQ("", Get("key"));563ASSERT_OK(Put("key", "v2"));564ASSERT_EQ("v2", Get("key"));565} while (ChangeOptions());566}568TEST(DBTest, ReadWrite) {569do {570ASSERT_OK(Put("foo", "v1"));571ASSERT_EQ("v1", Get("foo"));572ASSERT_OK(Put("bar", "v2"));573ASSERT_OK(Put("foo", "v3"));574ASSERT_EQ("v3", Get("foo"));575ASSERT_EQ("v2", Get("bar"));576} while (ChangeOptions());577}579TEST(DBTest, PutDeleteGet) {580do {581ASSERT_OK(db_->Put(WriteOptions(), "foo", "v1"));582ASSERT_EQ("v1", Get("foo"));583ASSERT_OK(db_->Put(WriteOptions(), "foo", "v2"));584ASSERT_EQ("v2", Get("foo"));585ASSERT_OK(db_->Delete(WriteOptions(), "foo"));586ASSERT_EQ("NOT_FOUND", Get("foo"));587} while (ChangeOptions());588}590TEST(DBTest, GetFromImmutableLayer) {591do {592Options options = CurrentOptions();593options.env = env_;594options.write_buffer_size = 100000; // Small write buffer595Reopen(&options);597ASSERT_OK(Put("foo", "v1"));598ASSERT_EQ("v1", Get("foo"));600// Block sync calls.601env_->delay_data_sync_.store(true, std::memory_order_release);602Put("k1", std::string(100000, 'x')); // Fill memtable.603Put("k2", std::string(100000, 'y')); // Trigger compaction.604ASSERT_EQ("v1", Get("foo"));605// Release sync calls.606env_->delay_data_sync_.store(false, std::memory_order_release);607} while (ChangeOptions());608}610TEST(DBTest, GetFromVersions) {611do {612ASSERT_OK(Put("foo", "v1"));613dbfull()->TEST_CompactMemTable();614ASSERT_EQ("v1", Get("foo"));615} while (ChangeOptions());616}618TEST(DBTest, GetMemUsage) {619do {620ASSERT_OK(Put("foo", "v1"));621std::string val;622ASSERT_TRUE(db_->GetProperty("leveldb.approximate-memory-usage", &val));623int mem_usage = std::stoi(val);624ASSERT_GT(mem_usage, 0);625ASSERT_LT(mem_usage, 5 * 1024 * 1024);626} while (ChangeOptions());627}629TEST(DBTest, GetSnapshot) {630do {631// Try with both a short key and a long key632for (int i = 0; i < 2; i++) {633std::string key = (i == 0) ? std::string("foo") : std::string(200, 'x');634ASSERT_OK(Put(key, "v1"));635const Snapshot* s1 = db_->GetSnapshot();636ASSERT_OK(Put(key, "v2"));637ASSERT_EQ("v2", Get(key));638ASSERT_EQ("v1", Get(key, s1));639dbfull()->TEST_CompactMemTable();640ASSERT_EQ("v2", Get(key));641ASSERT_EQ("v1", Get(key, s1));642db_->ReleaseSnapshot(s1);643}644} while (ChangeOptions());645}647TEST(DBTest, GetIdenticalSnapshots) {648do {649// Try with both a short key and a long key650for (int i = 0; i < 2; i++) {651std::string key = (i == 0) ? std::string("foo") : std::string(200, 'x');652ASSERT_OK(Put(key, "v1"));653const Snapshot* s1 = db_->GetSnapshot();654const Snapshot* s2 = db_->GetSnapshot();655const Snapshot* s3 = db_->GetSnapshot();656ASSERT_OK(Put(key, "v2"));657ASSERT_EQ("v2", Get(key));658ASSERT_EQ("v1", Get(key, s1));659ASSERT_EQ("v1", Get(key, s2));660ASSERT_EQ("v1", Get(key, s3));661db_->ReleaseSnapshot(s1);662dbfull()->TEST_CompactMemTable();663ASSERT_EQ("v2", Get(key));664ASSERT_EQ("v1", Get(key, s2));665db_->ReleaseSnapshot(s2);666ASSERT_EQ("v1", Get(key, s3));667db_->ReleaseSnapshot(s3);668}669} while (ChangeOptions());670}672TEST(DBTest, IterateOverEmptySnapshot) {673do {674const Snapshot* snapshot = db_->GetSnapshot();675ReadOptions read_options;676read_options.snapshot = snapshot;677ASSERT_OK(Put("foo", "v1"));678ASSERT_OK(Put("foo", "v2"));680Iterator* iterator1 = db_->NewIterator(read_options);681iterator1->SeekToFirst();682ASSERT_TRUE(!iterator1->Valid());683delete iterator1;685dbfull()->TEST_CompactMemTable();687Iterator* iterator2 = db_->NewIterator(read_options);688iterator2->SeekToFirst();689ASSERT_TRUE(!iterator2->Valid());690delete iterator2;692db_->ReleaseSnapshot(snapshot);693} while (ChangeOptions());694}696TEST(DBTest, GetLevel0Ordering) {697do {698// Check that we process level-0 files in correct order. The code699// below generates two level-0 files where the earlier one comes700// before the later one in the level-0 file list since the earlier701// one has a smaller "smallest" key.702ASSERT_OK(Put("bar", "b"));703ASSERT_OK(Put("foo", "v1"));704dbfull()->TEST_CompactMemTable();705ASSERT_OK(Put("foo", "v2"));706dbfull()->TEST_CompactMemTable();707ASSERT_EQ("v2", Get("foo"));708} while (ChangeOptions());709}711TEST(DBTest, GetOrderedByLevels) {712do {713ASSERT_OK(Put("foo", "v1"));714Compact("a", "z");715ASSERT_EQ("v1", Get("foo"));716ASSERT_OK(Put("foo", "v2"));717ASSERT_EQ("v2", Get("foo"));718dbfull()->TEST_CompactMemTable();719ASSERT_EQ("v2", Get("foo"));720} while (ChangeOptions());721}723TEST(DBTest, GetPicksCorrectFile) {724do {725// Arrange to have multiple files in a non-level-0 level.726ASSERT_OK(Put("a", "va"));727Compact("a", "b");728ASSERT_OK(Put("x", "vx"));729Compact("x", "y");730ASSERT_OK(Put("f", "vf"));731Compact("f", "g");732ASSERT_EQ("va", Get("a"));733ASSERT_EQ("vf", Get("f"));734ASSERT_EQ("vx", Get("x"));735} while (ChangeOptions());736}738TEST(DBTest, GetDoesNotTriggerSeekCompaction) {739do {740// Arrange for the following to happen:741// * sstable A in level 0742// * nothing in level 1743// * sstable B in level 2744// Seek compaction is disabled in this fork, so repeated reads must745// not change the level layout. A manual compaction must still work.747// Step 1: First place sstables in levels 0 and 2748int compaction_count = 0;749while (NumTableFilesAtLevel(0) == 0 || NumTableFilesAtLevel(2) == 0) {750ASSERT_LE(compaction_count, 100) << "could not fill levels 0 and 2";
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.