Line data Source code
1 : /**
2 : * Copyright Soramitsu Co., Ltd. 2017 All Rights Reserved.
3 : * http://soramitsu.co.jp
4 : *
5 : * Licensed under the Apache License, Version 2.0 (the "License");
6 : * you may not use this file except in compliance with the License.
7 : * 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, software
12 : * distributed under the License is distributed on an "AS IS" BASIS,
13 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 : * See the License for the specific language governing permissions and
15 : * limitations under the License.
16 : */
17 :
18 : #ifndef IROHA_CACHE_HPP
19 : #define IROHA_CACHE_HPP
20 :
21 : #include "cache/abstract_cache.hpp"
22 :
23 : #include <unordered_map>
24 :
25 : namespace iroha {
26 : namespace cache {
27 :
28 : /**
29 : * Cache for arbitrary types
30 : * @tparam KeyType type of key objects
31 : * @tparam ValueType type of value objects
32 : * @tparam KeyHash hasher for keys
33 : */
34 : template <typename KeyType,
35 : typename ValueType,
36 : typename KeyHash = std::hash<KeyType>>
37 : class Cache : public AbstractCache<KeyType,
38 : ValueType,
39 : Cache<KeyType, ValueType, KeyHash>> {
40 : public:
41 : Cache(uint32_t max_handler_map_size_high = 20000,
42 : uint32_t max_handler_map_size_low = 10000)
43 786 : : max_handler_map_size_high_(max_handler_map_size_high),
44 786 : max_handler_map_size_low_(max_handler_map_size_low) {}
45 :
46 : uint32_t getIndexSizeHighImpl() const {
47 82367 : return max_handler_map_size_high_;
48 : }
49 :
50 : uint32_t getIndexSizeLowImpl() const {
51 20005 : return max_handler_map_size_low_;
52 : }
53 :
54 : uint32_t getCacheItemCountImpl() const {
55 6 : return (uint32_t)handler_map_.size();
56 : }
57 :
58 : void addItemImpl(const KeyType &key, const ValueType &value) {
59 : // elements with the same hash should be replaced
60 42364 : handler_map_[key] = value;
61 42364 : handler_map_index_.push_back(key);
62 42364 : if (handler_map_.size() > getIndexSizeHighImpl()) {
63 20004 : while (handler_map_.size() > getIndexSizeLowImpl()) {
64 20002 : handler_map_.erase(handler_map_index_.front());
65 20002 : handler_map_index_.pop_front();
66 : }
67 2 : }
68 42364 : }
69 :
70 : boost::optional<ValueType> findItemImpl(const KeyType &key) const {
71 4686 : auto found = handler_map_.find(key);
72 4686 : if (found == handler_map_.end()) {
73 1038 : return boost::none;
74 : } else {
75 3648 : return handler_map_.at(key);
76 : }
77 4686 : }
78 :
79 : private:
80 : std::unordered_map<KeyType, ValueType, KeyHash> handler_map_;
81 : std::list<KeyType> handler_map_index_;
82 :
83 : /**
84 : * Protection from handler map overflow.
85 : * TODO 27/10/2017 luckychess Values are quite random and should be tuned
86 : * for better performance and may be even move to config IR-579
87 : */
88 : const uint32_t max_handler_map_size_high_;
89 : const uint32_t max_handler_map_size_low_;
90 : };
91 : } // namespace cache
92 : } // namespace iroha
93 :
94 : #endif // IROHA_CACHE_HPP
|