-
Notifications
You must be signed in to change notification settings - Fork 9k
Expand file tree
/
Copy pathBackupInMemory.cpp
More file actions
132 lines (102 loc) · 3.89 KB
/
Copy pathBackupInMemory.cpp
File metadata and controls
132 lines (102 loc) · 3.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include <Backups/BackupInMemory.h>
#include <Backups/BackupsInMemoryHolder.h>
#include <Common/Exception.h>
#include <Common/logger_useful.h>
#include <IO/ReadBufferFromMemory.h>
#include <IO/WriteBufferFromString.h>
namespace DB
{
namespace ErrorCodes
{
extern const int BACKUP_ENTRY_NOT_FOUND;
extern const int BACKUP_ENTRY_ALREADY_EXISTS;
}
BackupInMemory::BackupInMemory(const String & backup_name_, std::weak_ptr<BackupsInMemoryHolder> holder_)
: backup_name(backup_name_), holder(holder_)
{
}
bool BackupInMemory::isEmpty() const
{
std::lock_guard lock{mutex};
return files.empty();
}
bool BackupInMemory::fileExists(const String & file_name) const
{
std::lock_guard lock{mutex};
return files.contains(file_name);
}
UInt64 BackupInMemory::getFileSize(const String & file_name) const
{
std::lock_guard lock{mutex};
auto it = files.find(file_name);
if (it == files.end())
throw Exception(ErrorCodes::BACKUP_ENTRY_NOT_FOUND, "Backup entry {} not found in backup {}", file_name, backup_name);
return it->second.length();
}
void BackupInMemory::removeFile(const String & file_name)
{
/// Best-effort removal (like the S3, Disk and File writers): a partially written backup may lack
/// some files, e.g. `.backup` is written only at finalization.
std::lock_guard lock{mutex};
if (!files.erase(file_name))
LOG_DEBUG(getLogger("BackupInMemory"), "Backup entry {} not found in backup {}, skipping removal", file_name, backup_name);
}
std::unique_ptr<ReadBufferFromFileBase> BackupInMemory::readFile(const String & file_name) const
{
String file_contents;
{
std::lock_guard lock{mutex};
auto it = files.find(file_name);
if (it == files.end())
throw Exception(ErrorCodes::BACKUP_ENTRY_NOT_FOUND, "Backup entry {} not found in backup {}", file_name, backup_name);
file_contents = it->second;
}
return std::make_unique<ReadBufferFromOwnMemoryFile>(file_name, std::move(file_contents));
}
class BackupInMemory::WriteBufferToBackupInMemory : public WriteBufferFromOwnString
{
public:
WriteBufferToBackupInMemory(std::shared_ptr<BackupInMemory> backup_, const String & file_name_)
: backup(backup_), file_name(file_name_) {}
private:
void finalizeImpl() override
{
String file_contents{stringView()};
WriteBufferFromOwnString::finalizeImpl();
std::lock_guard lock{backup->mutex};
auto it = backup->files.find(file_name);
if (it == backup->files.end())
throw Exception(ErrorCodes::BACKUP_ENTRY_NOT_FOUND, "Backup entry {} not found in backup {}", file_name, backup->backup_name);
it->second = std::move(file_contents);
}
std::shared_ptr<BackupInMemory> backup;
String file_name;
};
std::unique_ptr<WriteBuffer> BackupInMemory::writeFile(const String & file_name)
{
{
std::lock_guard lock{mutex};
auto it = files.find(file_name);
if (it != files.end())
throw Exception(ErrorCodes::BACKUP_ENTRY_ALREADY_EXISTS, "Backup entry {} already exists in backup {}", file_name, backup_name);
files.emplace(file_name, "");
}
return std::make_unique<AutoFinalizedWriteBuffer<WriteBufferToBackupInMemory>>(shared_from_this(), file_name);
}
void BackupInMemory::copyFile(const String & from, const String & to)
{
std::lock_guard lock{mutex};
auto it_from = files.find(from);
if (it_from == files.end())
throw Exception(ErrorCodes::BACKUP_ENTRY_NOT_FOUND, "Backup entry {} not found in backup {}", from, backup_name);
auto it_to = files.find(to);
if (it_to != files.end())
throw Exception(ErrorCodes::BACKUP_ENTRY_ALREADY_EXISTS, "Backup entry {} already exists in backup {}", to, backup_name);
files.emplace(to, it_from->second);
}
void BackupInMemory::drop()
{
if (auto holder_ptr = holder.lock())
holder_ptr->dropBackup(backup_name);
}
}