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 #if __INTEL_COMPILER && _MSC_VER
18 #pragma warning(disable : 2586) // decorated name length exceeded, name was truncated
19 #endif
20 
21 #define TBB_PREVIEW_CONCURRENT_LRU_CACHE 1
22 
23 #include "common/test.h"
24 #include "oneapi/tbb/concurrent_lru_cache.h"
25 #include <common/concurrent_lru_cache_common.h>
26 
27 //! \file conformance_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 interface \ref requirement
35 TEST_CASE("basic test for creation and use") {
36     using preset = concurrent_lru_cache_presets::preset_default<int, int>;
37 
38     auto callback = [](int key) -> int { return key; };
39     std::size_t number_of_lru_history_items = 8;
40 
41     preset preset_object{callback, number_of_lru_history_items};
42     preset::cache_type& cache = preset_object.cache;
43 
44     int dummy_key = 0;
45     preset::handle_type h = cache[dummy_key];
46     int value = h.value();
47     (void)value;
48 }
49 
50 //! \brief \ref interface \ref requirement
51 TEST_CASE("basic test for std::move") {
52     using preset = concurrent_lru_cache_presets::preset1;
53     preset preset_object{};
54     preset::cache_type& cache = preset_object.cache;
55 
56     // retain handle object to keep an item in the cache
57     // if it is still active without aging
58     preset::handle_type sheep = cache["sheep"];
59     preset::handle_type horse = cache["horse"];
60     preset::handle_type bull = cache["bull"];
61 
62     // store handler objects in vector
63     std::vector<preset::handle_type> animals;
64     animals.reserve(5);
65     animals.emplace_back(std::move(sheep));
66     animals.emplace_back(std::move(horse));
67     animals[0] = std::move(bull);
68 
69     // after resize() vec will be full of default constructed handlers
70     // with null pointers on item in cache and on cache which item belongs to
71     animals.resize(10);
72 }
73 
74 //! \brief \ref interface \ref requirement
75 TEST_CASE("basic test for to bool conversion") {
76     using concurrent_lru_cache_presets::preset1;
77 
78     preset1 preset_instance{};
79     preset1::cache_type& cache = preset_instance.cache;
80 
81 
82     preset1::handle_type handle;
83     preset1::handle_type foobar = preset1::handle_type();
84 
85     handle = cache["handle"];
86 
87     preset1::handle_type foo = cache["bar"];
88 
89     preset1::handle_type handle1(std::move(handle));
90 
91     handle = std::move(handle1);
92 
93     REQUIRE_MESSAGE(
94         !preset1::handle_type(),
95         "user-defined to-bool conversion does not work");
96     REQUIRE_MESSAGE(
97         handle,
98         "user-defined to-bool conversion does not work");
99 
100     handle = preset1::handle_type();
101 }
102 
103 //! \brief \ref requirement
104 TEST_CASE("basic test for cache hit") {
105     using preset = concurrent_lru_cache_presets::preset_call_count<__LINE__>;
106     preset preset_object{};
107     preset::cache_type& cache = preset_object.cache;
108 
109     int dummy_key = 0;
110     cache[dummy_key];
111     cache[dummy_key];
112 
113     REQUIRE_MESSAGE(
114         preset::counter_type::calls == 1,
115         "value function should be called only on a cache miss");
116 }
117 
118 //! \brief \ref requirement
119 TEST_CASE("basic test for unused objects") {
120     using preset = concurrent_lru_cache_presets::preset_instance_count;
121     preset preset_object{};
122 
123     for (std::size_t i = 0; i < preset_object.number_of_lru_history_items; ++i)
124         preset_object.cache[i];
125 
126     REQUIRE_MESSAGE(
127         preset_object.source.instances_count() == preset_object.number_of_lru_history_items+1,
128         "cache should respect number of stored unused objects to number passed in constructor");
129 }
130 
131