39 std::size_t fingerprint{};
42 static Key key(std::string_view filename, std::string_view bytes)
44 constexpr std::size_t window = 64 * 1024;
45 std::size_t h = std::hash<std::string_view>{}(bytes.substr(0, window));
46 if(bytes.size() > window)
48 h, std::hash<std::string_view>{}(bytes.substr(bytes.size() - window)));
49 const QFileInfo fi{QString::fromUtf8(filename.data(), qsizetype(filename.size()))};
51 ossia::hash_combine(h, fi.lastModified().toMSecsSinceEpoch());
52 return Key{std::string{filename}, bytes.size(), h};
55 std::shared_ptr<const T> find(
const Key& k)
57 const auto now = clock::now();
58 std::lock_guard lock{m_mutex};
61 m_entries.begin(), m_entries.end(),
62 [&](
const Entry& e) { return now - e.last_use > ttl; }),
64 for(
auto& e : m_entries)
66 if(e.key.size == k.size && e.key.fingerprint == k.fingerprint
67 && e.key.filename == k.filename)
76 void store(Key k, std::shared_ptr<const T> data)
78 std::lock_guard lock{m_mutex};
79 if(m_entries.size() >= max_entries)
80 m_entries.erase(std::min_element(
81 m_entries.begin(), m_entries.end(),
82 [](
const Entry& a,
const Entry& b) { return a.last_use < b.last_use; }));
83 m_entries.push_back(Entry{std::move(k), std::move(data), clock::now()});
87 using clock = std::chrono::steady_clock;
88 static constexpr std::size_t max_entries = 4;
89 static constexpr auto ttl = std::chrono::seconds(30);
94 std::shared_ptr<const T> data;
95 clock::time_point last_use;
99 ossia::small_vector<Entry, max_entries> m_entries;