Mercurial > octave
changeset 30299:f306fe9bfa0d
Limit the size of the cache of latex parsed strings (bug #59546).
* graphics.in.h (gh_manager::latex_data): New typedef moved from latex_renderer.
(m_latex_cache, m_latex_keys): New data members. A map of cached latex_data
and a list of keys. The latter allows for deleting the oldest entries when
the cache becomes too large.
(gh_manager::get_latex_data, gh_manager::set_latex_data): Cache accessor
functions.
* latex-text-renderer.cc: Remove global latex_cache variable.
(latex_renderer::text_to_strlist,latex_renderer::render): Use the
gh_manager to handle the cache.
author | Pantxo Diribarne <pantxo.diribarne@gmail.com> |
---|---|
date | Thu, 27 May 2021 22:49:26 +0200 |
parents | 5797b9f87086 |
children | 4ee01c14fccd |
files | libinterp/corefcn/graphics.in.h libinterp/corefcn/latex-text-renderer.cc |
diffstat | 2 files changed, 61 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/graphics.in.h Thu Nov 18 17:45:49 2021 +0100 +++ b/libinterp/corefcn/graphics.in.h Thu May 27 22:49:26 2021 +0200 @@ -38,6 +38,7 @@ #include <set> #include <sstream> #include <string> +#include <unordered_map> #include <vector> #include "caseless-str.h" @@ -6627,6 +6628,8 @@ { public: + typedef std::pair<uint8NDArray /*pixels*/, std::string /*svg*/> latex_data; + OCTINTERP_API gh_manager (octave::interpreter& interp); // FIXME: eventually eliminate these static functions and access @@ -6797,6 +6800,35 @@ return m_graphics_lock; } + latex_data get_latex_data (const std::string& key) const + { + latex_data retval; + + const auto it = m_latex_cache.find (key); + + if (it != m_latex_cache.end ()) + retval = it->second; + + return retval; + } + + void set_latex_data (const std::string& key, latex_data val) + { + // Limit the number of cache entries to 500 + if (m_latex_keys.size () >= 500) + { + auto it = m_latex_cache.find (m_latex_keys.front ()); + + if (it != m_latex_cache.end ()) + m_latex_cache.erase (it); + + m_latex_keys.pop_front (); + } + + m_latex_cache[key] = val; + m_latex_keys.push_back (key); + } + private: typedef std::map<graphics_handle, graphics_object>::iterator iterator; @@ -6835,6 +6867,11 @@ // A flag telling whether event processing must be constantly on. int m_event_processing; + + // Cache of already parsed latex strings. Store a separate list of keys + // to allow for erasing oldest entries if cache size becomes too large. + std::unordered_map<std::string, latex_data> m_latex_cache; + std::list<std::string> m_latex_keys; }; OCTINTERP_API void
--- a/libinterp/corefcn/latex-text-renderer.cc Thu Nov 18 17:45:49 2021 +0100 +++ b/libinterp/corefcn/latex-text-renderer.cc Thu May 27 22:49:26 2021 +0200 @@ -34,6 +34,7 @@ #include "builtin-defun-decls.h" #include "dim-vector.h" #include "error.h" +#include "graphics.h" #include "file-ops.h" #include "interpreter.h" #include "interpreter-private.h" @@ -42,11 +43,6 @@ namespace octave { - // FIXME: get rid of this global variable - // Store both the generated pixmap and the svg image - typedef std::pair<uint8NDArray /*pixels*/, std::string /*svg*/> latex_data; - std::unordered_map<std::string, latex_data> latex_cache; - std::string quote_string (std::string str) { @@ -113,7 +109,9 @@ { Matrix bbox; uint8NDArray pixels; + text_to_pixels (txt, pixels, bbox, 0, 0, rotation, interpreter, false); + return bbox.extract_n (0, 2, 1, 2); } @@ -129,7 +127,13 @@ text_renderer::font fnt; text_renderer::string str ("", fnt, 0.0, 0.0); str.set_color (m_color); - str.set_svg_element (latex_cache[key (txt, halign)].second); + + gh_manager& gh_mgr = octave::__get_gh_manager__ ("text_to_strlist"); + + gh_manager::latex_data ldata = gh_mgr.get_latex_data (key (txt, halign)); + + str.set_svg_element (ldata.second); + lst.push_back (str); } @@ -351,10 +355,12 @@ latex_renderer::render (const std::string& txt, int halign) { // Render if it was not already done - auto it = latex_cache.find (key (txt, halign)); + gh_manager& gh_mgr = octave::__get_gh_manager__ ("latex_renderer::render"); - if (it != latex_cache.end ()) - return it->second.first; + gh_manager::latex_data ldata = gh_mgr.get_latex_data (key (txt, halign)); + + if (! ldata.first.isempty ()) + return ldata.first; uint8NDArray data; @@ -450,11 +456,13 @@ return data; // Cache pixel and svg data for this string - latex_cache[key (txt, halign)] = latex_data (data, svg_string); + ldata.first = data; + ldata.second = svg_string; + + gh_mgr.set_latex_data (key (txt, halign), ldata); if (m_debug) - std::cout << "* Caching " << key (txt, halign) - << " (numel: " << latex_cache.size () << ")\n"; + std::cout << "* Caching " << key (txt, halign) << std::endl; return data; } @@ -468,7 +476,10 @@ { // Return early for empty strings if (txt.empty ()) - return; + { + bbox = Matrix (1, 4, 0.0); + return; + } if (ok ()) pixels = render (txt, halign);