Mercurial > piecrust2
comparison piecrust/data/providersdata.py @ 440:32c7c2d219d2
performance: Refactor how data is managed to reduce copying.
* Make use of `collections.abc.Mapping` to better identify things that are
supposed to look like dictionaries.
* Instead of handling "overlay" of data in a dict tree in each different data
object, make all objects `Mapping`s and handle merging at a higher level
with the new `MergedMapping` object.
* Since this new object is read-only, remove the need for deep-copying of
app and page configurations.
* Split data classes into separate modules.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Sun, 28 Jun 2015 08:22:39 -0700 |
parents | |
children | aca04e175488 |
comparison
equal
deleted
inserted
replaced
439:c0700c6d9545 | 440:32c7c2d219d2 |
---|---|
1 import re | |
2 import collections.abc | |
3 | |
4 | |
5 re_endpoint_sep = re.compile(r'[\/\.]') | |
6 | |
7 | |
8 class DataProvidersData(collections.abc.Mapping): | |
9 def __init__(self, page): | |
10 self._page = page | |
11 self._dict = None | |
12 | |
13 def __getitem__(self, name): | |
14 self._load() | |
15 return self._dict[name] | |
16 | |
17 def __iter__(self): | |
18 self._load() | |
19 return iter(self._dict) | |
20 | |
21 def __len__(self): | |
22 self._load() | |
23 return len(self._dict) | |
24 | |
25 def _load(self): | |
26 if self._dict is not None: | |
27 return | |
28 | |
29 self._dict = {} | |
30 for source in self._page.app.sources: | |
31 endpoint_bits = re_endpoint_sep.split(source.data_endpoint) | |
32 endpoint = self._dict | |
33 for e in endpoint_bits[:-1]: | |
34 if e not in endpoint: | |
35 endpoint[e] = {} | |
36 endpoint = endpoint[e] | |
37 override = endpoint.get(endpoint_bits[-1]) | |
38 provider = source.buildDataProvider(self._page, override) | |
39 endpoint[endpoint_bits[-1]] = provider |