aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/clickhouse/src/Interpreters/EmbeddedDictionaries.h
blob: 674b3a7f01eb328c044bb2c5bf92853cf3aecf3c (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
#pragma once

#include <Interpreters/Context_fwd.h>
#include <Common/MultiVersion.h>
#include <Common/ThreadPool.h>

#include <Poco/Event.h>

#include <thread>
#include <functional>


namespace Poco { class Logger; namespace Util { class AbstractConfiguration; } }

class RegionsHierarchies;
class RegionsNames;
class GeoDictionariesLoader;


namespace DB
{

/// Metrica's Dictionaries which can be used in functions.

class EmbeddedDictionaries : WithContext
{
private:
    Poco::Logger * log;

    MultiVersion<RegionsHierarchies> regions_hierarchies;
    MultiVersion<RegionsNames> regions_names;

    std::unique_ptr<GeoDictionariesLoader> geo_dictionaries_loader;

    /// Directories' updating periodicity (in seconds).
    int reload_period;
    int cur_reload_period = 1;
    bool is_fast_start_stage = true;

    mutable std::mutex mutex;

    ThreadFromGlobalPool reloading_thread;
    Poco::Event destroy;


    void handleException(bool throw_on_error) const;

    /** Updates directories (dictionaries) every reload_period seconds.
     * If all dictionaries are not loaded at least once, try reload them with exponential delay (1, 2, ... reload_period).
     * If all dictionaries are loaded, update them using constant reload_period delay.
     */
    void reloadPeriodically();

    /// Updates dictionaries.
    bool reloadImpl(bool throw_on_error, bool force_reload = false);

    template <typename Dictionary>
    using DictionaryReloader = std::function<std::unique_ptr<Dictionary>(const Poco::Util::AbstractConfiguration & config)>;

    template <typename Dictionary>
    bool reloadDictionary(
        MultiVersion<Dictionary> & dictionary,
        DictionaryReloader<Dictionary> reload_dictionary,
        bool throw_on_error,
        bool force_reload);

public:
    /// Every reload_period seconds directories are updated inside a separate thread.
    EmbeddedDictionaries(
        std::unique_ptr<GeoDictionariesLoader> geo_dictionaries_loader,
        ContextPtr context,
        bool throw_on_error);

    /// Forcibly reloads all dictionaries.
    void reload();

    ~EmbeddedDictionaries();


    MultiVersion<RegionsHierarchies>::Version getRegionsHierarchies() const
    {
        return regions_hierarchies.get();
    }

    MultiVersion<RegionsNames>::Version getRegionsNames() const
    {
        return regions_names.get();
    }
};

}