2019-12-12 08:57:25 +00:00
|
|
|
#include "IDisk.h"
|
2020-08-07 11:40:19 +00:00
|
|
|
#include "Disks/Executor.h"
|
2020-03-19 16:37:55 +00:00
|
|
|
#include <IO/ReadBufferFromFileBase.h>
|
|
|
|
#include <IO/WriteBufferFromFileBase.h>
|
2020-08-07 11:40:19 +00:00
|
|
|
#include <IO/copyData.h>
|
2020-03-19 16:37:55 +00:00
|
|
|
#include <Poco/Logger.h>
|
|
|
|
#include <common/logger_useful.h>
|
2020-08-07 11:40:19 +00:00
|
|
|
#include <Common/setThreadName.h>
|
2019-12-12 08:57:25 +00:00
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
2020-01-18 22:17:48 +00:00
|
|
|
|
2020-07-12 02:31:58 +00:00
|
|
|
namespace ErrorCodes
|
|
|
|
{
|
|
|
|
extern const int NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
2019-12-12 08:57:25 +00:00
|
|
|
bool IDisk::isDirectoryEmpty(const String & path)
|
|
|
|
{
|
|
|
|
return !iterateDirectory(path)->isValid();
|
|
|
|
}
|
2020-03-19 16:37:55 +00:00
|
|
|
|
|
|
|
void copyFile(IDisk & from_disk, const String & from_path, IDisk & to_disk, const String & to_path)
|
|
|
|
{
|
2020-05-23 22:24:01 +00:00
|
|
|
LOG_DEBUG(&Poco::Logger::get("IDisk"), "Copying from {} {} to {} {}.", from_disk.getName(), from_path, to_disk.getName(), to_path);
|
2020-03-19 16:37:55 +00:00
|
|
|
|
|
|
|
auto in = from_disk.readFile(from_path);
|
|
|
|
auto out = to_disk.writeFile(to_path);
|
|
|
|
copyData(*in, *out);
|
2020-10-06 09:38:00 +00:00
|
|
|
out->finalize();
|
2020-03-19 16:37:55 +00:00
|
|
|
}
|
|
|
|
|
2020-08-07 11:40:19 +00:00
|
|
|
|
|
|
|
using ResultsCollector = std::vector<std::future<void>>;
|
|
|
|
|
|
|
|
void asyncCopy(IDisk & from_disk, String from_path, IDisk & to_disk, String to_path, Executor & exec, ResultsCollector & results)
|
2020-03-19 16:37:55 +00:00
|
|
|
{
|
2020-08-05 16:36:10 +00:00
|
|
|
if (from_disk.isFile(from_path))
|
2020-03-19 16:37:55 +00:00
|
|
|
{
|
2020-08-07 11:40:19 +00:00
|
|
|
auto result = exec.execute(
|
|
|
|
[&from_disk, from_path, &to_disk, to_path]()
|
2020-08-05 16:36:10 +00:00
|
|
|
{
|
2020-08-07 11:40:19 +00:00
|
|
|
setThreadName("DiskCopier");
|
2020-08-05 16:36:10 +00:00
|
|
|
DB::copyFile(from_disk, from_path, to_disk, to_path + fileName(from_path));
|
2020-08-07 11:40:19 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
results.push_back(std::move(result));
|
2020-03-19 16:37:55 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Poco::Path path(from_path);
|
|
|
|
const String & dir_name = path.directory(path.depth() - 1);
|
|
|
|
const String dest = to_path + dir_name + "/";
|
2020-08-05 16:36:10 +00:00
|
|
|
to_disk.createDirectories(dest);
|
|
|
|
|
|
|
|
for (auto it = from_disk.iterateDirectory(from_path); it->isValid(); it->next())
|
2020-08-07 11:40:19 +00:00
|
|
|
asyncCopy(from_disk, it->path(), to_disk, dest, exec, results);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void IDisk::copy(const String & from_path, const std::shared_ptr<IDisk> & to_disk, const String & to_path)
|
|
|
|
{
|
2020-08-11 19:08:32 +00:00
|
|
|
auto & exec = to_disk->getExecutor();
|
2020-08-07 11:40:19 +00:00
|
|
|
ResultsCollector results;
|
|
|
|
|
2020-08-11 19:08:32 +00:00
|
|
|
asyncCopy(*this, from_path, *to_disk, to_path, exec, results);
|
2020-08-07 11:40:19 +00:00
|
|
|
|
|
|
|
for (auto & result : results)
|
|
|
|
result.wait();
|
|
|
|
for (auto & result : results)
|
|
|
|
result.get();
|
|
|
|
}
|
2020-03-19 16:37:55 +00:00
|
|
|
|
2020-07-16 02:34:43 +00:00
|
|
|
void IDisk::truncateFile(const String &, size_t)
|
2020-07-12 02:31:58 +00:00
|
|
|
{
|
|
|
|
throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Truncate operation is not implemented for disk of type {}", getType());
|
|
|
|
}
|
|
|
|
|
2021-01-26 13:29:45 +00:00
|
|
|
SyncGuardPtr IDisk::getDirectorySyncGuard(const String & /* path */) const
|
|
|
|
{
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2019-12-12 08:57:25 +00:00
|
|
|
}
|