diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piecrust/data/providersdata.py	Sun Jun 28 08:22:39 2015 -0700
@@ -0,0 +1,39 @@
+import re
+import collections.abc
+
+
+re_endpoint_sep = re.compile(r'[\/\.]')
+
+
+class DataProvidersData(collections.abc.Mapping):
+    def __init__(self, page):
+        self._page = page
+        self._dict = None
+
+    def __getitem__(self, name):
+        self._load()
+        return self._dict[name]
+
+    def __iter__(self):
+        self._load()
+        return iter(self._dict)
+
+    def __len__(self):
+        self._load()
+        return len(self._dict)
+
+    def _load(self):
+        if self._dict is not None:
+            return
+
+        self._dict = {}
+        for source in self._page.app.sources:
+            endpoint_bits = re_endpoint_sep.split(source.data_endpoint)
+            endpoint = self._dict
+            for e in endpoint_bits[:-1]:
+                if e not in endpoint:
+                    endpoint[e] = {}
+                endpoint = endpoint[e]
+            override = endpoint.get(endpoint_bits[-1])
+            provider = source.buildDataProvider(self._page, override)
+            endpoint[endpoint_bits[-1]] = provider