be/src/util/lru_multi_cache.inline.h
Line | Count | Source |
1 | | // Licensed to the Apache Software Foundation (ASF) under one |
2 | | // or more contributor license agreements. See the NOTICE file |
3 | | // distributed with this work for additional information |
4 | | // regarding copyright ownership. The ASF licenses this file |
5 | | // to you under the Apache License, Version 2.0 (the |
6 | | // "License"); you may not use this file except in compliance |
7 | | // with the License. You may obtain a copy of the License at |
8 | | // |
9 | | // http://www.apache.org/licenses/LICENSE-2.0 |
10 | | // |
11 | | // Unless required by applicable law or agreed to in writing, |
12 | | // software distributed under the License is distributed on an |
13 | | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | | // KIND, either express or implied. See the License for the |
15 | | // specific language governing permissions and limitations |
16 | | // under the License. |
17 | | // |
18 | | // This file is copied from |
19 | | // https://github.com/apache/impala/blob/master/be/src/util/lru-multi-cache.inline.h |
20 | | // and modified by Doris |
21 | | |
22 | | #pragma once |
23 | | |
24 | | #include <glog/logging.h> |
25 | | |
26 | | #include "util/hash_util.hpp" // IWYU pragma: keep |
27 | | #include "util/lru_multi_cache.h" |
28 | | #include "util/time.h" |
29 | | |
30 | | namespace doris { |
31 | | |
32 | | template <typename KeyType, typename ValueType> |
33 | | template <typename... Args> |
34 | | LruMultiCache<KeyType, ValueType>::ValueType_internal::ValueType_internal( |
35 | | LruMultiCache& cache, const KeyType& key, Container_internal& container, Args&&... args) |
36 | 123 | : cache(cache), |
37 | 123 | key(key), |
38 | 123 | container(container), |
39 | 123 | value(std::forward<Args>(args)...), |
40 | 123 | timestamp_seconds(MonotonicSeconds()) {}_ZN5doris13LruMultiCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS_8TestTypeEE18ValueType_internalC2IJRifEEERS8_RKS6_RNS1_4listIS9_SaIS9_EEEDpOT_ Line | Count | Source | 36 | 5 | : cache(cache), | 37 | 5 | key(key), | 38 | 5 | container(container), | 39 | 5 | value(std::forward<Args>(args)...), | 40 | 5 | timestamp_seconds(MonotonicSeconds()) {} |
_ZN5doris13LruMultiCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS_8TestTypeEE18ValueType_internalC2IJifEEERS8_RKS6_RNS1_4listIS9_SaIS9_EEEDpOT_ Line | Count | Source | 36 | 9 | : cache(cache), | 37 | 9 | key(key), | 38 | 9 | container(container), | 39 | 9 | value(std::forward<Args>(args)...), | 40 | 9 | timestamp_seconds(MonotonicSeconds()) {} |
_ZN5doris13LruMultiCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS_8TestTypeEE18ValueType_internalC2IJRmfEEERS8_RKS6_RNS1_4listIS9_SaIS9_EEEDpOT_ Line | Count | Source | 36 | 40 | : cache(cache), | 37 | 40 | key(key), | 38 | 40 | container(container), | 39 | 40 | value(std::forward<Args>(args)...), | 40 | 40 | timestamp_seconds(MonotonicSeconds()) {} |
_ZN5doris13LruMultiCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS_8TestTypeEE18ValueType_internalC2IJmfEEERS8_RKS6_RNS1_4listIS9_SaIS9_EEEDpOT_ Line | Count | Source | 36 | 59 | : cache(cache), | 37 | 59 | key(key), | 38 | 59 | container(container), | 39 | 59 | value(std::forward<Args>(args)...), | 40 | 59 | timestamp_seconds(MonotonicSeconds()) {} |
_ZN5doris13LruMultiCacheI12CollidingKeyNS_8TestTypeEE18ValueType_internalC2IJRifEEERS3_RKS1_RNSt7__cxx114listIS4_SaIS4_EEEDpOT_ Line | Count | Source | 36 | 5 | : cache(cache), | 37 | 5 | key(key), | 38 | 5 | container(container), | 39 | 5 | value(std::forward<Args>(args)...), | 40 | 5 | timestamp_seconds(MonotonicSeconds()) {} |
_ZN5doris13LruMultiCacheI12CollidingKeyNS_8TestTypeEE18ValueType_internalC2IJifEEERS3_RKS1_RNSt7__cxx114listIS4_SaIS4_EEEDpOT_ Line | Count | Source | 36 | 5 | : cache(cache), | 37 | 5 | key(key), | 38 | 5 | container(container), | 39 | 5 | value(std::forward<Args>(args)...), | 40 | 5 | timestamp_seconds(MonotonicSeconds()) {} |
Unexecuted instantiation: _ZN5doris13LruMultiCacheISt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEElENS_2io20CachedHdfsFileHandleEE18ValueType_internalC2IJRKP13hdfs_internalRKS7_RlEEERSB_RKS8_RNS2_4listISC_SaISC_EEEDpOT_ |
41 | | |
42 | | template <typename KeyType, typename ValueType> |
43 | 352 | bool LruMultiCache<KeyType, ValueType>::ValueType_internal::is_available() { |
44 | 352 | return member_hook.is_linked(); |
45 | 352 | } _ZN5doris13LruMultiCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS_8TestTypeEE18ValueType_internal12is_availableEv Line | Count | Source | 43 | 277 | bool LruMultiCache<KeyType, ValueType>::ValueType_internal::is_available() { | 44 | 277 | return member_hook.is_linked(); | 45 | 277 | } |
_ZN5doris13LruMultiCacheI12CollidingKeyNS_8TestTypeEE18ValueType_internal12is_availableEv Line | Count | Source | 43 | 75 | bool LruMultiCache<KeyType, ValueType>::ValueType_internal::is_available() { | 44 | 75 | return member_hook.is_linked(); | 45 | 75 | } |
Unexecuted instantiation: _ZN5doris13LruMultiCacheISt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEElENS_2io20CachedHdfsFileHandleEE18ValueType_internal12is_availableEv |
46 | | |
47 | | template <typename KeyType, typename ValueType> |
48 | | LruMultiCache<KeyType, ValueType>::Accessor::Accessor(ValueType_internal* p_value_internal) |
49 | 222 | : _p_value_internal(p_value_internal) {}_ZN5doris13LruMultiCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS_8TestTypeEE8AccessorC2EPNS8_18ValueType_internalE Line | Count | Source | 49 | 172 | : _p_value_internal(p_value_internal) {} |
_ZN5doris13LruMultiCacheI12CollidingKeyNS_8TestTypeEE8AccessorC2EPNS3_18ValueType_internalE Line | Count | Source | 49 | 50 | : _p_value_internal(p_value_internal) {} |
Unexecuted instantiation: _ZN5doris13LruMultiCacheISt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEElENS_2io20CachedHdfsFileHandleEE8AccessorC2EPNSB_18ValueType_internalE |
50 | | |
51 | | template <typename KeyType, typename ValueType> |
52 | 25 | LruMultiCache<KeyType, ValueType>::Accessor::Accessor(Accessor&& rhs) { |
53 | 25 | _p_value_internal = std::move(rhs._p_value_internal); |
54 | 25 | rhs._p_value_internal = nullptr; |
55 | 25 | } _ZN5doris13LruMultiCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS_8TestTypeEE8AccessorC2EOS9_ Line | Count | Source | 52 | 25 | LruMultiCache<KeyType, ValueType>::Accessor::Accessor(Accessor&& rhs) { | 53 | 25 | _p_value_internal = std::move(rhs._p_value_internal); | 54 | 25 | rhs._p_value_internal = nullptr; | 55 | 25 | } |
Unexecuted instantiation: _ZN5doris13LruMultiCacheISt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEElENS_2io20CachedHdfsFileHandleEE8AccessorC2EOSC_ |
56 | | template <typename KeyType, typename ValueType> |
57 | 45 | auto LruMultiCache<KeyType, ValueType>::Accessor::operator=(Accessor&& rhs) -> Accessor& { |
58 | 45 | _p_value_internal = std::move(rhs._p_value_internal); |
59 | 45 | rhs._p_value_internal = nullptr; |
60 | 45 | return (*this); |
61 | 45 | } _ZN5doris13LruMultiCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS_8TestTypeEE8AccessoraSEOS9_ Line | Count | Source | 57 | 25 | auto LruMultiCache<KeyType, ValueType>::Accessor::operator=(Accessor&& rhs) -> Accessor& { | 58 | 25 | _p_value_internal = std::move(rhs._p_value_internal); | 59 | 25 | rhs._p_value_internal = nullptr; | 60 | 25 | return (*this); | 61 | 25 | } |
_ZN5doris13LruMultiCacheI12CollidingKeyNS_8TestTypeEE8AccessoraSEOS4_ Line | Count | Source | 57 | 20 | auto LruMultiCache<KeyType, ValueType>::Accessor::operator=(Accessor&& rhs) -> Accessor& { | 58 | 20 | _p_value_internal = std::move(rhs._p_value_internal); | 59 | 20 | rhs._p_value_internal = nullptr; | 60 | 20 | return (*this); | 61 | 20 | } |
Unexecuted instantiation: _ZN5doris13LruMultiCacheISt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEElENS_2io20CachedHdfsFileHandleEE8AccessoraSEOSC_ |
62 | | |
63 | | template <typename KeyType, typename ValueType> |
64 | 247 | LruMultiCache<KeyType, ValueType>::Accessor::~Accessor() { |
65 | 247 | release(); |
66 | 247 | } _ZN5doris13LruMultiCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS_8TestTypeEE8AccessorD2Ev Line | Count | Source | 64 | 197 | LruMultiCache<KeyType, ValueType>::Accessor::~Accessor() { | 65 | 197 | release(); | 66 | 197 | } |
_ZN5doris13LruMultiCacheI12CollidingKeyNS_8TestTypeEE8AccessorD2Ev Line | Count | Source | 64 | 50 | LruMultiCache<KeyType, ValueType>::Accessor::~Accessor() { | 65 | 50 | release(); | 66 | 50 | } |
Unexecuted instantiation: _ZN5doris13LruMultiCacheISt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEElENS_2io20CachedHdfsFileHandleEE8AccessorD2Ev |
67 | | |
68 | | template <typename KeyType, typename ValueType> |
69 | 101 | ValueType* LruMultiCache<KeyType, ValueType>::Accessor::get() { |
70 | 101 | if (_p_value_internal) { |
71 | 81 | return &(_p_value_internal->value); |
72 | 81 | } |
73 | | |
74 | 20 | return nullptr; |
75 | 101 | } _ZN5doris13LruMultiCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS_8TestTypeEE8Accessor3getEv Line | Count | Source | 69 | 61 | ValueType* LruMultiCache<KeyType, ValueType>::Accessor::get() { | 70 | 61 | if (_p_value_internal) { | 71 | 51 | return &(_p_value_internal->value); | 72 | 51 | } | 73 | | | 74 | 10 | return nullptr; | 75 | 61 | } |
_ZN5doris13LruMultiCacheI12CollidingKeyNS_8TestTypeEE8Accessor3getEv Line | Count | Source | 69 | 40 | ValueType* LruMultiCache<KeyType, ValueType>::Accessor::get() { | 70 | 40 | if (_p_value_internal) { | 71 | 30 | return &(_p_value_internal->value); | 72 | 30 | } | 73 | | | 74 | 10 | return nullptr; | 75 | 40 | } |
Unexecuted instantiation: _ZN5doris13LruMultiCacheISt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEElENS_2io20CachedHdfsFileHandleEE8Accessor3getEv |
76 | | |
77 | | template <typename KeyType, typename ValueType> |
78 | 0 | const KeyType* LruMultiCache<KeyType, ValueType>::Accessor::get_key() const { |
79 | 0 | if (_p_value_internal) { |
80 | 0 | return &(_p_value_internal->key); |
81 | 0 | } |
82 | | |
83 | 0 | return nullptr; |
84 | 0 | } |
85 | | |
86 | | template <typename KeyType, typename ValueType> |
87 | 403 | void LruMultiCache<KeyType, ValueType>::Accessor::release() { |
88 | | /// Nullptr check as it has to be dereferenced to get the cache reference |
89 | | /// No nullptr check is needed inside LruMultiCache::Release() |
90 | 403 | if (_p_value_internal) { |
91 | 200 | LruMultiCache& cache = _p_value_internal->cache; |
92 | 200 | cache.release(_p_value_internal); |
93 | 200 | _p_value_internal = nullptr; |
94 | 200 | } |
95 | 403 | } _ZN5doris13LruMultiCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS_8TestTypeEE8Accessor7releaseEv Line | Count | Source | 87 | 313 | void LruMultiCache<KeyType, ValueType>::Accessor::release() { | 88 | | /// Nullptr check as it has to be dereferenced to get the cache reference | 89 | | /// No nullptr check is needed inside LruMultiCache::Release() | 90 | 313 | if (_p_value_internal) { | 91 | 160 | LruMultiCache& cache = _p_value_internal->cache; | 92 | 160 | cache.release(_p_value_internal); | 93 | 160 | _p_value_internal = nullptr; | 94 | 160 | } | 95 | 313 | } |
_ZN5doris13LruMultiCacheI12CollidingKeyNS_8TestTypeEE8Accessor7releaseEv Line | Count | Source | 87 | 90 | void LruMultiCache<KeyType, ValueType>::Accessor::release() { | 88 | | /// Nullptr check as it has to be dereferenced to get the cache reference | 89 | | /// No nullptr check is needed inside LruMultiCache::Release() | 90 | 90 | if (_p_value_internal) { | 91 | 40 | LruMultiCache& cache = _p_value_internal->cache; | 92 | 40 | cache.release(_p_value_internal); | 93 | 40 | _p_value_internal = nullptr; | 94 | 40 | } | 95 | 90 | } |
Unexecuted instantiation: _ZN5doris13LruMultiCacheISt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEElENS_2io20CachedHdfsFileHandleEE8Accessor7releaseEv |
96 | | |
97 | | template <typename KeyType, typename ValueType> |
98 | 2 | void LruMultiCache<KeyType, ValueType>::Accessor::destroy() { |
99 | | /// Nullptr check as it has to be dereferenced to get the cache reference |
100 | | /// No nullptr check is needed inside LruMultiCache::destroy() |
101 | 2 | if (_p_value_internal) { |
102 | 2 | LruMultiCache& cache = _p_value_internal->cache; |
103 | 2 | cache.destroy(_p_value_internal); |
104 | 2 | _p_value_internal = nullptr; |
105 | 2 | } |
106 | 2 | } _ZN5doris13LruMultiCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS_8TestTypeEE8Accessor7destroyEv Line | Count | Source | 98 | 2 | void LruMultiCache<KeyType, ValueType>::Accessor::destroy() { | 99 | | /// Nullptr check as it has to be dereferenced to get the cache reference | 100 | | /// No nullptr check is needed inside LruMultiCache::destroy() | 101 | 2 | if (_p_value_internal) { | 102 | 2 | LruMultiCache& cache = _p_value_internal->cache; | 103 | 2 | cache.destroy(_p_value_internal); | 104 | 2 | _p_value_internal = nullptr; | 105 | 2 | } | 106 | 2 | } |
Unexecuted instantiation: _ZN5doris13LruMultiCacheISt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEElENS_2io20CachedHdfsFileHandleEE8Accessor7destroyEv |
107 | | |
108 | | template <typename KeyType, typename ValueType> |
109 | 6 | LruMultiCache<KeyType, ValueType>::LruMultiCache(size_t capacity) : _capacity(capacity), _size(0) {}_ZN5doris13LruMultiCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS_8TestTypeEEC2Em Line | Count | Source | 109 | 5 | LruMultiCache<KeyType, ValueType>::LruMultiCache(size_t capacity) : _capacity(capacity), _size(0) {} |
_ZN5doris13LruMultiCacheI12CollidingKeyNS_8TestTypeEEC2Em Line | Count | Source | 109 | 1 | LruMultiCache<KeyType, ValueType>::LruMultiCache(size_t capacity) : _capacity(capacity), _size(0) {} |
Unexecuted instantiation: _ZN5doris13LruMultiCacheISt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEElENS_2io20CachedHdfsFileHandleEEC2Em |
110 | | |
111 | | template <typename KeyType, typename ValueType> |
112 | 118 | size_t LruMultiCache<KeyType, ValueType>::size() { |
113 | 118 | std::lock_guard<std::mutex> g(_lock); |
114 | 118 | return _size; |
115 | 118 | } _ZN5doris13LruMultiCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS_8TestTypeEE4sizeEv Line | Count | Source | 112 | 117 | size_t LruMultiCache<KeyType, ValueType>::size() { | 113 | 117 | std::lock_guard<std::mutex> g(_lock); | 114 | 117 | return _size; | 115 | 117 | } |
_ZN5doris13LruMultiCacheI12CollidingKeyNS_8TestTypeEE4sizeEv Line | Count | Source | 112 | 1 | size_t LruMultiCache<KeyType, ValueType>::size() { | 113 | 1 | std::lock_guard<std::mutex> g(_lock); | 114 | 1 | return _size; | 115 | 1 | } |
|
116 | | |
117 | | template <typename KeyType, typename ValueType> |
118 | 14 | size_t LruMultiCache<KeyType, ValueType>::number_of_keys() { |
119 | 14 | std::lock_guard<std::mutex> g(_lock); |
120 | 14 | return _hash_table.size(); |
121 | 14 | } |
122 | | |
123 | | template <typename KeyType, typename ValueType> |
124 | 0 | void LruMultiCache<KeyType, ValueType>::set_capacity(size_t new_capacity) { |
125 | 0 | std::lock_guard<std::mutex> g(_lock); |
126 | 0 | _capacity = new_capacity; |
127 | 0 | } |
128 | | |
129 | | template <typename KeyType, typename ValueType> |
130 | 99 | auto LruMultiCache<KeyType, ValueType>::get(const KeyType& key) -> Accessor { |
131 | 99 | std::lock_guard<std::mutex> g(_lock); |
132 | 99 | auto hash_table_it = _hash_table.find(key); |
133 | | |
134 | | // No owning list found with this key, the caller will have to create a new object |
135 | | // with EmplaceAndGet() |
136 | 99 | if (hash_table_it == _hash_table.end()) return Accessor(); |
137 | | |
138 | 89 | Container& container = hash_table_it->second; |
139 | | |
140 | | // Empty containers are deleted automatiacally |
141 | 89 | DCHECK(!container.empty()); |
142 | | |
143 | | // All the available elements are in the front, only need to check the first |
144 | 89 | auto container_it = container.begin(); |
145 | | |
146 | | // No available object found, the caller will have to create a new one with |
147 | | // EmplaceAndGet() |
148 | 89 | if (!container_it->is_available()) return Accessor(); |
149 | | |
150 | | // Move the object to the back of the owning list as it is no longer available. |
151 | 79 | container.splice(container.end(), container, container_it); |
152 | | |
153 | | // Remove the element from the LRU list as it is no longer available |
154 | 79 | container_it->member_hook.unlink(); |
155 | | |
156 | 79 | return Accessor(&(*container_it)); |
157 | 89 | } _ZN5doris13LruMultiCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS_8TestTypeEE3getERKS6_ Line | Count | Source | 130 | 59 | auto LruMultiCache<KeyType, ValueType>::get(const KeyType& key) -> Accessor { | 131 | 59 | std::lock_guard<std::mutex> g(_lock); | 132 | 59 | auto hash_table_it = _hash_table.find(key); | 133 | | | 134 | | // No owning list found with this key, the caller will have to create a new object | 135 | | // with EmplaceAndGet() | 136 | 59 | if (hash_table_it == _hash_table.end()) return Accessor(); | 137 | | | 138 | 54 | Container& container = hash_table_it->second; | 139 | | | 140 | | // Empty containers are deleted automatiacally | 141 | 54 | DCHECK(!container.empty()); | 142 | | | 143 | | // All the available elements are in the front, only need to check the first | 144 | 54 | auto container_it = container.begin(); | 145 | | | 146 | | // No available object found, the caller will have to create a new one with | 147 | | // EmplaceAndGet() | 148 | 54 | if (!container_it->is_available()) return Accessor(); | 149 | | | 150 | | // Move the object to the back of the owning list as it is no longer available. | 151 | 49 | container.splice(container.end(), container, container_it); | 152 | | | 153 | | // Remove the element from the LRU list as it is no longer available | 154 | 49 | container_it->member_hook.unlink(); | 155 | | | 156 | 49 | return Accessor(&(*container_it)); | 157 | 54 | } |
_ZN5doris13LruMultiCacheI12CollidingKeyNS_8TestTypeEE3getERKS1_ Line | Count | Source | 130 | 40 | auto LruMultiCache<KeyType, ValueType>::get(const KeyType& key) -> Accessor { | 131 | 40 | std::lock_guard<std::mutex> g(_lock); | 132 | 40 | auto hash_table_it = _hash_table.find(key); | 133 | | | 134 | | // No owning list found with this key, the caller will have to create a new object | 135 | | // with EmplaceAndGet() | 136 | 40 | if (hash_table_it == _hash_table.end()) return Accessor(); | 137 | | | 138 | 35 | Container& container = hash_table_it->second; | 139 | | | 140 | | // Empty containers are deleted automatiacally | 141 | 35 | DCHECK(!container.empty()); | 142 | | | 143 | | // All the available elements are in the front, only need to check the first | 144 | 35 | auto container_it = container.begin(); | 145 | | | 146 | | // No available object found, the caller will have to create a new one with | 147 | | // EmplaceAndGet() | 148 | 35 | if (!container_it->is_available()) return Accessor(); | 149 | | | 150 | | // Move the object to the back of the owning list as it is no longer available. | 151 | 30 | container.splice(container.end(), container, container_it); | 152 | | | 153 | | // Remove the element from the LRU list as it is no longer available | 154 | 30 | container_it->member_hook.unlink(); | 155 | | | 156 | 30 | return Accessor(&(*container_it)); | 157 | 35 | } |
Unexecuted instantiation: _ZN5doris13LruMultiCacheISt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEElENS_2io20CachedHdfsFileHandleEE3getERKS8_ |
158 | | |
159 | | template <typename KeyType, typename ValueType> |
160 | | template <typename... Args> |
161 | | auto LruMultiCache<KeyType, ValueType>::emplace_and_get(const KeyType& key, Args&&... args) |
162 | 123 | -> Accessor { |
163 | 123 | std::lock_guard<std::mutex> g(_lock); |
164 | | |
165 | | // creates default container if there isn't one |
166 | 123 | Container& container = _hash_table[key]; |
167 | | |
168 | | // Get the reference of the key stored in unordered_map, the parameter could be |
169 | | // temporary object but std::unordered_map has stable references |
170 | 123 | const KeyType& stored_key = _hash_table.find(key)->first; |
171 | | |
172 | | // Place it as the last entry for the owning list, as it just got reserved |
173 | 123 | auto container_it = container.emplace(container.end(), (*this), stored_key, container, |
174 | 123 | std::forward<Args>(args)...); |
175 | | |
176 | | // Only can set this after emplace |
177 | 123 | container_it->it = container_it; |
178 | | |
179 | 123 | _size++; |
180 | | |
181 | | // Need to remove the oldest available if the cache is over the capacity |
182 | 123 | _evict_one_if_needed(); |
183 | | |
184 | 123 | return Accessor(&(*container_it)); |
185 | 123 | } _ZN5doris13LruMultiCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS_8TestTypeEE15emplace_and_getIJRifEEENS8_8AccessorERKS6_DpOT_ Line | Count | Source | 162 | 5 | -> Accessor { | 163 | 5 | std::lock_guard<std::mutex> g(_lock); | 164 | | | 165 | | // creates default container if there isn't one | 166 | 5 | Container& container = _hash_table[key]; | 167 | | | 168 | | // Get the reference of the key stored in unordered_map, the parameter could be | 169 | | // temporary object but std::unordered_map has stable references | 170 | 5 | const KeyType& stored_key = _hash_table.find(key)->first; | 171 | | | 172 | | // Place it as the last entry for the owning list, as it just got reserved | 173 | 5 | auto container_it = container.emplace(container.end(), (*this), stored_key, container, | 174 | 5 | std::forward<Args>(args)...); | 175 | | | 176 | | // Only can set this after emplace | 177 | 5 | container_it->it = container_it; | 178 | | | 179 | 5 | _size++; | 180 | | | 181 | | // Need to remove the oldest available if the cache is over the capacity | 182 | 5 | _evict_one_if_needed(); | 183 | | | 184 | 5 | return Accessor(&(*container_it)); | 185 | 5 | } |
_ZN5doris13LruMultiCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS_8TestTypeEE15emplace_and_getIJifEEENS8_8AccessorERKS6_DpOT_ Line | Count | Source | 162 | 9 | -> Accessor { | 163 | 9 | std::lock_guard<std::mutex> g(_lock); | 164 | | | 165 | | // creates default container if there isn't one | 166 | 9 | Container& container = _hash_table[key]; | 167 | | | 168 | | // Get the reference of the key stored in unordered_map, the parameter could be | 169 | | // temporary object but std::unordered_map has stable references | 170 | 9 | const KeyType& stored_key = _hash_table.find(key)->first; | 171 | | | 172 | | // Place it as the last entry for the owning list, as it just got reserved | 173 | 9 | auto container_it = container.emplace(container.end(), (*this), stored_key, container, | 174 | 9 | std::forward<Args>(args)...); | 175 | | | 176 | | // Only can set this after emplace | 177 | 9 | container_it->it = container_it; | 178 | | | 179 | 9 | _size++; | 180 | | | 181 | | // Need to remove the oldest available if the cache is over the capacity | 182 | 9 | _evict_one_if_needed(); | 183 | | | 184 | 9 | return Accessor(&(*container_it)); | 185 | 9 | } |
_ZN5doris13LruMultiCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS_8TestTypeEE15emplace_and_getIJRmfEEENS8_8AccessorERKS6_DpOT_ Line | Count | Source | 162 | 40 | -> Accessor { | 163 | 40 | std::lock_guard<std::mutex> g(_lock); | 164 | | | 165 | | // creates default container if there isn't one | 166 | 40 | Container& container = _hash_table[key]; | 167 | | | 168 | | // Get the reference of the key stored in unordered_map, the parameter could be | 169 | | // temporary object but std::unordered_map has stable references | 170 | 40 | const KeyType& stored_key = _hash_table.find(key)->first; | 171 | | | 172 | | // Place it as the last entry for the owning list, as it just got reserved | 173 | 40 | auto container_it = container.emplace(container.end(), (*this), stored_key, container, | 174 | 40 | std::forward<Args>(args)...); | 175 | | | 176 | | // Only can set this after emplace | 177 | 40 | container_it->it = container_it; | 178 | | | 179 | 40 | _size++; | 180 | | | 181 | | // Need to remove the oldest available if the cache is over the capacity | 182 | 40 | _evict_one_if_needed(); | 183 | | | 184 | 40 | return Accessor(&(*container_it)); | 185 | 40 | } |
_ZN5doris13LruMultiCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS_8TestTypeEE15emplace_and_getIJmfEEENS8_8AccessorERKS6_DpOT_ Line | Count | Source | 162 | 59 | -> Accessor { | 163 | 59 | std::lock_guard<std::mutex> g(_lock); | 164 | | | 165 | | // creates default container if there isn't one | 166 | 59 | Container& container = _hash_table[key]; | 167 | | | 168 | | // Get the reference of the key stored in unordered_map, the parameter could be | 169 | | // temporary object but std::unordered_map has stable references | 170 | 59 | const KeyType& stored_key = _hash_table.find(key)->first; | 171 | | | 172 | | // Place it as the last entry for the owning list, as it just got reserved | 173 | 59 | auto container_it = container.emplace(container.end(), (*this), stored_key, container, | 174 | 59 | std::forward<Args>(args)...); | 175 | | | 176 | | // Only can set this after emplace | 177 | 59 | container_it->it = container_it; | 178 | | | 179 | 59 | _size++; | 180 | | | 181 | | // Need to remove the oldest available if the cache is over the capacity | 182 | 59 | _evict_one_if_needed(); | 183 | | | 184 | 59 | return Accessor(&(*container_it)); | 185 | 59 | } |
_ZN5doris13LruMultiCacheI12CollidingKeyNS_8TestTypeEE15emplace_and_getIJRifEEENS3_8AccessorERKS1_DpOT_ Line | Count | Source | 162 | 5 | -> Accessor { | 163 | 5 | std::lock_guard<std::mutex> g(_lock); | 164 | | | 165 | | // creates default container if there isn't one | 166 | 5 | Container& container = _hash_table[key]; | 167 | | | 168 | | // Get the reference of the key stored in unordered_map, the parameter could be | 169 | | // temporary object but std::unordered_map has stable references | 170 | 5 | const KeyType& stored_key = _hash_table.find(key)->first; | 171 | | | 172 | | // Place it as the last entry for the owning list, as it just got reserved | 173 | 5 | auto container_it = container.emplace(container.end(), (*this), stored_key, container, | 174 | 5 | std::forward<Args>(args)...); | 175 | | | 176 | | // Only can set this after emplace | 177 | 5 | container_it->it = container_it; | 178 | | | 179 | 5 | _size++; | 180 | | | 181 | | // Need to remove the oldest available if the cache is over the capacity | 182 | 5 | _evict_one_if_needed(); | 183 | | | 184 | 5 | return Accessor(&(*container_it)); | 185 | 5 | } |
_ZN5doris13LruMultiCacheI12CollidingKeyNS_8TestTypeEE15emplace_and_getIJifEEENS3_8AccessorERKS1_DpOT_ Line | Count | Source | 162 | 5 | -> Accessor { | 163 | 5 | std::lock_guard<std::mutex> g(_lock); | 164 | | | 165 | | // creates default container if there isn't one | 166 | 5 | Container& container = _hash_table[key]; | 167 | | | 168 | | // Get the reference of the key stored in unordered_map, the parameter could be | 169 | | // temporary object but std::unordered_map has stable references | 170 | 5 | const KeyType& stored_key = _hash_table.find(key)->first; | 171 | | | 172 | | // Place it as the last entry for the owning list, as it just got reserved | 173 | 5 | auto container_it = container.emplace(container.end(), (*this), stored_key, container, | 174 | 5 | std::forward<Args>(args)...); | 175 | | | 176 | | // Only can set this after emplace | 177 | 5 | container_it->it = container_it; | 178 | | | 179 | 5 | _size++; | 180 | | | 181 | | // Need to remove the oldest available if the cache is over the capacity | 182 | 5 | _evict_one_if_needed(); | 183 | | | 184 | 5 | return Accessor(&(*container_it)); | 185 | 5 | } |
Unexecuted instantiation: _ZN5doris13LruMultiCacheISt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEElENS_2io20CachedHdfsFileHandleEE15emplace_and_getIJRKP13hdfs_internalRKS7_RlEEENSB_8AccessorERKS8_DpOT_ |
186 | | |
187 | | template <typename KeyType, typename ValueType> |
188 | 200 | void LruMultiCache<KeyType, ValueType>::release(ValueType_internal* p_value_internal) { |
189 | 200 | std::lock_guard<std::mutex> g(_lock); |
190 | | |
191 | | // This only can be used by the accessor, which already checks for nullptr |
192 | 200 | DCHECK(p_value_internal); |
193 | | |
194 | | // Has to be currently not available |
195 | 200 | DCHECK(!p_value_internal->is_available()); |
196 | | |
197 | | // DO NOT update timestamp_seconds when release. |
198 | | // Because we are about to evict cache value after a certain period. |
199 | 200 | p_value_internal->timestamp_seconds = MonotonicSeconds(); |
200 | | |
201 | 200 | Container& container = p_value_internal->container; |
202 | | |
203 | | // Move the object to the front, keep LRU relation in owning list too to |
204 | | // be able to age out unused objects |
205 | 200 | container.splice(container.begin(), container, p_value_internal->it); |
206 | | |
207 | | // Add the object to LRU list too as it is now available for usage |
208 | 200 | _lru_list.push_front(container.front()); |
209 | | |
210 | | // In case we overshot the capacity already, the cache can evict the oldest one |
211 | 200 | _evict_one_if_needed(); |
212 | 200 | } _ZN5doris13LruMultiCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS_8TestTypeEE7releaseEPNS8_18ValueType_internalE Line | Count | Source | 188 | 160 | void LruMultiCache<KeyType, ValueType>::release(ValueType_internal* p_value_internal) { | 189 | 160 | std::lock_guard<std::mutex> g(_lock); | 190 | | | 191 | | // This only can be used by the accessor, which already checks for nullptr | 192 | 160 | DCHECK(p_value_internal); | 193 | | | 194 | | // Has to be currently not available | 195 | 160 | DCHECK(!p_value_internal->is_available()); | 196 | | | 197 | | // DO NOT update timestamp_seconds when release. | 198 | | // Because we are about to evict cache value after a certain period. | 199 | 160 | p_value_internal->timestamp_seconds = MonotonicSeconds(); | 200 | | | 201 | 160 | Container& container = p_value_internal->container; | 202 | | | 203 | | // Move the object to the front, keep LRU relation in owning list too to | 204 | | // be able to age out unused objects | 205 | 160 | container.splice(container.begin(), container, p_value_internal->it); | 206 | | | 207 | | // Add the object to LRU list too as it is now available for usage | 208 | 160 | _lru_list.push_front(container.front()); | 209 | | | 210 | | // In case we overshot the capacity already, the cache can evict the oldest one | 211 | 160 | _evict_one_if_needed(); | 212 | 160 | } |
_ZN5doris13LruMultiCacheI12CollidingKeyNS_8TestTypeEE7releaseEPNS3_18ValueType_internalE Line | Count | Source | 188 | 40 | void LruMultiCache<KeyType, ValueType>::release(ValueType_internal* p_value_internal) { | 189 | 40 | std::lock_guard<std::mutex> g(_lock); | 190 | | | 191 | | // This only can be used by the accessor, which already checks for nullptr | 192 | 40 | DCHECK(p_value_internal); | 193 | | | 194 | | // Has to be currently not available | 195 | 40 | DCHECK(!p_value_internal->is_available()); | 196 | | | 197 | | // DO NOT update timestamp_seconds when release. | 198 | | // Because we are about to evict cache value after a certain period. | 199 | 40 | p_value_internal->timestamp_seconds = MonotonicSeconds(); | 200 | | | 201 | 40 | Container& container = p_value_internal->container; | 202 | | | 203 | | // Move the object to the front, keep LRU relation in owning list too to | 204 | | // be able to age out unused objects | 205 | 40 | container.splice(container.begin(), container, p_value_internal->it); | 206 | | | 207 | | // Add the object to LRU list too as it is now available for usage | 208 | 40 | _lru_list.push_front(container.front()); | 209 | | | 210 | | // In case we overshot the capacity already, the cache can evict the oldest one | 211 | 40 | _evict_one_if_needed(); | 212 | 40 | } |
Unexecuted instantiation: _ZN5doris13LruMultiCacheISt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEElENS_2io20CachedHdfsFileHandleEE7releaseEPNSB_18ValueType_internalE |
213 | | |
214 | | template <typename KeyType, typename ValueType> |
215 | 2 | void LruMultiCache<KeyType, ValueType>::destroy(ValueType_internal* p_value_internal) { |
216 | 2 | std::lock_guard<std::mutex> g(_lock); |
217 | | |
218 | | // This only can be used by the accessor, which already checks for nullptr |
219 | 2 | DCHECK(p_value_internal); |
220 | | |
221 | | // Has to be currently not available |
222 | 2 | DCHECK(!p_value_internal->is_available()); |
223 | | |
224 | 2 | Container& container = p_value_internal->container; |
225 | | |
226 | 2 | if (container.size() == 1) { |
227 | | // Last element, owning list can be removed to prevent aging |
228 | 1 | _hash_table.erase(p_value_internal->key); |
229 | 1 | } else { |
230 | | // Remove from owning list |
231 | 1 | container.erase(p_value_internal->it); |
232 | 1 | } |
233 | | |
234 | 2 | _size--; |
235 | 2 | } _ZN5doris13LruMultiCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS_8TestTypeEE7destroyEPNS8_18ValueType_internalE Line | Count | Source | 215 | 2 | void LruMultiCache<KeyType, ValueType>::destroy(ValueType_internal* p_value_internal) { | 216 | 2 | std::lock_guard<std::mutex> g(_lock); | 217 | | | 218 | | // This only can be used by the accessor, which already checks for nullptr | 219 | 2 | DCHECK(p_value_internal); | 220 | | | 221 | | // Has to be currently not available | 222 | 2 | DCHECK(!p_value_internal->is_available()); | 223 | | | 224 | 2 | Container& container = p_value_internal->container; | 225 | | | 226 | 2 | if (container.size() == 1) { | 227 | | // Last element, owning list can be removed to prevent aging | 228 | 1 | _hash_table.erase(p_value_internal->key); | 229 | 1 | } else { | 230 | | // Remove from owning list | 231 | 1 | container.erase(p_value_internal->it); | 232 | 1 | } | 233 | | | 234 | 2 | _size--; | 235 | 2 | } |
Unexecuted instantiation: _ZN5doris13LruMultiCacheISt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEElENS_2io20CachedHdfsFileHandleEE7destroyEPNSB_18ValueType_internalE |
236 | | |
237 | | template <typename KeyType, typename ValueType> |
238 | 118 | size_t LruMultiCache<KeyType, ValueType>::number_of_available_objects() { |
239 | 118 | std::lock_guard<std::mutex> g(_lock); |
240 | 118 | return _lru_list.size(); |
241 | 118 | } _ZN5doris13LruMultiCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS_8TestTypeEE27number_of_available_objectsEv Line | Count | Source | 238 | 117 | size_t LruMultiCache<KeyType, ValueType>::number_of_available_objects() { | 239 | 117 | std::lock_guard<std::mutex> g(_lock); | 240 | 117 | return _lru_list.size(); | 241 | 117 | } |
_ZN5doris13LruMultiCacheI12CollidingKeyNS_8TestTypeEE27number_of_available_objectsEv Line | Count | Source | 238 | 1 | size_t LruMultiCache<KeyType, ValueType>::number_of_available_objects() { | 239 | 1 | std::lock_guard<std::mutex> g(_lock); | 240 | 1 | return _lru_list.size(); | 241 | 1 | } |
|
242 | | |
243 | | template <typename KeyType, typename ValueType> |
244 | 21 | void LruMultiCache<KeyType, ValueType>::rehash() { |
245 | 21 | std::lock_guard<std::mutex> g(_lock); |
246 | 21 | _hash_table.rehash(_hash_table.bucket_count() + 1); |
247 | 21 | } _ZN5doris13LruMultiCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS_8TestTypeEE6rehashEv Line | Count | Source | 244 | 11 | void LruMultiCache<KeyType, ValueType>::rehash() { | 245 | 11 | std::lock_guard<std::mutex> g(_lock); | 246 | 11 | _hash_table.rehash(_hash_table.bucket_count() + 1); | 247 | 11 | } |
_ZN5doris13LruMultiCacheI12CollidingKeyNS_8TestTypeEE6rehashEv Line | Count | Source | 244 | 10 | void LruMultiCache<KeyType, ValueType>::rehash() { | 245 | 10 | std::lock_guard<std::mutex> g(_lock); | 246 | 10 | _hash_table.rehash(_hash_table.bucket_count() + 1); | 247 | 10 | } |
|
248 | | |
249 | | template <typename KeyType, typename ValueType> |
250 | 61 | void LruMultiCache<KeyType, ValueType>::_evict_one(ValueType_internal& value_internal) { |
251 | | // std::mutex is locked by the caller evicting function |
252 | | // _lock.DCheckLocked(); |
253 | | |
254 | | // Has to be available to evict |
255 | 61 | DCHECK(value_internal.is_available()); |
256 | | |
257 | | // Remove from LRU cache |
258 | 61 | value_internal.member_hook.unlink(); |
259 | | |
260 | 61 | Container& container = value_internal.container; |
261 | | |
262 | 61 | if (container.size() == 1) { |
263 | | // Last element, owning list can be removed to prevent aging |
264 | 1 | _hash_table.erase(value_internal.key); |
265 | 60 | } else { |
266 | | // Remove from owning list |
267 | 60 | container.erase(value_internal.it); |
268 | 60 | } |
269 | | |
270 | 61 | _size--; |
271 | 61 | } _ZN5doris13LruMultiCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS_8TestTypeEE10_evict_oneERNS8_18ValueType_internalE Line | Count | Source | 250 | 61 | void LruMultiCache<KeyType, ValueType>::_evict_one(ValueType_internal& value_internal) { | 251 | | // std::mutex is locked by the caller evicting function | 252 | | // _lock.DCheckLocked(); | 253 | | | 254 | | // Has to be available to evict | 255 | 61 | DCHECK(value_internal.is_available()); | 256 | | | 257 | | // Remove from LRU cache | 258 | 61 | value_internal.member_hook.unlink(); | 259 | | | 260 | 61 | Container& container = value_internal.container; | 261 | | | 262 | 61 | if (container.size() == 1) { | 263 | | // Last element, owning list can be removed to prevent aging | 264 | 1 | _hash_table.erase(value_internal.key); | 265 | 60 | } else { | 266 | | // Remove from owning list | 267 | 60 | container.erase(value_internal.it); | 268 | 60 | } | 269 | | | 270 | 61 | _size--; | 271 | 61 | } |
Unexecuted instantiation: _ZN5doris13LruMultiCacheI12CollidingKeyNS_8TestTypeEE10_evict_oneERNS3_18ValueType_internalE Unexecuted instantiation: _ZN5doris13LruMultiCacheISt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEElENS_2io20CachedHdfsFileHandleEE10_evict_oneERNSB_18ValueType_internalE |
272 | | |
273 | | template <typename KeyType, typename ValueType> |
274 | 323 | void LruMultiCache<KeyType, ValueType>::_evict_one_if_needed() { |
275 | | // std::mutex is locked by the caller public function |
276 | | // _lock.DCheckLocked(); |
277 | | |
278 | 323 | if (!_lru_list.empty() && _size > _capacity) { |
279 | 61 | _evict_one(_lru_list.back()); |
280 | 61 | } |
281 | 323 | } _ZN5doris13LruMultiCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS_8TestTypeEE20_evict_one_if_neededEv Line | Count | Source | 274 | 273 | void LruMultiCache<KeyType, ValueType>::_evict_one_if_needed() { | 275 | | // std::mutex is locked by the caller public function | 276 | | // _lock.DCheckLocked(); | 277 | | | 278 | 273 | if (!_lru_list.empty() && _size > _capacity) { | 279 | 61 | _evict_one(_lru_list.back()); | 280 | 61 | } | 281 | 273 | } |
_ZN5doris13LruMultiCacheI12CollidingKeyNS_8TestTypeEE20_evict_one_if_neededEv Line | Count | Source | 274 | 50 | void LruMultiCache<KeyType, ValueType>::_evict_one_if_needed() { | 275 | | // std::mutex is locked by the caller public function | 276 | | // _lock.DCheckLocked(); | 277 | | | 278 | 50 | if (!_lru_list.empty() && _size > _capacity) { | 279 | 0 | _evict_one(_lru_list.back()); | 280 | 0 | } | 281 | 50 | } |
Unexecuted instantiation: _ZN5doris13LruMultiCacheISt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEElENS_2io20CachedHdfsFileHandleEE20_evict_one_if_neededEv |
282 | | |
283 | | template <typename KeyType, typename ValueType> |
284 | 0 | void LruMultiCache<KeyType, ValueType>::evict_older_than(uint64_t oldest_allowed_timestamp) { |
285 | 0 | std::lock_guard<std::mutex> g(_lock); |
286 | | |
287 | | // Stop eviction if |
288 | | // - there are no more available (i.e. evictable) objects |
289 | | // - cache size is below capacity and the oldest object is not older than the limit |
290 | 0 | while (!_lru_list.empty() && |
291 | 0 | (_size > _capacity || _lru_list.back().timestamp_seconds < oldest_allowed_timestamp)) { |
292 | 0 | _evict_one(_lru_list.back()); |
293 | 0 | } |
294 | 0 | } |
295 | | |
296 | | } // namespace doris |