aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/clickhouse/src/Dictionaries/HashedDictionaryCollectionTraits.h
blob: 4989664890a92da53f98452149b072cc860d3bf9 (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
#pragma once

#include <type_traits>
#include <sparsehash/sparse_hash_map>
#include <Common/HashTable/Hash.h>
#include <Common/HashTable/HashMap.h>
#include <Common/HashTable/HashSet.h>
#include <Common/HashTable/PackedHashMap.h>

namespace DB
{

namespace HashedDictionaryImpl
{

/// sparse_hash_map/sparse_hash_set
template <typename C>
concept IsGoogleSparseHashTable = std::is_same_v<C, google::sparse_hash_map<
    typename C::key_type,
    typename C::mapped_type,
    /// HashFcn is not exported in sparse_hash_map is public type
    DefaultHash<typename C::key_type>>>;

template <typename V>
concept IsStdMapCell = requires (V v)
{
    v->first;
    v->second;
};

/// HashMap/HashMapWithSavedHash/HashSet/HashMapWithSavedHash/PackedHashMap and their Cells
template <typename C>
concept IsBuiltinHashTable = (
    std::is_same_v<C, HashMapWithSavedHash<
        typename C::key_type,
        typename C::mapped_type,
        DefaultHash<typename C::key_type>,
        typename C::grower_type>> ||
    std::is_same_v<C, HashMap<
        typename C::key_type,
        typename C::mapped_type,
        DefaultHash<typename C::key_type>,
        typename C::grower_type>> ||
    std::is_same_v<C, PackedHashMap<
        typename C::key_type,
        typename C::mapped_type,
        DefaultHash<typename C::key_type>,
        typename C::grower_type>> ||
    std::is_same_v<C, HashSetWithSavedHash<
        typename C::key_type,
        DefaultHash<typename C::key_type>,
        typename C::grower_type>> ||
    std::is_same_v<C, HashSet<
        typename C::key_type,
        DefaultHash<typename C::key_type>,
        typename C::grower_type>>
);

template <typename V>
concept IsBuiltinSetCell = requires (V v)
{
    v.getKey();
};

template <typename V>
concept IsBuiltinMapCell = requires (V v)
{
    v->getKey();
    v->getMapped();
};

// NOLINTBEGIN(*)

/// google::sparse_hash_map
template <typename T> auto getSetKeyFromCell(const T & value) { return value; }
template <typename T> auto getKeyFromCell(const T & value) requires (IsStdMapCell<T>) { return value->first; }
template <typename T> auto getValueFromCell(const T & value) requires (IsStdMapCell<T>) { return value->second; }

/// size() - returns table size, without empty and deleted
/// and since this is sparsehash, empty cells should not be significant,
/// and since items cannot be removed from the dictionary, deleted is also not important.
///
/// NOTE: for google::sparse_hash_set value_type is Key, for sparse_hash_map
/// value_type is std::pair<Key, Value>, and now we correctly takes into
/// account padding in structures, if any.
template <typename C> auto getBufferSizeInBytes(const C & c) requires (IsGoogleSparseHashTable<C>) { return c.size() * sizeof(typename C::value_type); }
/// bucket_count() - Returns table size, that includes empty and deleted
template <typename C> auto getBufferSizeInCells(const C & c) requires (IsGoogleSparseHashTable<C>) { return c.bucket_count(); }

template <typename C> auto resizeContainer(C & c, size_t size) requires (IsGoogleSparseHashTable<C>) { return c.resize(size); }
template <typename C> auto clearContainer(C & c) requires (IsGoogleSparseHashTable<C>) { return c.clear(); }

/// HashMap
template <typename T> auto getSetKeyFromCell(const T & value) requires (IsBuiltinSetCell<T>) { return value.getKey(); }
template <typename T> auto getKeyFromCell(const T & value) requires (IsBuiltinMapCell<T>) { return value->getKey(); }
template <typename T> auto getValueFromCell(const T & value) requires (IsBuiltinMapCell<T>) { return value->getMapped(); }

template <typename C> auto getBufferSizeInBytes(const C & c) requires (IsBuiltinHashTable<C>) { return c.getBufferSizeInBytes(); }
template <typename C> auto getBufferSizeInCells(const C & c) requires (IsBuiltinHashTable<C>) { return c.getBufferSizeInCells(); }
template <typename C> auto resizeContainer(C & c, size_t size) requires (IsBuiltinHashTable<C>) { return c.reserve(size); }
template <typename C> void clearContainer(C & c) requires (IsBuiltinHashTable<C>) { return c.clearAndShrink(); }

// NOLINTEND(*)

}

}