2019-11-27 09:39:44 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <Disks/IDisk.h>
|
|
|
|
#include <IO/ReadBufferFromFile.h>
|
|
|
|
#include <IO/WriteBufferFromFile.h>
|
|
|
|
|
|
|
|
#include <Poco/DirectoryIterator.h>
|
|
|
|
#include <Poco/File.h>
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
namespace ErrorCodes
|
|
|
|
{
|
|
|
|
extern const int LOGICAL_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
class DiskLocalReservation;
|
|
|
|
|
|
|
|
class DiskLocal : public IDisk
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
friend class DiskLocalReservation;
|
|
|
|
|
|
|
|
DiskLocal(const String & name_, const String & path_, UInt64 keep_free_space_bytes_)
|
2019-12-03 13:37:40 +00:00
|
|
|
: name(name_), disk_path(path_), keep_free_space_bytes(keep_free_space_bytes_)
|
2019-11-27 09:39:44 +00:00
|
|
|
{
|
2019-12-03 13:37:40 +00:00
|
|
|
if (disk_path.back() != '/')
|
2019-12-09 05:47:12 +00:00
|
|
|
throw Exception("Disk path must ends with '/', but '" + disk_path + "' doesn't.", ErrorCodes::LOGICAL_ERROR);
|
2019-11-27 09:39:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const String & getName() const override { return name; }
|
|
|
|
|
2019-12-03 13:37:40 +00:00
|
|
|
const String & getPath() const override { return disk_path; }
|
2019-11-27 09:39:44 +00:00
|
|
|
|
2019-12-03 13:37:40 +00:00
|
|
|
ReservationPtr reserve(UInt64 bytes) override;
|
2019-11-27 09:39:44 +00:00
|
|
|
|
|
|
|
UInt64 getTotalSpace() const override;
|
|
|
|
|
|
|
|
UInt64 getAvailableSpace() const override;
|
|
|
|
|
|
|
|
UInt64 getUnreservedSpace() const override;
|
|
|
|
|
|
|
|
UInt64 getKeepingFreeSpace() const override { return keep_free_space_bytes; }
|
|
|
|
|
2019-12-03 13:37:40 +00:00
|
|
|
bool exists(const String & path) const override;
|
2019-11-27 09:39:44 +00:00
|
|
|
|
2019-12-03 13:37:40 +00:00
|
|
|
bool isFile(const String & path) const override;
|
2019-11-27 09:39:44 +00:00
|
|
|
|
2019-12-03 13:37:40 +00:00
|
|
|
bool isDirectory(const String & path) const override;
|
2019-11-27 09:39:44 +00:00
|
|
|
|
2019-12-12 08:57:25 +00:00
|
|
|
size_t getFileSize(const String & path) const override;
|
|
|
|
|
2019-12-03 13:37:40 +00:00
|
|
|
void createDirectory(const String & path) override;
|
2019-11-27 09:39:44 +00:00
|
|
|
|
2019-12-03 13:37:40 +00:00
|
|
|
void createDirectories(const String & path) override;
|
2019-11-27 09:39:44 +00:00
|
|
|
|
2019-12-12 08:57:25 +00:00
|
|
|
void clearDirectory(const String & path) override;
|
|
|
|
|
|
|
|
void moveDirectory(const String & from_path, const String & to_path) override;
|
|
|
|
|
2019-12-03 13:37:40 +00:00
|
|
|
DiskDirectoryIteratorPtr iterateDirectory(const String & path) override;
|
2019-11-27 09:39:44 +00:00
|
|
|
|
2019-12-03 13:37:40 +00:00
|
|
|
void moveFile(const String & from_path, const String & to_path) override;
|
2019-11-27 09:39:44 +00:00
|
|
|
|
2020-01-02 14:37:31 +00:00
|
|
|
void replaceFile(const String & from_path, const String & to_path) override;
|
|
|
|
|
2019-12-03 13:37:40 +00:00
|
|
|
void copyFile(const String & from_path, const String & to_path) override;
|
2019-11-27 09:39:44 +00:00
|
|
|
|
2019-12-26 14:28:22 +00:00
|
|
|
std::unique_ptr<ReadBuffer> readFile(const String & path, size_t buf_size = DBMS_DEFAULT_BUFFER_SIZE) const override;
|
2019-12-12 08:57:25 +00:00
|
|
|
|
2019-12-26 14:28:22 +00:00
|
|
|
std::unique_ptr<WriteBuffer> writeFile(const String & path, size_t buf_size = DBMS_DEFAULT_BUFFER_SIZE, WriteMode mode = WriteMode::Rewrite) override;
|
2019-11-27 09:39:44 +00:00
|
|
|
|
2020-01-15 14:15:21 +00:00
|
|
|
void remove(const String & path, bool recursive) override;
|
|
|
|
|
2019-11-27 09:39:44 +00:00
|
|
|
private:
|
2019-12-03 13:37:40 +00:00
|
|
|
bool tryReserve(UInt64 bytes);
|
2019-11-27 09:39:44 +00:00
|
|
|
|
|
|
|
private:
|
2019-12-03 13:37:40 +00:00
|
|
|
const String name;
|
|
|
|
const String disk_path;
|
|
|
|
const UInt64 keep_free_space_bytes;
|
|
|
|
|
|
|
|
UInt64 reserved_bytes = 0;
|
|
|
|
UInt64 reservation_count = 0;
|
2019-11-27 09:39:44 +00:00
|
|
|
};
|
|
|
|
|
2019-12-03 13:37:40 +00:00
|
|
|
using DiskLocalPtr = std::shared_ptr<DiskLocal>;
|
2019-11-27 09:39:44 +00:00
|
|
|
|
|
|
|
|
2019-12-03 13:37:40 +00:00
|
|
|
class DiskLocalDirectoryIterator : public IDiskDirectoryIterator
|
|
|
|
{
|
|
|
|
public:
|
2020-01-10 21:42:26 +00:00
|
|
|
explicit DiskLocalDirectoryIterator(const String & disk_path_, const String & dir_path_) :
|
|
|
|
dir_path(dir_path_), iter(disk_path_ + dir_path_) {}
|
2019-11-27 09:39:44 +00:00
|
|
|
|
2019-12-03 13:37:40 +00:00
|
|
|
void next() override { ++iter; }
|
2019-11-27 09:39:44 +00:00
|
|
|
|
2019-12-03 13:37:40 +00:00
|
|
|
bool isValid() const override { return iter != Poco::DirectoryIterator(); }
|
2019-11-27 09:39:44 +00:00
|
|
|
|
2020-01-10 21:42:26 +00:00
|
|
|
String path() const override
|
|
|
|
{
|
|
|
|
if (iter->isDirectory())
|
|
|
|
return dir_path + iter.name() + '/';
|
|
|
|
else
|
|
|
|
return dir_path + iter.name();
|
|
|
|
}
|
2019-11-27 09:39:44 +00:00
|
|
|
|
|
|
|
private:
|
2020-01-10 21:42:26 +00:00
|
|
|
String dir_path;
|
2019-11-27 09:39:44 +00:00
|
|
|
Poco::DirectoryIterator iter;
|
|
|
|
};
|
|
|
|
|
|
|
|
class DiskLocalReservation : public IReservation
|
|
|
|
{
|
|
|
|
public:
|
2019-12-03 13:37:40 +00:00
|
|
|
DiskLocalReservation(const DiskLocalPtr & disk_, UInt64 size_)
|
|
|
|
: disk(disk_), size(size_), metric_increment(CurrentMetrics::DiskSpaceReservedForMerge, size_)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
UInt64 getSize() const override { return size; }
|
|
|
|
|
|
|
|
DiskPtr getDisk() const override { return disk; }
|
2019-11-27 09:39:44 +00:00
|
|
|
|
|
|
|
void update(UInt64 new_size) override;
|
|
|
|
|
|
|
|
~DiskLocalReservation() override;
|
2019-12-03 13:37:40 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
DiskLocalPtr disk;
|
|
|
|
UInt64 size;
|
|
|
|
CurrentMetrics::Increment metric_increment;
|
2019-11-27 09:39:44 +00:00
|
|
|
};
|
|
|
|
|
2019-12-15 06:34:43 +00:00
|
|
|
class DiskFactory;
|
|
|
|
void registerDiskLocal(DiskFactory & factory);
|
|
|
|
|
2019-11-27 09:39:44 +00:00
|
|
|
}
|