aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/clickhouse/src/Databases/DatabaseLazy.h
blob: 2b1b119754d6f7efba84a02f1cc3f94da5c2d9e7 (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
#pragma once

#include <Databases/DatabaseOnDisk.h>
#include <Parsers/ASTCreateQuery.h>


namespace DB
{


class DatabaseLazyIterator;
class Context;

/** Lazy engine of databases.
  * Works like DatabaseOrdinary, but stores in memory only cache.
  * Can be used only with *Log engines.
  */
class DatabaseLazy final : public DatabaseOnDisk
{
public:
    DatabaseLazy(const String & name_, const String & metadata_path_, time_t expiration_time_, ContextPtr context_);

    String getEngineName() const override { return "Lazy"; }

    bool canContainMergeTreeTables() const override { return false; }

    bool canContainDistributedTables() const override { return false; }

    void loadStoredObjects(ContextMutablePtr context, LoadingStrictnessLevel /*mode*/) override;

    void createTable(
        ContextPtr context,
        const String & table_name,
        const StoragePtr & table,
        const ASTPtr & query) override;

    void dropTable(
        ContextPtr context,
        const String & table_name,
        bool sync) override;

    void renameTable(
        ContextPtr context,
        const String & table_name,
        IDatabase & to_database,
        const String & to_table_name,
        bool exchange,
        bool dictionary) override;

    void alterTable(
        ContextPtr context,
        const StorageID & table_id,
        const StorageInMemoryMetadata & metadata) override;

    time_t getObjectMetadataModificationTime(const String & table_name) const override;

    bool isTableExist(const String & table_name, ContextPtr) const override { return isTableExist(table_name); }
    bool isTableExist(const String & table_name) const;

    StoragePtr tryGetTable(const String & table_name, ContextPtr) const override { return tryGetTable(table_name); }
    StoragePtr tryGetTable(const String & table_name) const;

    bool empty() const override;

    DatabaseTablesIteratorPtr getTablesIterator(ContextPtr context, const FilterByNameFunction & filter_by_table_name) const override;

    void attachTable(ContextPtr context, const String & table_name, const StoragePtr & table, const String & relative_table_path) override;

    StoragePtr detachTable(ContextPtr context, const String & table_name) override;

    void shutdown() override;

    ~DatabaseLazy() override;

private:
    struct CacheExpirationQueueElement
    {
        time_t last_touched;
        String table_name;

        CacheExpirationQueueElement(time_t last_touched_, const String & table_name_)
            : last_touched(last_touched_), table_name(table_name_) {}
    };

    using CacheExpirationQueue = std::list<CacheExpirationQueueElement>;


    struct CachedTable
    {
        StoragePtr table;
        time_t last_touched;
        time_t metadata_modification_time;
        CacheExpirationQueue::iterator expiration_iterator;

        CachedTable() = delete;
        CachedTable(const StoragePtr & table_, time_t last_touched_, time_t metadata_modification_time_)
            : table(table_), last_touched(last_touched_), metadata_modification_time(metadata_modification_time_) {}
    };

    using TablesCache = std::unordered_map<String, CachedTable>;

    const time_t expiration_time;

    /// TODO use DatabaseWithOwnTablesBase::tables
    mutable TablesCache tables_cache TSA_GUARDED_BY(mutex);
    mutable CacheExpirationQueue cache_expiration_queue TSA_GUARDED_BY(mutex);

    StoragePtr loadTable(const String & table_name) const;

    void clearExpiredTables() const;

    friend class DatabaseLazyIterator;
};


class DatabaseLazyIterator final : public IDatabaseTablesIterator
{
public:
    DatabaseLazyIterator(
        const DatabaseLazy & database_,
        Strings && table_names_);

    void next() override;
    bool isValid() const override;
    const String & name() const override;
    const StoragePtr & table() const override;

private:
    const DatabaseLazy & database;
    const Strings table_names;
    Strings::const_iterator iterator;
    mutable StoragePtr current_storage;
};
}