| 841 | void SsdFile::readCheckpoint(std::ifstream& state) { |
| 842 | char magic[4]; |
| 843 | state.read(magic, sizeof(magic)); |
| 844 | BOLT_CHECK_EQ(strncmp(magic, kCheckpointMagic, 4), 0); |
| 845 | const auto maxRegions = readNumber<int32_t>(state); |
| 846 | BOLT_CHECK_EQ( |
| 847 | maxRegions, |
| 848 | maxRegions_, |
| 849 | "Trying to start from checkpoint with a different capacity"); |
| 850 | numRegions_ = readNumber<int32_t>(state); |
| 851 | std::vector<int64_t> scores(maxRegions); |
| 852 | state.read(asChar(scores.data()), maxRegions_ * sizeof(uint64_t)); |
| 853 | std::unordered_map<uint64_t, StringIdLease> idMap; |
| 854 | for (;;) { |
| 855 | auto id = readNumber<uint64_t>(state); |
| 856 | if (id == kCheckpointMapMarker) { |
| 857 | break; |
| 858 | } |
| 859 | std::string name; |
| 860 | name.resize(readNumber<int32_t>(state)); |
| 861 | state.read(name.data(), name.size()); |
| 862 | auto lease = StringIdLease(fileIds(), name); |
| 863 | idMap[id] = std::move(lease); |
| 864 | } |
| 865 | |
| 866 | const auto logSize = ::lseek(evictLogFd_, 0, SEEK_END); |
| 867 | std::vector<uint32_t> evicted(logSize / sizeof(uint32_t)); |
| 868 | const auto rc = ::pread(evictLogFd_, evicted.data(), logSize, 0); |
| 869 | BOLT_CHECK_EQ(logSize, rc, "Failed to read eviction log"); |
| 870 | std::unordered_set<uint32_t> evictedMap; |
| 871 | for (auto region : evicted) { |
| 872 | evictedMap.insert(region); |
| 873 | } |
| 874 | for (;;) { |
| 875 | const uint64_t fileNum = readNumber<uint64_t>(state); |
| 876 | if (fileNum == kCheckpointEndMarker) { |
| 877 | break; |
| 878 | } |
| 879 | const uint64_t offset = readNumber<uint64_t>(state); |
| 880 | const auto run = SsdRun(readNumber<uint64_t>(state)); |
| 881 | // Check that the recovered entry does not fall in an evicted region. |
| 882 | if (evictedMap.find(regionIndex(run.offset())) == evictedMap.end()) { |
| 883 | // The file may have a different id on restore. |
| 884 | auto it = idMap.find(fileNum); |
| 885 | BOLT_CHECK(it != idMap.end()); |
| 886 | FileCacheKey key{it->second, offset}; |
| 887 | entries_[std::move(key)] = run; |
| 888 | } |
| 889 | } |
| 890 | // The state is successfully read. Install the access frequency scores and |
| 891 | // evicted regions. |
| 892 | BOLT_CHECK_EQ(scores.size(), tracker_.regionScores().size()); |
| 893 | // Set the writable regions by deduplicated evicted regions. |
| 894 | writableRegions_.clear(); |
| 895 | for (auto region : evictedMap) { |
| 896 | writableRegions_.push_back(region); |
| 897 | } |
| 898 | tracker_.setRegionScores(scores); |
| 899 | BOLT_SSD_CACHE_LOG(INFO) << fmt::format( |
| 900 | "Starting shard {} from checkpoint with {} entries, {} regions with {} free.", |
nothing calls this directly
no test coverage detected