101 lines
2.9 KiB
C
101 lines
2.9 KiB
C
|
/*
|
||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||
|
*
|
||
|
* Copyright (C) 2022 Jon Evans <jon@craftyjon.com>
|
||
|
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||
|
*
|
||
|
* This program is free software: you can redistribute it and/or modify it
|
||
|
* under the terms of the GNU General Public License as published by the
|
||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||
|
* option) any later version.
|
||
|
*
|
||
|
* This program is distributed in the hope that it will be useful, but
|
||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
* General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License along
|
||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
*/
|
||
|
|
||
|
#ifndef KICAD_DATABASE_CACHE_H
|
||
|
#define KICAD_DATABASE_CACHE_H
|
||
|
|
||
|
#include <chrono>
|
||
|
#include <list>
|
||
|
#include <string>
|
||
|
#include <unordered_map>
|
||
|
|
||
|
#include <database/database_connection.h>
|
||
|
|
||
|
|
||
|
class DATABASE_CACHE
|
||
|
{
|
||
|
public:
|
||
|
typedef std::pair<std::string, std::pair<time_t, DATABASE_CONNECTION::ROW>> CACHE_ENTRY;
|
||
|
|
||
|
DATABASE_CACHE( size_t aMaxSize, time_t aMaxAge ) :
|
||
|
m_maxSize( aMaxSize ),
|
||
|
m_maxAge( aMaxAge )
|
||
|
{}
|
||
|
|
||
|
void Put( const std::string& aQuery, const DATABASE_CONNECTION::ROW& aResult )
|
||
|
{
|
||
|
auto it = m_cache.find( aQuery );
|
||
|
|
||
|
time_t time = std::chrono::system_clock::to_time_t( std::chrono::system_clock::now() );
|
||
|
|
||
|
m_cacheMru.push_front( std::make_pair( aQuery,
|
||
|
std::make_pair( time, aResult ) ) );
|
||
|
|
||
|
if( it != m_cache.end() )
|
||
|
{
|
||
|
m_cacheMru.erase( it->second );
|
||
|
m_cache.erase( it );
|
||
|
}
|
||
|
|
||
|
m_cache[aQuery] = m_cacheMru.begin();
|
||
|
|
||
|
if( m_cache.size() > m_maxSize )
|
||
|
{
|
||
|
auto last = m_cacheMru.end();
|
||
|
last--;
|
||
|
m_cache.erase( last->first );
|
||
|
m_cacheMru.pop_back();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool Get( const std::string& aQuery, DATABASE_CONNECTION::ROW& aResult )
|
||
|
{
|
||
|
auto it = m_cache.find( aQuery );
|
||
|
|
||
|
if( it == m_cache.end() )
|
||
|
return false;
|
||
|
|
||
|
time_t time = std::chrono::system_clock::to_time_t( std::chrono::system_clock::now() );
|
||
|
|
||
|
if( time - it->second->second.first > m_maxAge )
|
||
|
{
|
||
|
m_cacheMru.erase( it->second );
|
||
|
m_cache.erase( it );
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
m_cacheMru.splice( m_cacheMru.begin(), m_cacheMru, it->second );
|
||
|
|
||
|
aResult = it->second->second.second;
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void SetMaxSize( size_t aMaxSize ) { m_maxSize = aMaxSize; }
|
||
|
void SetMaxAge( time_t aMaxAge ) { m_maxAge = aMaxAge; }
|
||
|
|
||
|
private:
|
||
|
size_t m_maxSize;
|
||
|
time_t m_maxAge;
|
||
|
std::list<CACHE_ENTRY> m_cacheMru;
|
||
|
std::unordered_map<std::string, std::list<CACHE_ENTRY>::iterator> m_cache;
|
||
|
};
|
||
|
|
||
|
#endif //KICAD_DATABASE_CACHE_H
|