performance: faster autorefs URL membership check

Signed-off-by: Timothée Mazzucotelli <dev@pawamoy.fr>
This commit is contained in:
Timothée Mazzucotelli
2026-09-01 18:54:43 +02:00
committed by squidfunk
parent 965351d939
commit af0ca2eeb1
2 changed files with 47 additions and 21 deletions
+33 -7
View File
@@ -117,6 +117,34 @@ class TestStore:
"external": "https://example.com/external"
}
def test_urls_are_ordered_and_unique(self) -> None:
"""Candidate URLs preserve registration order without duplicates."""
store = get_autorefs_store()
page = Page("page", "page.html")
store.register_anchor(page, "identifier", "first")
store.register_anchor(page, "identifier", "second")
store.register_anchor(page, "identifier", "first")
assert get_autorefs_page_data("page")["primary"] == {
"identifier": ["page#first", "page#second"]
}
def test_page_registrations_remove_urls(self) -> None:
"""Reprocessing a page removes its previously registered URLs."""
store = get_autorefs_store()
first_page = Page("first", "first.html")
second_page = Page("second", "second.html")
store.register_anchor(first_page, "identifier", "anchor")
store.register_anchor(second_page, "identifier", "anchor")
store.set_page(first_page)
assert get_autorefs_page_data("first")["primary"] == {}
assert get_autorefs_page_data("second")["primary"] == {
"identifier": ["second#anchor"]
}
# ---------------------------------------------------------------------------
# Inline processor
@@ -415,8 +443,7 @@ class TestAnchorsTreeprocessor:
[](){#alias10}
"""),
)
store = get_autorefs_store()
assert store._primary_url_map == {
assert get_autorefs_page_data("page")["primary"] == {
"foo": ["page#heading-foo"],
"heading-foo": ["page#heading-foo"],
"bar": ["page#bar"],
@@ -474,8 +501,7 @@ class TestAnchorsTreeprocessor:
## Heading baz
"""),
)
store = get_autorefs_store()
assert store._primary_url_map == {
assert get_autorefs_page_data("page")["primary"] == {
"heading-foo": ["page#heading-foo"],
"heading-bar": ["page#heading-bar"],
"heading-baz": ["page#heading-baz"],
@@ -510,9 +536,9 @@ class TestHeadingsTreeprocessor:
def test_register_heading(self, md: Markdown) -> None:
"""A single heading is registered under its toc-generated slug."""
md.convert("## Foo")
store = get_autorefs_store()
assert "foo" in store._primary_url_map
assert store._primary_url_map["foo"] == ["page#foo"]
assert get_autorefs_page_data("page")["primary"]["foo"] == [
"page#foo"
]
@pytest.mark.parametrize(
"md",
+14 -14
View File
@@ -27,7 +27,7 @@ import re
from abc import ABC, abstractmethod
from dataclasses import dataclass
from html import escape
from typing import TYPE_CHECKING, Any
from typing import TYPE_CHECKING, Any, TypeAlias
from xml.etree.ElementTree import Element
from markdown.core import Markdown
@@ -59,6 +59,11 @@ if TYPE_CHECKING:
HTAGS = {"h1", "h2", "h3", "h4", "h5", "h6"}
# URL order determines which target wins when several are equally
# suitable. Dict keys give us that order plus constant-time lookups.
OrderedSet: TypeAlias = dict[str, None]
URLMap: TypeAlias = dict[str, OrderedSet]
# ----------------------------------------------------------------------------
# Globals
@@ -81,8 +86,8 @@ class AutorefsStore:
self.scan_toc: bool = True
self.record_backlinks: bool = False
self._primary_url_map: dict[str, list[str]] = {}
self._secondary_url_map: dict[str, list[str]] = {}
self._primary_url_map: URLMap = {}
self._secondary_url_map: URLMap = {}
self._abs_url_map: dict[str, str] = {}
self._title_map: dict[str, str] = {}
self._page_registrations: dict[str, set[tuple[bool, str, str]]] = {}
@@ -118,7 +123,7 @@ class AutorefsStore:
@staticmethod
def _pop_urls(
url_map: dict[str, list[str]],
url_map: URLMap,
registrations: set[tuple[bool, str, str]],
primary: bool,
) -> dict[str, list[str]]:
@@ -130,12 +135,11 @@ class AutorefsStore:
result: dict[str, list[str]] = {}
for identifier, selected_urls in selected.items():
urls = url_map.get(identifier, [])
urls = url_map.get(identifier, {})
result[identifier] = [url for url in urls if url in selected_urls]
remaining = [url for url in urls if url not in selected_urls]
if remaining:
url_map[identifier] = remaining
else:
for url in selected_urls:
urls.pop(url, None)
if not urls:
url_map.pop(identifier, None)
return result
@@ -150,11 +154,7 @@ class AutorefsStore:
) -> None:
url = f"{page.url}#{anchor or identifier}"
url_map = self._primary_url_map if primary else self._secondary_url_map
if identifier in url_map:
if url not in url_map[identifier]:
url_map[identifier].append(url)
else:
url_map[identifier] = [url]
url_map.setdefault(identifier, {})[url] = None
self._page_registrations.setdefault(page.url, set()).add(
(primary, identifier, url)
)