aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/clickhouse/src/Backups/BackupEntryWithChecksumCalculation.cpp
blob: a507e1b0a84e3dac57a02ad4872d8c8d0354bdd3 (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
#include <Backups/BackupEntryWithChecksumCalculation.h>
#include <IO/HashingReadBuffer.h>


namespace DB
{

template <typename Base>
UInt128 BackupEntryWithChecksumCalculation<Base>::getChecksum(const ReadSettings & read_settings) const
{
    {
        std::lock_guard lock{checksum_calculation_mutex};
        if (calculated_checksum)
            return *calculated_checksum;
    }

    size_t size = this->getSize();

    {
        std::lock_guard lock{checksum_calculation_mutex};
        if (!calculated_checksum)
        {
            if (size == 0)
            {
                calculated_checksum = 0;
            }
            else
            {
                auto read_buffer = this->getReadBuffer(read_settings.adjustBufferSize(size));
                HashingReadBuffer hashing_read_buffer(*read_buffer);
                hashing_read_buffer.ignoreAll();
                calculated_checksum = hashing_read_buffer.getHash();
            }
        }
        return *calculated_checksum;
    }
}

template <typename Base>
std::optional<UInt128> BackupEntryWithChecksumCalculation<Base>::getPartialChecksum(size_t prefix_length, const ReadSettings & read_settings) const
{
    if (prefix_length == 0)
        return 0;

    size_t size = this->getSize();
    if (prefix_length >= size)
        return this->getChecksum(read_settings);

    std::lock_guard lock{checksum_calculation_mutex};

    auto read_buffer = this->getReadBuffer(read_settings.adjustBufferSize(calculated_checksum ? prefix_length : size));
    HashingReadBuffer hashing_read_buffer(*read_buffer);

    hashing_read_buffer.ignore(prefix_length);
    auto partial_checksum = hashing_read_buffer.getHash();

    if (!calculated_checksum)
    {
        hashing_read_buffer.ignoreAll();
        calculated_checksum = hashing_read_buffer.getHash();
    }

    return partial_checksum;
}

template class BackupEntryWithChecksumCalculation<IBackupEntry>;

}