| 609 | |
| 610 | template<typename Key, typename Engine> |
| 611 | void PersistentTableImpl<Key, Engine>::SaveSnapshotImpl(const std::string& name) { |
| 612 | CHECK(!read_only_); |
| 613 | std::lock_guard<std::recursive_mutex> lock(mutex_); |
| 614 | PosixFile::RecursiveCreateDirectory(SnapshotDirPath(name), 0755); |
| 615 | std::ofstream list_ofs(SnapshotListFilePath(name)); |
| 616 | if (row_id_mapping_.empty()) { return; } |
| 617 | std::vector<PosixMappedFile> index_files(value_files_.size()); |
| 618 | std::vector<uint64_t> counters(value_files_.size()); |
| 619 | const uint64_t max_index_file_size = num_values_per_chunk_ * sizeof(uint64_t); |
| 620 | for (const auto& pair : row_id_mapping_) { |
| 621 | const uint64_t chunk_id = pair.second / num_values_per_chunk_; |
| 622 | CHECK(chunk_id < value_files_.size()); |
| 623 | if (index_files[chunk_id].ptr() == nullptr) { |
| 624 | PosixFile snapshot_file(IndexFilePath(name, chunk_id), O_CREAT | O_RDWR, 0644); |
| 625 | snapshot_file.Truncate(max_index_file_size); |
| 626 | index_files[chunk_id] = |
| 627 | PosixMappedFile(std::move(snapshot_file), max_index_file_size, PROT_READ | PROT_WRITE); |
| 628 | } |
| 629 | uint64_t* indices = static_cast<uint64_t*>(index_files[chunk_id].ptr()); |
| 630 | uint64_t& count = counters[chunk_id]; |
| 631 | CHECK_LT(count, num_values_per_chunk_); |
| 632 | indices[count] = pair.second; |
| 633 | count += 1; |
| 634 | } |
| 635 | for (size_t i = 0; i < value_files_.size(); ++i) { |
| 636 | const uint64_t count = counters[i]; |
| 637 | if (count > 0) { |
| 638 | index_files[i].file().Truncate(count * sizeof(uint64_t)); |
| 639 | list_ofs << kIndexFileNamePrefix + GetChunkName(i) << std::endl; |
| 640 | } else { |
| 641 | CHECK(index_files[i].ptr() == nullptr); |
| 642 | } |
| 643 | } |
| 644 | } |
| 645 | |
| 646 | template<typename Key, typename Engine> |
| 647 | bool PersistentTableImpl<Key, Engine>::SnapshotExists(const std::string& name) { |
nothing calls this directly
no test coverage detected