KiCad PCB EDA Suite
Loading...
Searching...
No Matches
database_cache.h
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2022 Jon Evans <[email protected]>
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
21#ifndef KICAD_DATABASE_CACHE_H
22#define KICAD_DATABASE_CACHE_H
23
24#include <chrono>
25#include <list>
26#include <mutex>
27#include <string>
28#include <unordered_map>
29
31
32
33template<typename CacheValueType>
35{
36public:
37 typedef std::pair<std::string, std::pair<time_t, CacheValueType>> CACHE_ENTRY;
38
39 typedef std::unordered_map<std::string, typename std::list<CACHE_ENTRY>::iterator> CACHE_TYPE;
40
41 typedef typename CACHE_TYPE::const_iterator CACHE_CITER;
42
43 typedef CacheValueType CACHE_VALUE;
44
45 DATABASE_CACHE( size_t aMaxSize, time_t aMaxAge ) :
46 m_maxSize( aMaxSize ),
47 m_maxAge( aMaxAge )
48 {}
49
50 void Put( const std::string& aQuery, const CacheValueType& aResult )
51 {
52 std::lock_guard<std::mutex> lock( m_mutex );
53
54 auto it = m_cache.find( aQuery );
55
56 time_t time = std::chrono::system_clock::to_time_t( std::chrono::system_clock::now() );
57
58 m_cacheMru.push_front( std::make_pair( aQuery,
59 std::make_pair( time, aResult ) ) );
60
61 if( it != m_cache.end() )
62 {
63 m_cacheMru.erase( it->second );
64 m_cache.erase( it );
65 }
66
67 m_cache[aQuery] = m_cacheMru.begin();
68
69 if( m_cache.size() > m_maxSize )
70 {
71 auto last = m_cacheMru.end();
72 last--;
73 m_cache.erase( last->first );
74 m_cacheMru.pop_back();
75 }
76 }
77
78 bool Get( const std::string& aQuery, CacheValueType& aResult )
79 {
80 std::lock_guard<std::mutex> lock( m_mutex );
81
82 auto it = m_cache.find( aQuery );
83
84 if( it == m_cache.end() )
85 return false;
86
87 time_t time = std::chrono::system_clock::to_time_t( std::chrono::system_clock::now() );
88
89 if( time - it->second->second.first > m_maxAge )
90 {
91 m_cacheMru.erase( it->second );
92 m_cache.erase( it );
93 return false;
94 }
95
96 m_cacheMru.splice( m_cacheMru.begin(), m_cacheMru, it->second );
97
98 aResult = it->second->second.second;
99 return true;
100 }
101
102 void SetMaxSize( size_t aMaxSize )
103 {
104 std::lock_guard<std::mutex> lock( m_mutex );
105 m_maxSize = aMaxSize;
106 }
107
108 void SetMaxAge( time_t aMaxAge )
109 {
110 std::lock_guard<std::mutex> lock( m_mutex );
111 m_maxAge = aMaxAge;
112 }
113
114 void Clear( const std::string& aQuery )
115 {
116 std::lock_guard<std::mutex> lock( m_mutex );
117
118 auto it = m_cache.find( aQuery );
119
120 if( it != m_cache.end() )
121 {
122 m_cacheMru.erase( it->second );
123 m_cache.erase( it );
124 }
125 }
126
127private:
128 mutable std::mutex m_mutex;
129 size_t m_maxSize;
130 time_t m_maxAge;
131 std::list<CACHE_ENTRY> m_cacheMru;
133};
134
135#endif //KICAD_DATABASE_CACHE_H
void Put(const std::string &aQuery, const CacheValueType &aResult)
std::pair< std::string, std::pair< time_t, CacheValueType > > CACHE_ENTRY
bool Get(const std::string &aQuery, CacheValueType &aResult)
void SetMaxAge(time_t aMaxAge)
void Clear(const std::string &aQuery)
CACHE_TYPE::const_iterator CACHE_CITER
CacheValueType CACHE_VALUE
std::unordered_map< std::string, typename std::list< CACHE_ENTRY >::iterator > CACHE_TYPE
DATABASE_CACHE(size_t aMaxSize, time_t aMaxAge)
void SetMaxSize(size_t aMaxSize)