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