-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #26 from darbyjohnston/logging
Add more logging
- Loading branch information
Showing
7 changed files
with
222 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// Copyright Contributors to the toucan project. | ||
|
||
#pragma once | ||
|
||
#include <cstdint> | ||
#include <map> | ||
#include <vector> | ||
|
||
namespace toucan | ||
{ | ||
//! Least recently used (LRU) cache. | ||
template<typename T, typename U> | ||
class LRUCache | ||
{ | ||
public: | ||
//! \name Size | ||
///@{ | ||
|
||
size_t getMax() const; | ||
size_t getSize() const; | ||
size_t getCount() const; | ||
float getPercentage() const; | ||
|
||
void setMax(size_t); | ||
|
||
///@} | ||
|
||
//! \name Contents | ||
///@{ | ||
|
||
bool contains(const T& key) const; | ||
bool get(const T& key, U& value) const; | ||
|
||
void add(const T& key, const U& value, size_t size = 1); | ||
void remove(const T& key); | ||
void clear(); | ||
|
||
std::vector<T> getKeys() const; | ||
std::vector<U> getValues() const; | ||
|
||
///@} | ||
|
||
private: | ||
void _maxUpdate(); | ||
|
||
size_t _max = 10000; | ||
std::map<T, std::pair<U, size_t> > _map; | ||
mutable std::map<T, int64_t> _counts; | ||
mutable int64_t _counter = 0; | ||
}; | ||
} | ||
|
||
#include <toucan/LRUCacheInline.h> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// Copyright Contributors to the toucan project. | ||
|
||
#include <algorithm> | ||
|
||
namespace toucan | ||
{ | ||
template<typename T, typename U> | ||
inline std::size_t LRUCache<T, U>::getMax() const | ||
{ | ||
return _max; | ||
} | ||
|
||
template<typename T, typename U> | ||
inline std::size_t LRUCache<T, U>::getSize() const | ||
{ | ||
size_t out = 0; | ||
for (const auto& i : _map) | ||
{ | ||
out += i.second.second; | ||
} | ||
return out; | ||
} | ||
|
||
template<typename T, typename U> | ||
inline std::size_t LRUCache<T, U>::getCount() const | ||
{ | ||
return _map.size(); | ||
} | ||
|
||
template<typename T, typename U> | ||
inline float LRUCache<T, U>::getPercentage() const | ||
{ | ||
return getSize() / static_cast<float>(_max) * 100.F; | ||
} | ||
|
||
template<typename T, typename U> | ||
inline void LRUCache<T, U>::setMax(std::size_t value) | ||
{ | ||
if (value == _max) | ||
return; | ||
_max = value; | ||
_maxUpdate(); | ||
} | ||
|
||
template<typename T, typename U> | ||
inline bool LRUCache<T, U>::contains(const T& key) const | ||
{ | ||
return _map.find(key) != _map.end(); | ||
} | ||
|
||
template<typename T, typename U> | ||
inline bool LRUCache<T, U>::get(const T& key, U& value) const | ||
{ | ||
auto i = _map.find(key); | ||
if (i != _map.end()) | ||
{ | ||
value = i->second.first; | ||
auto j = _counts.find(key); | ||
if (j != _counts.end()) | ||
{ | ||
++_counter; | ||
j->second = _counter; | ||
} | ||
return true; | ||
} | ||
return i != _map.end(); | ||
} | ||
|
||
template<typename T, typename U> | ||
inline void LRUCache<T, U>::add(const T& key, const U& value, size_t size) | ||
{ | ||
_map[key] = std::make_pair(value, size); | ||
++_counter; | ||
_counts[key] = _counter; | ||
_maxUpdate(); | ||
} | ||
|
||
template<typename T, typename U> | ||
inline void LRUCache<T, U>::remove(const T& key) | ||
{ | ||
const auto i = _map.find(key); | ||
if (i != _map.end()) | ||
{ | ||
_map.erase(i); | ||
} | ||
const auto j = _counts.find(key); | ||
if (j != _counts.end()) | ||
{ | ||
_counts.erase(j); | ||
} | ||
_maxUpdate(); | ||
} | ||
|
||
template<typename T, typename U> | ||
inline void LRUCache<T, U>::clear() | ||
{ | ||
_map.clear(); | ||
} | ||
|
||
template<typename T, typename U> | ||
inline std::vector<T> LRUCache<T, U>::getKeys() const | ||
{ | ||
std::vector<T> out; | ||
for (const auto& i : _map) | ||
{ | ||
out.push_back(i.first); | ||
} | ||
return out; | ||
} | ||
|
||
template<typename T, typename U> | ||
inline std::vector<U> LRUCache<T, U>::getValues() const | ||
{ | ||
std::vector<U> out; | ||
for (const auto& i : _map) | ||
{ | ||
out.push_back(i.second.first); | ||
} | ||
return out; | ||
} | ||
|
||
template<typename T, typename U> | ||
inline void LRUCache<T, U>::_maxUpdate() | ||
{ | ||
size_t size = getSize(); | ||
if (size > _max) | ||
{ | ||
std::map<int64_t, T> sorted; | ||
for (const auto& i : _counts) | ||
{ | ||
sorted[i.second] = i.first; | ||
} | ||
while (getSize() > _max) | ||
{ | ||
auto begin = sorted.begin(); | ||
auto i = _map.find(begin->second); | ||
if (i != _map.end()) | ||
{ | ||
_map.erase(i); | ||
} | ||
auto j = _counts.find(begin->second); | ||
if (j != _counts.end()) | ||
{ | ||
_counts.erase(j); | ||
} | ||
sorted.erase(begin); | ||
} | ||
} | ||
} | ||
} |