Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
cached_map.h
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
5/*
6 * Authors:
7 * PBS <pbs3141@gmail.com>
8 *
9 * Copyright (C) 2022 PBS
10 *
11 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
12 */
13#ifndef INKSCAPE_UTIL_CACHED_MAP_H
14#define INKSCAPE_UTIL_CACHED_MAP_H
15
16#include <unordered_map>
17#include <deque>
18#include <memory>
19#include <algorithm>
20
21namespace Inkscape {
22namespace Util {
23
48template <typename Tk, typename Tv, typename Hash = std::hash<Tk>, typename Compare = std::equal_to<Tk>>
50{
51public:
59
66 auto add(Tk key, std::unique_ptr<Tv> value)
67 {
68 auto ret = map.emplace(std::move(key), std::move(value));
69 return get_view(ret.first->second);
70 }
71
77 auto lookup(Tk const &key) -> std::shared_ptr<Tv>
78 {
79 if (auto it = map.find(key); it != map.end()) {
80 return get_view(it->second);
81 } else {
82 return {};
83 }
84 }
85
86 void clear()
87 {
88 unused.clear();
89 map.clear();
90 }
91
92private:
93 struct Item
94 {
95 std::unique_ptr<Tv> value; // The unique_ptr owning the actual value.
96 std::weak_ptr<Tv> view; // A non-owning shared_ptr view that is in use by the outside world.
97 Item(decltype(value) value) : value(std::move(value)) {}
98 };
99
100 std::size_t const max_cache_size;
101 std::unordered_map<Tk, Item, Hash, Compare> map;
102 std::deque<Tv*> unused;
103
105 {
106 if (auto view = item.view.lock()) {
107 return view;
108 } else {
109 remove_unused(item.value.get());
110 auto new_view = std::shared_ptr<Tv>(item.value.get(), [this] (Tv *value) {
111 push_unused(value);
112 });
113 item.view = new_view;
114 return new_view;
115 }
116 }
117
118 void remove_unused(Tv *value)
119 {
120 auto it = std::find(unused.begin(), unused.end(), value);
121 if (it != unused.end()) {
122 unused.erase(it);
123 }
124 }
125
126 void push_unused(Tv *value)
127 {
128 unused.emplace_back(value);
129 if (unused.size() > max_cache_size) {
130 pop_unused();
131 }
132 }
133
135 {
136 auto value = unused.front();
137 map.erase(std::find_if(map.begin(), map.end(), [value] (auto const &it) {
138 return it.second.value.get() == value;
139 }));
140 unused.pop_front();
141 }
142};
143
144} // namespace Util
145} // namespace Inkscape
146
147#endif // INKSCAPE_UTIL_CACHED_MAP_H
A cached_map<Tk, Tv> is designed for use by a factory that takes as input keys of type Tk and produce...
Definition cached_map.h:50
void remove_unused(Tv *value)
Definition cached_map.h:118
auto get_view(Item &item)
Definition cached_map.h:104
cached_map(std::size_t max_cache_size=32)
Construct an empty cached_map.
Definition cached_map.h:58
auto lookup(Tk const &key) -> std::shared_ptr< Tv >
Look up a key in the map.
Definition cached_map.h:77
auto add(Tk key, std::unique_ptr< Tv > value)
Given a key and a unique_ptr to a value, inserts them into the map, or discards them if the key is al...
Definition cached_map.h:66
std::deque< Tv * > unused
Definition cached_map.h:102
void push_unused(Tv *value)
Definition cached_map.h:126
std::unordered_map< Tk, Item, Hash, Compare > map
Definition cached_map.h:101
std::size_t const max_cache_size
Definition cached_map.h:100
SPItem * item
Miscellaneous supporting code.
Definition document.h:93
Helper class to stream background task notifications as a series of messages.
STL namespace.
static cairo_user_data_key_t key
std::unique_ptr< Tv > value
Definition cached_map.h:95
Item(decltype(value) value)
Definition cached_map.h:97