... |
... |
@@ -20,6 +20,7 @@ |
20
|
20
|
import os
|
21
|
21
|
import pickle
|
22
|
22
|
import hashlib
|
|
23
|
+import io
|
23
|
24
|
|
24
|
25
|
from contextlib import contextmanager
|
25
|
26
|
from collections import namedtuple
|
... |
... |
@@ -53,8 +54,6 @@ class BstUnpickler(pickle.Unpickler): |
53
|
54
|
def persistent_load(self, pid):
|
54
|
55
|
type_tag, key_id = pid
|
55
|
56
|
if type_tag == "Project":
|
56
|
|
- # XXX: This doesn't actually help, we need to load the junction
|
57
|
|
- # to create the project
|
58
|
57
|
for project in self._context.get_projects():
|
59
|
58
|
if key_id == project.name:
|
60
|
59
|
return project
|
... |
... |
@@ -66,7 +65,27 @@ class BstUnpickler(pickle.Unpickler): |
66
|
65
|
|
67
|
66
|
|
68
|
67
|
CachedProject = namedtuple('CachedProject', ['path', 'project_sum', 'elements'])
|
69
|
|
-CachedYaml = namedtuple('CachedYaml', ['key', 'contents'])
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+class CachedYaml():
|
|
71
|
+ def __init__(self, key, contents):
|
|
72
|
+ self.key = key
|
|
73
|
+ self.contents = contents
|
|
74
|
+ self.pickled_contents = None
|
|
75
|
+
|
|
76
|
+ # Intercept and return the pickled object
|
|
77
|
+ def __getstate__(self):
|
|
78
|
+ data = self.__dict__.copy()
|
|
79
|
+ if not self.pickled_contents:
|
|
80
|
+ # Pickle self.contents and store it as self.pickled_contents
|
|
81
|
+ picklestream = io.BytesIO()
|
|
82
|
+ BstPickler(picklestream).dump(self.contents)
|
|
83
|
+ provenance = _yaml.node_get_provenance(self.contents)
|
|
84
|
+ project = provenance.filename.project
|
|
85
|
+ data['pickled_contents'] = picklestream
|
|
86
|
+ data['contents'] = None
|
|
87
|
+
|
|
88
|
+ return data
|
70
|
89
|
|
71
|
90
|
|
72
|
91
|
class YamlCache():
|
... |
... |
@@ -86,12 +105,15 @@ class YamlCache(): |
86
|
105
|
if filepath in project_cache.elements:
|
87
|
106
|
cachedyaml = project_cache.elements[filepath]
|
88
|
107
|
if cachedyaml.key == key:
|
|
108
|
+ if not cachedyaml.contents:
|
|
109
|
+ cachedyaml.pickled_contents.seek(0)
|
|
110
|
+ cachedyaml.contents = BstUnpickler(cachedyaml.pickled_contents, project._context).load()
|
89
|
111
|
return _yaml.node_copy(cachedyaml.contents)
|
90
|
112
|
return None
|
91
|
113
|
|
92
|
114
|
def put(self, project, filepath, key, value):
|
93
|
|
- if project.name in self.project_caches:
|
94
|
|
- # XXX: Needs a check that the project hasn't changed
|
|
115
|
+ if project.name in self.project_caches \
|
|
116
|
+ and project.shasum == self.project_caches[project.name].project_sum:
|
95
|
117
|
project_cache = self.project_caches[project.name]
|
96
|
118
|
else:
|
97
|
119
|
project_cache = self.project_caches[project.name] = CachedProject(project.directory, project.shasum, {})
|