Changeset - r25898:e57f843dc921
[Not reviewed]
master
0 2 0
Frédéric Simonis - 3 years ago 2021-08-16 09:18:47
simonisfrederic@gmail.com
Codechange: Improve LineCache queries (#9417)

Adds the support to query the linecache without copying the string.
This uses a custom transparent comparator in conjunction with
a query type using a std::string_view.
2 files changed with 26 insertions and 7 deletions:
0 comments (0 inline, 0 general)
src/gfx_layout.cpp
Show inline comments
 
@@ -885,12 +885,18 @@ Layouter::LineCacheItem &Layouter::GetCa
 
{
 
	if (linecache == nullptr) {
 
		/* Create linecache on first access to avoid trouble with initialisation order of static variables. */
 
		linecache = new LineCache();
 
	}
 

	
 
	if (auto match = linecache->find(LineCacheQuery{state, std::string_view{str, len}});
 
		match != linecache->end()) {
 
		return match->second;
 
	}
 

	
 
	/* Create missing entry */
 
	LineCacheKey key;
 
	key.state_before = state;
 
	key.str.assign(str, len);
 
	return (*linecache)[key];
 
}
 

	
src/gfx_layout.h
Show inline comments
 
@@ -14,12 +14,14 @@
 
#include "gfx_func.h"
 
#include "core/smallmap_type.hpp"
 

	
 
#include <map>
 
#include <string>
 
#include <stack>
 
#include <string_view>
 
#include <type_traits>
 
#include <vector>
 

	
 
#ifdef WITH_ICU_LX
 
#include "layout/ParagraphLayout.h"
 
#define ICU_FONTINSTANCE : public icu::LEFontInstance
 
#else /* WITH_ICU_LX */
 
@@ -152,20 +154,31 @@ class Layouter : public std::vector<std:
 
	const char *string; ///< Pointer to the original string.
 

	
 
	/** Key into the linecache */
 
	struct LineCacheKey {
 
		FontState state_before;  ///< Font state at the beginning of the line.
 
		std::string str;         ///< Source string of the line (including colour and font size codes).
 
	};
 

	
 
		/** Comparison operator for std::map */
 
		bool operator<(const LineCacheKey &other) const
 
	struct LineCacheQuery {
 
		FontState state_before;  ///< Font state at the beginning of the line.
 
		std::string_view str;    ///< Source string of the line (including colour and font size codes).
 
	};
 

	
 
	/** Comparator for std::map */
 
	struct LineCacheCompare {
 
		using is_transparent = void; ///< Enable map queries with various key types
 

	
 
		/** Comparison operator for LineCacheKey and LineCacheQuery */
 
		template<typename Key1, typename Key2>
 
		bool operator()(const Key1 &lhs, const Key2 &rhs) const
 
		{
 
			if (this->state_before.fontsize != other.state_before.fontsize) return this->state_before.fontsize < other.state_before.fontsize;
 
			if (this->state_before.cur_colour != other.state_before.cur_colour) return this->state_before.cur_colour < other.state_before.cur_colour;
 
			if (this->state_before.colour_stack != other.state_before.colour_stack) return this->state_before.colour_stack < other.state_before.colour_stack;
 
			return this->str < other.str;
 
			if (lhs.state_before.fontsize != rhs.state_before.fontsize) return lhs.state_before.fontsize < rhs.state_before.fontsize;
 
			if (lhs.state_before.cur_colour != rhs.state_before.cur_colour) return lhs.state_before.cur_colour < rhs.state_before.cur_colour;
 
			if (lhs.state_before.colour_stack != rhs.state_before.colour_stack) return lhs.state_before.colour_stack < rhs.state_before.colour_stack;
 
			return lhs.str < rhs.str;
 
		}
 
	};
 
public:
 
	/** Item in the linecache */
 
	struct LineCacheItem {
 
		/* Stuff that cannot be freed until the ParagraphLayout is freed */
 
@@ -176,13 +189,13 @@ public:
 
		ParagraphLayouter *layout; ///< Layout of the line.
 

	
 
		LineCacheItem() : buffer(nullptr), layout(nullptr) {}
 
		~LineCacheItem() { delete layout; free(buffer); }
 
	};
 
private:
 
	typedef std::map<LineCacheKey, LineCacheItem> LineCache;
 
	typedef std::map<LineCacheKey, LineCacheItem, LineCacheCompare> LineCache;
 
	static LineCache *linecache;
 

	
 
	static LineCacheItem &GetCachedParagraphLayout(const char *str, size_t len, const FontState &state);
 

	
 
	typedef SmallMap<TextColour, Font *> FontColourMap;
 
	static FontColourMap fonts[FS_END];
0 comments (0 inline, 0 general)