1 /*
2     Copyright (c) 2005-2020 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 #include "common/test.h"
20 #include <tbb/concurrent_lru_cache.h>
21 #include <common/concurrent_lru_cache_common.h>
22 
23 //! \file test_concurrent_lru_cache.cpp
24 //! \brief Test for [preview] functionality
25 
26 //-----------------------------------------------------------------------------
27 // Concurrent LRU Cache Tests: Cache Test Cases
28 //-----------------------------------------------------------------------------
29 
30 //! \brief \ref error_guessing
31 TEST_CASE("basic test for return value") {
32     using preset = concurrent_lru_cache_presets::preset_default<int, int>;
33 
34     auto dummy_f = [](int /*key*/) -> int { return 0xDEADBEEF; };
35     std::size_t number_of_lru_history_items = 8;
36 
37     preset preset_object{dummy_f, number_of_lru_history_items};
38     preset::cache_type& cache = preset_object.cache;
39 
40     int dummy_key = 1;
41     REQUIRE_MESSAGE(
42         dummy_f(dummy_key) == cache[dummy_key].value(),
43         "cache operator() must return only values obtained from value function");
44 }
45 
46 //! \brief \ref error_guessing
47 TEST_CASE("basic test for unused objects") {
48     using preset = concurrent_lru_cache_presets::preset_instance_count;
49     preset preset_object{};
50 
51     for (std::size_t i = 0; i < preset_object.number_of_lru_history_items; ++i)
52         preset_object.cache[i];
53 
54     REQUIRE_MESSAGE(
55         preset_object.source.instances_count() > 1,
56         "cache should store some unused objects");
57 }
58 
59 //! \brief \ref error_guessing
60 TEST_CASE("basic test for unused object limit") {
61     using preset = concurrent_lru_cache_presets::preset_instance_count;
62     preset preset_object{};
63 
64     for (std::size_t i = 0; i < preset_object.number_of_lru_history_items + 1; ++i)
65         preset_object.cache[i];
66 
67     REQUIRE_MESSAGE(
68         preset_object.source.instances_count() == preset_object.number_of_lru_history_items + 1,
69         "cache should respect number of stored unused objects to number passed in constructor");
70 }
71 
72 //! \brief \ref error_guessing
73 TEST_CASE("basic test for eviction order") {
74     using preset = concurrent_lru_cache_presets::preset_map_instance_count;
75     preset preset_object{};
76 
77     REQUIRE_MESSAGE(
78         preset_object.number_of_lru_history_items > 2,
79         "incorrect test setup");
80 
81     preset_object.fill_up_cache(0, preset_object.number_of_lru_history_items);
82 
83     // heat up first element
84     preset_object.cache[0];
85 
86     // cause eviction;
87     preset_object.cache[preset_object.number_of_lru_history_items];
88 
89     bool is_correct = preset_object.is_evicted(1) && !preset_object.is_evicted(0);
90     REQUIRE_MESSAGE(is_correct, "cache should evict items in lru order");
91 }
92 
93 //! \brief \ref error_guessing
94 TEST_CASE("basic test for eviction of only unused items") {
95     using preset = concurrent_lru_cache_presets::preset_map_instance_count;
96     preset preset_object{};
97 
98     preset::handle_type h = preset_object.cache[0];
99 
100     //cause eviction
101     preset_object.fill_up_cache(1, preset_object.number_of_lru_history_items+2);
102 
103     bool is_correct = preset_object.is_evicted(1) && !preset_object.is_evicted(0);
104     REQUIRE_MESSAGE(is_correct, "cache should not evict items in use");
105 }
106 
107 //! \brief \ref error_guessing
108 TEST_CASE("basic test for eviction of only unused items 2") {
109     using preset = concurrent_lru_cache_presets::preset_map_instance_count;
110     preset preset_object{};
111 
112     preset::handle_type h = preset_object.cache[0];
113     {
114         preset::handle_type h1 = preset_object.cache[0];
115     }
116 
117     //cause eviction
118     preset_object.fill_up_cache(1,preset_object.number_of_lru_history_items+2);
119 
120     bool is_correct = preset_object.is_evicted(1) && !preset_object.is_evicted(0);
121     REQUIRE_MESSAGE(is_correct, "cache should not evict items in use");
122 }
123 
124