aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/clickhouse/src/Backups/IBackupEntriesLazyBatch.cpp
blob: 4974d9f6702eb65504eac0eea51fb3c1da498e40 (plain) (blame)
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
#include <Backups/IBackupEntriesLazyBatch.h>
#include <Common/Exception.h>
#include <IO/SeekableReadBuffer.h>


namespace DB
{

namespace ErrorCodes
{
    extern const int LOGICAL_ERROR;
}


class IBackupEntriesLazyBatch::BackupEntryFromBatch : public IBackupEntry
{
public:
    BackupEntryFromBatch(const std::shared_ptr<IBackupEntriesLazyBatch> & batch_, size_t index_) : batch(batch_), index(index_) { }

    std::unique_ptr<SeekableReadBuffer> getReadBuffer(const ReadSettings & read_settings) const override { return getInternalBackupEntry()->getReadBuffer(read_settings); }
    UInt64 getSize() const override { return getInternalBackupEntry()->getSize(); }
    UInt128 getChecksum(const ReadSettings & read_settings) const override { return getInternalBackupEntry()->getChecksum(read_settings); }
    std::optional<UInt128> getPartialChecksum(size_t prefix_length, const ReadSettings & read_settings) const override { return getInternalBackupEntry()->getPartialChecksum(prefix_length, read_settings); }
    DataSourceDescription getDataSourceDescription() const override { return getInternalBackupEntry()->getDataSourceDescription(); }
    bool isEncryptedByDisk() const override { return getInternalBackupEntry()->isEncryptedByDisk(); }
    bool isFromFile() const override { return getInternalBackupEntry()->isFromFile(); }
    bool isFromImmutableFile() const override { return getInternalBackupEntry()->isFromImmutableFile(); }
    String getFilePath() const override { return getInternalBackupEntry()->getFilePath(); }
    DiskPtr getDisk() const override { return getInternalBackupEntry()->getDisk(); }

private:
    BackupEntryPtr getInternalBackupEntry() const
    {
        std::lock_guard lock{mutex};
        if (!entry)
        {
            batch->generateIfNecessary();
            entry = batch->entries[index].second;
        }
        return entry;
    }

    const std::shared_ptr<IBackupEntriesLazyBatch> batch;
    const size_t index;
    mutable std::mutex mutex;
    mutable BackupEntryPtr entry;
};


BackupEntries IBackupEntriesLazyBatch::getBackupEntries()
{
    BackupEntries res;
    size_t size = getSize();
    res.reserve(size);
    for (size_t i = 0; i != size; ++i)
    {
        res.emplace_back(getName(i), std::make_unique<BackupEntryFromBatch>(shared_from_this(), i));
    }
    return res;
}

void IBackupEntriesLazyBatch::generateIfNecessary()
{
    std::lock_guard lock{mutex};
    if (generated)
        return;

    entries = generate();

    if (entries.size() != getSize())
        throw Exception(ErrorCodes::LOGICAL_ERROR, "Backup entries were generated incorrectly");

    for (size_t i = 0; i != entries.size(); ++i)
    {
        if (entries[i].first != getName(i))
            throw Exception(ErrorCodes::LOGICAL_ERROR, "Backup entries were generated incorrectly");
    }

    generated = true;
}

IBackupEntriesLazyBatch::~IBackupEntriesLazyBatch() = default;

}