aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/clickhouse/src/Common/NamedCollections/NamedCollections.h
blob: 4a0f020db21b17d9f4b41a3ff6d9c3e257cbe415 (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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#pragma once
#include <Interpreters/Context.h>
#include <Common/NamedCollections/NamedCollections_fwd.h>
#include <Common/NamedCollections/NamedCollectionUtils.h>

namespace Poco { namespace Util { class AbstractConfiguration; } }

namespace DB
{

/**
 * Class to represent arbitrary-structured named collection object.
 * It can be defined via config or via SQL command.
 * <named_collections>
 *     <collection1>
 *         ...
 *     </collection1>
 *     ...
 * </named_collections>
 */
class NamedCollection
{
public:
    using Key = std::string;
    using Keys = std::set<Key, std::less<>>;
    using SourceId = NamedCollectionUtils::SourceId;

    static MutableNamedCollectionPtr create(
        const Poco::Util::AbstractConfiguration & config,
        const std::string & collection_name,
        const std::string & collection_path,
        const Keys & keys,
        SourceId source_id_,
        bool is_mutable_);

    bool has(const Key & key) const;

    bool hasAny(const std::initializer_list<Key> & keys) const;

    template <typename T> T get(const Key & key) const;

    template <typename T> T getOrDefault(const Key & key, const T & default_value) const;

    template <typename T> T getAny(const std::initializer_list<Key> & keys) const;

    template <typename T> T getAnyOrDefault(const std::initializer_list<Key> & keys, const T & default_value) const;

    std::unique_lock<std::mutex> lock();

    template <typename T, bool locked = false> void set(const Key & key, const T & value);

    template <typename T, bool locked = false> void setOrUpdate(const Key & key, const T & value);

    template <bool locked = false> void remove(const Key & key);

    MutableNamedCollectionPtr duplicate() const;

    Keys getKeys(ssize_t depth = -1, const std::string & prefix = "") const;

    using iterator = typename Keys::iterator;
    using const_iterator = typename Keys::const_iterator;

    template <bool locked = false> const_iterator begin() const;

    template <bool locked = false> const_iterator end() const;

    std::string dumpStructure() const;

    bool isMutable() const { return is_mutable; }

    SourceId getSourceId() const { return source_id; }

private:
    class Impl;
    using ImplPtr = std::unique_ptr<Impl>;

    NamedCollection(
        ImplPtr pimpl_,
        const std::string & collection_name,
        SourceId source_id,
        bool is_mutable);

    void assertMutable() const;

    ImplPtr pimpl;
    const std::string collection_name;
    const SourceId source_id;
    const bool is_mutable;
    mutable std::mutex mutex;
};

/**
 * A factory of immutable named collections.
 */
class NamedCollectionFactory : boost::noncopyable
{
public:
    static NamedCollectionFactory & instance();

    bool exists(const std::string & collection_name) const;

    NamedCollectionPtr get(const std::string & collection_name) const;

    NamedCollectionPtr tryGet(const std::string & collection_name) const;

    MutableNamedCollectionPtr getMutable(const std::string & collection_name) const;

    void add(const std::string & collection_name, MutableNamedCollectionPtr collection);

    void add(NamedCollectionsMap collections);

    void update(NamedCollectionsMap collections);

    void remove(const std::string & collection_name);

    void removeIfExists(const std::string & collection_name);

    void removeById(NamedCollectionUtils::SourceId id);

    NamedCollectionsMap getAll() const;

private:
    bool existsUnlocked(
        const std::string & collection_name,
        std::lock_guard<std::mutex> & lock) const;

    MutableNamedCollectionPtr tryGetUnlocked(
        const std::string & collection_name,
        std::lock_guard<std::mutex> & lock) const;

    void addUnlocked(
        const std::string & collection_name,
        MutableNamedCollectionPtr collection,
        std::lock_guard<std::mutex> & lock);

    bool removeIfExistsUnlocked(
        const std::string & collection_name,
        std::lock_guard<std::mutex> & lock);

    mutable NamedCollectionsMap loaded_named_collections;

    mutable std::mutex mutex;
    bool is_initialized = false;
};


}