| 1245 | } |
| 1246 | |
| 1247 | Compaction* VersionSet::PickCompaction() { |
| 1248 | Compaction* c; |
| 1249 | int level; |
| 1250 | |
| 1251 | // We prefer compactions triggered by too much data in a level over |
| 1252 | // the compactions triggered by seeks. |
| 1253 | const bool size_compaction = (current_->compaction_score_ >= 1); |
| 1254 | const bool seek_compaction = (current_->file_to_compact_ != nullptr); |
| 1255 | if (size_compaction) { |
| 1256 | level = current_->compaction_level_; |
| 1257 | assert(level >= 0); |
| 1258 | assert(level + 1 < config::kNumLevels); |
| 1259 | c = new Compaction(options_, level); |
| 1260 | |
| 1261 | // Pick the first file that comes after compact_pointer_[level] |
| 1262 | for (size_t i = 0; i < current_->files_[level].size(); i++) { |
| 1263 | FileMetaData* f = current_->files_[level][i]; |
| 1264 | if (compact_pointer_[level].empty() || |
| 1265 | icmp_.Compare(f->largest.Encode(), compact_pointer_[level]) > 0) { |
| 1266 | c->inputs_[0].push_back(f); |
| 1267 | break; |
| 1268 | } |
| 1269 | } |
| 1270 | if (c->inputs_[0].empty()) { |
| 1271 | // Wrap-around to the beginning of the key space |
| 1272 | c->inputs_[0].push_back(current_->files_[level][0]); |
| 1273 | } |
| 1274 | } else if (seek_compaction) { |
| 1275 | level = current_->file_to_compact_level_; |
| 1276 | c = new Compaction(options_, level); |
| 1277 | c->inputs_[0].push_back(current_->file_to_compact_); |
| 1278 | } else { |
| 1279 | return nullptr; |
| 1280 | } |
| 1281 | |
| 1282 | c->input_version_ = current_; |
| 1283 | c->input_version_->Ref(); |
| 1284 | |
| 1285 | // Files in level 0 may overlap each other, so pick up all overlapping ones |
| 1286 | if (level == 0) { |
| 1287 | InternalKey smallest, largest; |
| 1288 | GetRange(c->inputs_[0], &smallest, &largest); |
| 1289 | // Note that the next call will discard the file we placed in |
| 1290 | // c->inputs_[0] earlier and replace it with an overlapping set |
| 1291 | // which will include the picked file. |
| 1292 | current_->GetOverlappingInputs(0, &smallest, &largest, &c->inputs_[0]); |
| 1293 | assert(!c->inputs_[0].empty()); |
| 1294 | } |
| 1295 | |
| 1296 | SetupOtherInputs(c); |
| 1297 | |
| 1298 | return c; |
| 1299 | } |
| 1300 | |
| 1301 | // Finds the largest key in a vector of files. Returns true if files it not |
| 1302 | // empty. |
no test coverage detected