| 414 | } |
| 415 | |
| 416 | bool Version::RecordReadSample(Slice internal_key) { |
| 417 | ParsedInternalKey ikey; |
| 418 | if (!ParseInternalKey(internal_key, &ikey)) { |
| 419 | return false; |
| 420 | } |
| 421 | |
| 422 | struct State { |
| 423 | GetStats stats; // Holds first matching file |
| 424 | int matches; |
| 425 | |
| 426 | static bool Match(void* arg, int level, FileMetaData* f) { |
| 427 | State* state = reinterpret_cast<State*>(arg); |
| 428 | state->matches++; |
| 429 | if (state->matches == 1) { |
| 430 | // Remember first match. |
| 431 | state->stats.seek_file = f; |
| 432 | state->stats.seek_file_level = level; |
| 433 | } |
| 434 | // We can stop iterating once we have a second match. |
| 435 | return state->matches < 2; |
| 436 | } |
| 437 | }; |
| 438 | |
| 439 | State state; |
| 440 | state.matches = 0; |
| 441 | ForEachOverlapping(ikey.user_key, internal_key, &state, &State::Match); |
| 442 | |
| 443 | // Must have at least two matches since we want to merge across |
| 444 | // files. But what if we have a single file that contains many |
| 445 | // overwrites and deletions? Should we have another mechanism for |
| 446 | // finding such files? |
| 447 | if (state.matches >= 2) { |
| 448 | // 1MB cost is about 1 seek (see comment in Builder::Apply). |
| 449 | return UpdateStats(state.stats); |
| 450 | } |
| 451 | return false; |
| 452 | } |
| 453 | |
| 454 | void Version::Ref() { ++refs_; } |
| 455 |
nothing calls this directly
no test coverage detected