Store region pointers instead of names in the RegionsHighlighter cache
Cache get fully invalidated whenever the regions change, so there should be no risk of referencing a removed region, and this removes one hash map lookup for every region in the displayed buffer range.
This commit is contained in:
parent
af66a95ef8
commit
6984340936
|
@ -1910,10 +1910,7 @@ public:
|
||||||
if (apply_default and last_begin < begin->begin)
|
if (apply_default and last_begin < begin->begin)
|
||||||
apply_highlighter(correct(last_begin), correct(begin->begin), *default_region_it->value);
|
apply_highlighter(correct(last_begin), correct(begin->begin), *default_region_it->value);
|
||||||
|
|
||||||
auto it = m_regions.find(begin->region);
|
apply_highlighter(correct(begin->begin), correct(begin->end), *begin->highlighter);
|
||||||
if (it == m_regions.end())
|
|
||||||
continue;
|
|
||||||
apply_highlighter(correct(begin->begin), correct(begin->end), *it->value);
|
|
||||||
last_begin = begin->end;
|
last_begin = begin->end;
|
||||||
}
|
}
|
||||||
if (apply_default and last_begin < display_range.end)
|
if (apply_default and last_begin < display_range.end)
|
||||||
|
@ -2040,32 +2037,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Region
|
|
||||||
{
|
|
||||||
BufferCoord begin;
|
|
||||||
BufferCoord end;
|
|
||||||
StringView region;
|
|
||||||
};
|
|
||||||
using RegionList = Vector<Region, MemoryDomain::Highlight>;
|
|
||||||
|
|
||||||
struct RegexKey
|
|
||||||
{
|
|
||||||
StringView regex;
|
|
||||||
bool match_captures;
|
|
||||||
|
|
||||||
friend size_t hash_value(const RegexKey& key) { return hash_values(key.regex, key.match_captures); }
|
|
||||||
friend bool operator==(const RegexKey&, const RegexKey&) = default;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Cache
|
|
||||||
{
|
|
||||||
size_t buffer_timestamp = 0;
|
|
||||||
size_t regions_timestamp = 0;
|
|
||||||
LineRangeSet ranges;
|
|
||||||
HashMap<RegexKey, RegexMatchList> matches;
|
|
||||||
HashMap<BufferRange, RegionList, MemoryDomain::Highlight> regions;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct RegionHighlighter : public Highlighter
|
struct RegionHighlighter : public Highlighter
|
||||||
{
|
{
|
||||||
RegionHighlighter(std::unique_ptr<Highlighter>&& delegate,
|
RegionHighlighter(std::unique_ptr<Highlighter>&& delegate,
|
||||||
|
@ -2134,6 +2105,32 @@ private:
|
||||||
bool m_default = false;
|
bool m_default = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Region
|
||||||
|
{
|
||||||
|
BufferCoord begin;
|
||||||
|
BufferCoord end;
|
||||||
|
RegionHighlighter* highlighter;
|
||||||
|
};
|
||||||
|
using RegionList = Vector<Region, MemoryDomain::Highlight>;
|
||||||
|
|
||||||
|
struct RegexKey
|
||||||
|
{
|
||||||
|
StringView regex;
|
||||||
|
bool match_captures;
|
||||||
|
|
||||||
|
friend size_t hash_value(const RegexKey& key) { return hash_values(key.regex, key.match_captures); }
|
||||||
|
friend bool operator==(const RegexKey&, const RegexKey&) = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Cache
|
||||||
|
{
|
||||||
|
size_t buffer_timestamp = 0;
|
||||||
|
size_t regions_timestamp = 0;
|
||||||
|
LineRangeSet ranges;
|
||||||
|
HashMap<RegexKey, RegexMatchList> matches;
|
||||||
|
HashMap<BufferRange, RegionList, MemoryDomain::Highlight> regions;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
using RegionAndMatch = std::pair<size_t, RegexMatchList::const_iterator>;
|
using RegionAndMatch = std::pair<size_t, RegexMatchList::const_iterator>;
|
||||||
|
|
||||||
|
@ -2367,24 +2364,24 @@ private:
|
||||||
for (auto begin = find_next_begin(cache, range.begin); begin; )
|
for (auto begin = find_next_begin(cache, range.begin); begin; )
|
||||||
{
|
{
|
||||||
auto& [index, beg_it] = *begin;
|
auto& [index, beg_it] = *begin;
|
||||||
auto& [name, region] = m_regions.item(index);
|
auto& region = *m_regions.item(index).value;
|
||||||
auto& end_matches = cache.matches.get(RegexKey{region->m_end, region->match_capture()});
|
auto& end_matches = cache.matches.get(RegexKey{region.m_end, region.match_capture()});
|
||||||
auto& recurse_matches = region->m_recurse.empty() ?
|
auto& recurse_matches = region.m_recurse.empty() ?
|
||||||
empty_matches : cache.matches.get(RegexKey{region->m_recurse, region->match_capture()});
|
empty_matches : cache.matches.get(RegexKey{region.m_recurse, region.match_capture()});
|
||||||
|
|
||||||
auto end_it = find_matching_end(buffer, beg_it->end_coord(), end_matches, recurse_matches,
|
auto end_it = find_matching_end(buffer, beg_it->end_coord(), end_matches, recurse_matches,
|
||||||
region->match_capture() ? beg_it->capture(buffer) : Optional<StringView>{});
|
region.match_capture() ? beg_it->capture(buffer) : Optional<StringView>{});
|
||||||
|
|
||||||
if (end_it == end_matches.end() or end_it->end_coord() >= range.end) // region continue past range end
|
if (end_it == end_matches.end() or end_it->end_coord() >= range.end) // region continue past range end
|
||||||
{
|
{
|
||||||
auto begin_coord = beg_it->begin_coord();
|
auto begin_coord = beg_it->begin_coord();
|
||||||
if (begin_coord < range.end)
|
if (begin_coord < range.end)
|
||||||
regions.push_back({begin_coord, range.end, name});
|
regions.push_back({begin_coord, range.end, ®ion});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto end_coord = end_it->end_coord();
|
auto end_coord = end_it->end_coord();
|
||||||
regions.push_back({beg_it->begin_coord(), end_coord, name});
|
regions.push_back({beg_it->begin_coord(), end_coord, ®ion});
|
||||||
|
|
||||||
// With empty begin and end matches (for example if the regexes
|
// With empty begin and end matches (for example if the regexes
|
||||||
// are /"\K/ and /(?=")/), that case can happen, and would
|
// are /"\K/ and /(?=")/), that case can happen, and would
|
||||||
|
|
Loading…
Reference in New Issue
Block a user