You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
/*
* 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
|