Merge pull request #449 from robertabcd/improve-backupable

Improve backupable db performance on loading BackupMeta
This commit is contained in:
Igor Canadi 2015-01-05 09:59:50 -08:00
commit 9619081d9b

View file

@ -20,6 +20,7 @@
#endif #endif
#include <inttypes.h> #include <inttypes.h>
#include <stdlib.h>
#include <algorithm> #include <algorithm>
#include <vector> #include <vector>
#include <map> #include <map>
@ -184,6 +185,13 @@ class BackupEngineImpl : public BackupEngine {
return files_.empty(); return files_.empty();
} }
const FileInfo* GetFile(const std::string& filename) const {
auto it = file_infos_->find(filename);
if (it == file_infos_->end())
return nullptr;
return &it->second;
}
const std::vector<std::string>& GetFiles() { const std::vector<std::string>& GetFiles() {
return files_; return files_;
} }
@ -1163,24 +1171,31 @@ Status BackupEngineImpl::BackupMeta::LoadFromFile(
buf[data.size()] = 0; buf[data.size()] = 0;
uint32_t num_files = 0; uint32_t num_files = 0;
int bytes_read = 0; char *next;
sscanf(data.data(), "%" PRId64 "%n", &timestamp_, &bytes_read); timestamp_ = strtoull(data.data(), &next, 10);
data.remove_prefix(bytes_read + 1); // +1 for '\n' data.remove_prefix(next - data.data() + 1); // +1 for '\n'
sscanf(data.data(), "%" PRIu64 "%n", &sequence_number_, &bytes_read); sequence_number_ = strtoull(data.data(), &next, 10);
data.remove_prefix(bytes_read + 1); // +1 for '\n' data.remove_prefix(next - data.data() + 1); // +1 for '\n'
sscanf(data.data(), "%u%n", &num_files, &bytes_read); num_files = static_cast<uint32_t>(strtoul(data.data(), &next, 10));
data.remove_prefix(bytes_read + 1); // +1 for '\n' data.remove_prefix(next - data.data() + 1); // +1 for '\n'
std::vector<FileInfo> files; std::vector<FileInfo> files;
Slice checksum_prefix("crc32 ");
for (uint32_t i = 0; s.ok() && i < num_files; ++i) { for (uint32_t i = 0; s.ok() && i < num_files; ++i) {
auto line = GetSliceUntil(&data, '\n'); auto line = GetSliceUntil(&data, '\n');
std::string filename = GetSliceUntil(&line, ' ').ToString(); std::string filename = GetSliceUntil(&line, ' ').ToString();
uint64_t size; uint64_t size;
s = env_->GetFileSize(backup_dir + "/" + filename, &size); const FileInfo* file_info = GetFile(filename);
if (!s.ok()) { if (file_info != nullptr) {
return s; size = file_info->size;
} else {
s = env_->GetFileSize(backup_dir + "/" + filename, &size);
if (!s.ok()) {
return s;
}
} }
if (line.empty()) { if (line.empty()) {
@ -1188,9 +1203,10 @@ Status BackupEngineImpl::BackupMeta::LoadFromFile(
} }
uint32_t checksum_value = 0; uint32_t checksum_value = 0;
if (line.starts_with("crc32 ")) { if (line.starts_with(checksum_prefix)) {
line.remove_prefix(6); line.remove_prefix(checksum_prefix.size());
sscanf(line.data(), "%u", &checksum_value); checksum_value = static_cast<uint32_t>(
strtoul(line.data(), nullptr, 10));
if (memcmp(line.data(), std::to_string(checksum_value).c_str(), if (memcmp(line.data(), std::to_string(checksum_value).c_str(),
line.size() - 1) != 0) { line.size() - 1) != 0) {
return Status::Corruption("Invalid checksum value"); return Status::Corruption("Invalid checksum value");