aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/clickhouse/src/Disks/IVolume.h
blob: f40d4dcba60f03ea1029cd92c7cc4318f1ea50c6 (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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#pragma once

#include <Disks/IDisk.h>
#include <Disks/DiskSelector.h>

#include <Poco/Util/AbstractConfiguration.h>

namespace DB
{

enum class VolumeType
{
    JBOD,
    SINGLE_DISK,
    UNKNOWN
};

enum class VolumeLoadBalancing
{
    ROUND_ROBIN,
    LEAST_USED,
};

VolumeLoadBalancing parseVolumeLoadBalancing(const String & config);

class IVolume;
using VolumePtr = std::shared_ptr<IVolume>;
using Volumes = std::vector<VolumePtr>;

/**
 * Disks group by some (user) criteria. For example,
 * - VolumeJBOD("slow_disks", [d1, d2], 100)
 * - VolumeJBOD("fast_disks", [d3, d4], 200)
 *
 * Here VolumeJBOD is one of implementations of IVolume.
 *
 * Different of implementations of this interface implement different reserve behaviour —
 * VolumeJBOD reserves space on the next disk after the last used, other future implementations
 * will reserve, for example, equal spaces on all disks.
 */
class IVolume : public Space
{
public:
    /// This constructor is only for:
    /// - SingleDiskVolume
    /// From createVolumeFromReservation().
    IVolume(String name_,
            Disks disks_,
            size_t max_data_part_size_ = 0,
            bool perform_ttl_move_on_insert_ = true,
            VolumeLoadBalancing load_balancing_ = VolumeLoadBalancing::ROUND_ROBIN)
        : disks(std::move(disks_))
        , name(name_)
        , max_data_part_size(max_data_part_size_)
        , perform_ttl_move_on_insert(perform_ttl_move_on_insert_)
        , load_balancing(load_balancing_)
    {
    }

    IVolume(
        String name_,
        const Poco::Util::AbstractConfiguration & config,
        const String & config_prefix,
        DiskSelectorPtr disk_selector
    );

    virtual ReservationPtr reserve(UInt64 bytes) override = 0;

    /// This is a volume.
    bool isVolume() const override { return true; }

    /// Volume name from config
    const String & getName() const override { return name; }
    virtual VolumeType getType() const = 0;

    /// Return biggest unreserved space across all disks
    std::optional<UInt64> getMaxUnreservedFreeSpace() const;

    DiskPtr getDisk() const { return getDisk(0); }
    virtual DiskPtr getDisk(size_t i) const { return disks[i]; }
    Disks & getDisks() { return disks; }
    const Disks & getDisks() const { return disks; }

    /// Returns effective value of whether merges are allowed on this volume (false) or not (true).
    virtual bool areMergesAvoided() const { return false; }

    /// User setting for enabling and disabling merges on volume.
    virtual void setAvoidMergesUserOverride(bool /*avoid*/) {}

protected:
    Disks disks;
    const String name;

public:
    /// Max size of reservation, zero means unlimited size
    UInt64 max_data_part_size = 0;
    /// Should a new data part be synchronously moved to a volume according to ttl on insert
    /// or move this part in background task asynchronously after insert.
    bool perform_ttl_move_on_insert = true;
    /// Load balancing, one of:
    /// - ROUND_ROBIN
    /// - LEAST_USED
    const VolumeLoadBalancing load_balancing;
};

}