Skip to content

Commit 6689927

Browse files
committed
Consolidate caching logic
1 parent 7021e10 commit 6689927

File tree

3 files changed

+55
-16
lines changed

3 files changed

+55
-16
lines changed

data_prototype/artist.py

+28
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from bisect import insort
2+
from collections import OrderedDict
23
from typing import Sequence
34
from contextlib import contextmanager
45

@@ -33,6 +34,8 @@ def __init__(
3334
**{"x": np.asarray([0, 1]), "y": np.asarray([0, 1])}
3435
)
3536

37+
self._caches = {}
38+
3639
def draw(self, renderer, graph: Graph) -> None:
3740
return
3841

@@ -119,6 +122,31 @@ def pick(self, mouseevent, graph: Graph | None = None):
119122
# which do not have an axes property but children might
120123
a.pick(mouseevent, graph)
121124

125+
def _get_dynamic_graph(self, query):
126+
return Graph([])
127+
128+
def _query_and_eval(self, container, requires, graph, cacheset=None):
129+
g = graph + self._graph
130+
query, q_cache_key = container.query(g)
131+
g = g + self._get_dynamic_graph(query)
132+
g_cache_key = g.cache_key()
133+
cache_key = (g_cache_key, q_cache_key)
134+
135+
cache = None
136+
if cacheset is not None:
137+
cache = self._caches.setdefault(cacheset, OrderedDict())
138+
if cache_key in cache:
139+
return cache[cache_key]
140+
141+
conv = g.evaluator(container.describe(), requires)
142+
ret = conv.evaluate(query)
143+
144+
if cache is not None:
145+
cache[cache_key] = ret
146+
# TODO prune
147+
148+
return ret
149+
122150

123151
class CompatibilityArtist:
124152
"""A compatibility shim to ducktype as a classic Matplotlib Artist.

data_prototype/conversion_edge.py

+9
Original file line numberDiff line numberDiff line change
@@ -418,3 +418,12 @@ def __add__(self, other: Graph) -> Graph:
418418
aother = {k: v for k, v in other._aliases}
419419
aliases = tuple((aself | aother).items())
420420
return Graph(self._edges + other._edges, aliases)
421+
422+
def cache_key(self):
423+
"""A cache key representing the graph.
424+
425+
Current implementation is a new UUID, that is to say uncachable.
426+
"""
427+
import uuid
428+
429+
return str(uuid.uuid4())

data_prototype/patches.py

+18-16
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@
77

88
from .wrappers import ProxyWrapper, _stale_wrapper
99

10-
from .containers import DataContainer
11-
1210
from .artist import Artist, _renderer_group
1311
from .description import Desc
12+
from .containers import DataContainer
1413
from .conversion_edge import Graph, CoordinateEdge, DefaultEdge
1514

1615

@@ -19,7 +18,7 @@ def __init__(self, container, edges=None, **kwargs):
1918
super().__init__(container, edges, **kwargs)
2019

2120
scalar = Desc((), "display") # ... this needs thinking...
22-
edges = [
21+
def_edges = [
2322
CoordinateEdge.from_coords("xycoords", {"x": "auto", "y": "auto"}, "data"),
2423
CoordinateEdge.from_coords("codes", {"codes": "auto"}, "display"),
2524
CoordinateEdge.from_coords("facecolor", {"color": Desc(())}, "display"),
@@ -34,12 +33,11 @@ def __init__(self, container, edges=None, **kwargs):
3433
DefaultEdge.from_default_value("alpha_def", "alpha", scalar, 1),
3534
DefaultEdge.from_default_value("hatch_def", "hatch", scalar, None),
3635
]
37-
self._graph = self._graph + Graph(edges)
36+
self._graph = self._graph + Graph(def_edges)
3837

3938
def draw(self, renderer, graph: Graph) -> None:
4039
if not self.get_visible():
4140
return
42-
g = graph + self._graph
4341
desc = Desc(("N",), "display")
4442
scalar = Desc((), "display") # ... this needs thinking...
4543

@@ -55,18 +53,14 @@ def draw(self, renderer, graph: Graph) -> None:
5553
"alpha": scalar,
5654
}
5755

58-
# copy from line
59-
conv = g.evaluator(self._container.describe(), require)
60-
query, _ = self._container.query(g)
61-
evald = conv.evaluate(query)
62-
63-
clip_conv = g.evaluator(
64-
self._clip_box.describe(),
65-
{"x": Desc(("N",), "display"), "y": Desc(("N",), "display")},
56+
evald = self._query_and_eval(
57+
self._container, require, graph, cacheset="default"
6658
)
67-
clip_query, _ = self._clip_box.query(g)
68-
clipx, clipy = clip_conv.evaluate(clip_query).values()
69-
# copy from line
59+
60+
clip_req = {"x": Desc(("N",), "display"), "y": Desc(("N",), "display")}
61+
clipx, clipy = self._query_and_eval(
62+
self._clip_box, clip_req, graph, cacheset="clip"
63+
).values()
7064

7165
path = mpath.Path._fast_from_codes_and_verts(
7266
verts=np.vstack([evald["x"], evald["y"]]).T, codes=evald["codes"]
@@ -111,6 +105,14 @@ def draw(self, renderer, graph: Graph) -> None:
111105
gc.restore()
112106

113107

108+
class RectangleContainer(DataContainer): ...
109+
110+
111+
class Rectangle(Patch):
112+
def __init__(self, container, edges=None, **kwargs):
113+
super().__init__(container, edges, **kwargs)
114+
115+
114116
class PatchWrapper(ProxyWrapper):
115117
_wrapped_class = _Patch
116118
_privtized_methods = (

0 commit comments

Comments
 (0)