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.
1001if (compact->builder->FileSize() >=1002compact->compaction->MaxOutputFileSize()) {1003status = FinishCompactionOutputFile(compact, input);1004if (!status.ok()) {1005break;1006}1007}1008}1010input->Next();1011}1013if (status.ok() && shutting_down_.load(std::memory_order_acquire)) {1014status = Status::IOError("Deleting DB during compaction");1015}1016if (status.ok() && compact->builder != nullptr) {1017status = FinishCompactionOutputFile(compact, input);1018}1019if (status.ok()) {1020status = input->status();1021}1022delete input;1023input = nullptr;1025CompactionStats stats;1026stats.micros = env_->NowMicros() - start_micros - imm_micros;1027for (int which = 0; which < 2; which++) {1028for (int i = 0; i < compact->compaction->num_input_files(which); i++) {1029stats.bytes_read += compact->compaction->input(which, i)->file_size;1030}1031}1032for (size_t i = 0; i < compact->outputs.size(); i++) {1033stats.bytes_written += compact->outputs[i].file_size;1034}1036mutex_.Lock();1037stats_[compact->compaction->level() + 1].Add(stats);1039if (status.ok()) {1040status = InstallCompactionResults(compact);1041}1042if (!status.ok()) {1043RecordBackgroundError(status);1044}1045VersionSet::LevelSummaryStorage tmp;1046Log(options_.info_log, "compacted to: %s", versions_->LevelSummary(&tmp));1047return status;1048}1050namespace {1052struct IterState {1053port::Mutex* const mu;1054Version* const version GUARDED_BY(mu);1055MemTable* const mem GUARDED_BY(mu);1056MemTable* const imm GUARDED_BY(mu);1058IterState(port::Mutex* mutex, MemTable* mem, MemTable* imm, Version* version)1059: mu(mutex), version(version), mem(mem), imm(imm) {}1060};1062static void CleanupIteratorState(void* arg1, void* arg2) {1063IterState* state = reinterpret_cast<IterState*>(arg1);1064state->mu->Lock();1065state->mem->Unref();1066if (state->imm != nullptr) state->imm->Unref();1067state->version->Unref();1068state->mu->Unlock();1069delete state;1070}1072} // anonymous namespace1074Iterator* DBImpl::NewInternalIterator(const ReadOptions& options,1075SequenceNumber* latest_snapshot,1076uint32_t* seed) {1077mutex_.Lock();1078*latest_snapshot = versions_->LastSequence();1080// Collect together all needed child iterators1081std::vector<Iterator*> list;1082list.push_back(mem_->NewIterator());1083mem_->Ref();1084if (imm_ != nullptr) {1085list.push_back(imm_->NewIterator());1086imm_->Ref();1087}1088versions_->current()->AddIterators(options, &list);1089Iterator* internal_iter =1090NewMergingIterator(&internal_comparator_, &list[0], list.size());1091versions_->current()->Ref();1093IterState* cleanup = new IterState(&mutex_, mem_, imm_, versions_->current());1094internal_iter->RegisterCleanup(CleanupIteratorState, cleanup, nullptr);1096*seed = ++seed_;1097mutex_.Unlock();1098return internal_iter;1099}1101Iterator* DBImpl::TEST_NewInternalIterator() {1102SequenceNumber ignored;1103uint32_t ignored_seed;1104return NewInternalIterator(ReadOptions(), &ignored, &ignored_seed);1105}1107int64_t DBImpl::TEST_MaxNextLevelOverlappingBytes() {1108MutexLock l(&mutex_);1109return versions_->MaxNextLevelOverlappingBytes();1110}1112Status DBImpl::Get(const ReadOptions& options, const Slice& key,1113std::string* value) {1114Status s;1115MutexLock l(&mutex_);1116SequenceNumber snapshot;1117if (options.snapshot != nullptr) {1118snapshot =1119static_cast<const SnapshotImpl*>(options.snapshot)->sequence_number();1120} else {1121snapshot = versions_->LastSequence();1122}1124MemTable* mem = mem_;1125MemTable* imm = imm_;1126Version* current = versions_->current();1127mem->Ref();1128if (imm != nullptr) imm->Ref();1129current->Ref();1131bool have_stat_update = false;1132Version::GetStats stats;1134// Unlock while reading from files and memtables1135{1136mutex_.Unlock();1137// First look in the memtable, then in the immutable memtable (if any).1138LookupKey lkey(key, snapshot);1139if (mem->Get(lkey, value, &s)) {1140// Done1141} else if (imm != nullptr && imm->Get(lkey, value, &s)) {1142// Done1143} else {1144s = current->Get(options, lkey, value, &stats);1145have_stat_update = true;1146}1147mutex_.Lock();1148}1150if (have_stat_update && current->UpdateStats(stats)) {1151MaybeScheduleCompaction();1152}1153mem->Unref();1154if (imm != nullptr) imm->Unref();1155current->Unref();1156return s;1157}1159Iterator* DBImpl::NewIterator(const ReadOptions& options) {1160SequenceNumber latest_snapshot;1161uint32_t seed;1162Iterator* iter = NewInternalIterator(options, &latest_snapshot, &seed);1163return NewDBIterator(this, user_comparator(), iter,1164(options.snapshot != nullptr1165? static_cast<const SnapshotImpl*>(options.snapshot)1166->sequence_number()1167: latest_snapshot),1168seed);1169}1171void DBImpl::RecordReadSample(Slice key) {1172MutexLock l(&mutex_);1173if (versions_->current()->RecordReadSample(key)) {1174MaybeScheduleCompaction();1175}1176}1178const Snapshot* DBImpl::GetSnapshot() {1179MutexLock l(&mutex_);1180return snapshots_.New(versions_->LastSequence());1181}1183void DBImpl::ReleaseSnapshot(const Snapshot* snapshot) {1184MutexLock l(&mutex_);1185snapshots_.Delete(static_cast<const SnapshotImpl*>(snapshot));1186}1188// Convenience methods1189Status DBImpl::Put(const WriteOptions& o, const Slice& key, const Slice& val) {1190return DB::Put(o, key, val);1191}1193Status DBImpl::Delete(const WriteOptions& options, const Slice& key) {1194return DB::Delete(options, key);1195}1197Status DBImpl::Write(const WriteOptions& options, WriteBatch* updates) {1198Writer w(&mutex_);1199w.batch = updates;1200w.sync = options.sync;1201w.done = false;1203MutexLock l(&mutex_);1204writers_.push_back(&w);1205while (!w.done && &w != writers_.front()) {1206w.cv.Wait();1207}1208if (w.done) {1209return w.status;1210}1212// May temporarily unlock and wait.1213Status status = MakeRoomForWrite(updates == nullptr);1214uint64_t last_sequence = versions_->LastSequence();1215Writer* last_writer = &w;1216if (status.ok() && updates != nullptr) { // nullptr batch is for compactions1217WriteBatch* write_batch = BuildBatchGroup(&last_writer);1218WriteBatchInternal::SetSequence(write_batch, last_sequence + 1);1219last_sequence += WriteBatchInternal::Count(write_batch);1221// Add to log and apply to memtable. We can release the lock1222// during this phase since &w is currently responsible for logging1223// and protects against concurrent loggers and concurrent writes1224// into mem_.1225{1226mutex_.Unlock();1227status = log_->AddRecord(WriteBatchInternal::Contents(write_batch));1228bool sync_error = false;1229if (status.ok() && options.sync) {1230status = logfile_->Sync();1231if (!status.ok()) {1232sync_error = true;1233}1234}1235if (status.ok()) {1236status = WriteBatchInternal::InsertInto(write_batch, mem_);1237}1238mutex_.Lock();1239if (sync_error) {1240// The state of the log file is indeterminate: the log record we1241// just added may or may not show up when the DB is re-opened.1242// So we force the DB into a mode where all future writes fail.1243RecordBackgroundError(status);1244}1245}1246if (write_batch == tmp_batch_) tmp_batch_->Clear();1248versions_->SetLastSequence(last_sequence);1249}
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.