1 /*
2     Copyright (c) 2005-2021 Intel Corporation
3 
4     Licensed under the Apache License, Version 2.0 (the "License");
5     you may not use this file except in compliance with the License.
6     You may obtain a copy of the License at
7 
8         http://www.apache.org/licenses/LICENSE-2.0
9 
10     Unless required by applicable law or agreed to in writing, software
11     distributed under the License is distributed on an "AS IS" BASIS,
12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13     See the License for the specific language governing permissions and
14     limitations under the License.
15 */
16 
17 #define TBB_PREVIEW_CONCURRENT_LRU_CACHE 1
18 
19 #if __INTEL_COMPILER && _MSC_VER
20 #pragma warning(disable : 2586) // decorated name length exceeded, name was truncated
21 #endif
22 
23 #include "common/test.h"
24 #include <tbb/concurrent_lru_cache.h>
25 #include <common/concurrent_lru_cache_common.h>
26 
27 //! \file test_concurrent_lru_cache.cpp
28 //! \brief Test for [preview] functionality
29 
30 //-----------------------------------------------------------------------------
31 // Concurrent LRU Cache Tests: Cache Test Cases
32 //-----------------------------------------------------------------------------
33 
34 //! \brief \ref error_guessing
35 TEST_CASE("basic test for return value") {
36     using preset = concurrent_lru_cache_presets::preset_default<int, int>;
37 
38     auto dummy_f = [](int /*key*/) -> int { return 0xDEADBEEF; };
39     std::size_t number_of_lru_history_items = 8;
40 
41     preset preset_object{dummy_f, number_of_lru_history_items};
42     preset::cache_type& cache = preset_object.cache;
43 
44     int dummy_key = 1;
45     REQUIRE_MESSAGE(
46         dummy_f(dummy_key) == cache[dummy_key].value(),
47         "cache operator() must return only values obtained from value function");
48 }
49 
50 //! \brief \ref error_guessing
51 TEST_CASE("basic test for unused objects") {
52     using preset = concurrent_lru_cache_presets::preset_instance_count;
53     preset preset_object{};
54 
55     for (std::size_t i = 0; i < preset_object.number_of_lru_history_items; ++i)
56         preset_object.cache[i];
57 
58     REQUIRE_MESSAGE(
59         preset_object.source.instances_count() > 1,
60         "cache should store some unused objects");
61 }
62 
63 //! \brief \ref error_guessing
64 TEST_CASE("basic test for unused object limit") {
65     using preset = concurrent_lru_cache_presets::preset_instance_count;
66     preset preset_object{};
67 
68     for (std::size_t i = 0; i < preset_object.number_of_lru_history_items + 1; ++i)
69         preset_object.cache[i];
70 
71     REQUIRE_MESSAGE(
72         preset_object.source.instances_count() == preset_object.number_of_lru_history_items + 1,
73         "cache should respect number of stored unused objects to number passed in constructor");
74 }
75 
76 //! \brief \ref error_guessing
77 TEST_CASE("basic test for eviction order") {
78     using preset = concurrent_lru_cache_presets::preset_map_instance_count;
79     preset preset_object{};
80 
81     REQUIRE_MESSAGE(
82         preset_object.number_of_lru_history_items > 2,
83         "incorrect test setup");
84 
85     preset_object.fill_up_cache(0, preset_object.number_of_lru_history_items);
86 
87     // heat up first element
88     preset_object.cache[0];
89 
90     // cause eviction;
91     preset_object.cache[preset_object.number_of_lru_history_items];
92 
93     bool is_correct = preset_object.is_evicted(1) && !preset_object.is_evicted(0);
94     REQUIRE_MESSAGE(is_correct, "cache should evict items in lru order");
95 }
96 
97 //! \brief \ref error_guessing
98 TEST_CASE("basic test for eviction of only unused items") {
99     using preset = concurrent_lru_cache_presets::preset_map_instance_count;
100     preset preset_object{};
101 
102     preset::handle_type h = preset_object.cache[0];
103 
104     //cause eviction
105     preset_object.fill_up_cache(1, preset_object.number_of_lru_history_items+2);
106 
107     bool is_correct = preset_object.is_evicted(1) && !preset_object.is_evicted(0);
108     REQUIRE_MESSAGE(is_correct, "cache should not evict items in use");
109 }
110 
111 //! \brief \ref error_guessing
112 TEST_CASE("basic test for eviction of only unused items 2") {
113     using preset = concurrent_lru_cache_presets::preset_map_instance_count;
114     preset preset_object{};
115 
116     preset::handle_type h = preset_object.cache[0];
117     {
118         preset::handle_type h1 = preset_object.cache[0];
119     }
120 
121     //cause eviction
122     preset_object.fill_up_cache(1,preset_object.number_of_lru_history_items+2);
123 
124     bool is_correct = preset_object.is_evicted(1) && !preset_object.is_evicted(0);
125     REQUIRE_MESSAGE(is_correct, "cache should not evict items in use");
126 }
127 
128