Rev 4517: Copy the implementation over to the Pyrex version. in http://bazaar.launchpad.net/~jameinel/bzr/1.17-rework-annotate
John Arbash Meinel
john at arbash-meinel.com
Mon Jul 6 20:16:48 BST 2009
At http://bazaar.launchpad.net/~jameinel/bzr/1.17-rework-annotate
------------------------------------------------------------
revno: 4517
revision-id: john at arbash-meinel.com-20090706191619-lycpcdwo73j2g1cg
parent: john at arbash-meinel.com-20090706190526-4rn5l49rigy4wia2
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: 1.17-rework-annotate
timestamp: Mon 2009-07-06 14:16:19 -0500
message:
Copy the implementation over to the Pyrex version.
-------------- next part --------------
=== modified file 'bzrlib/_annotator_py.py'
--- a/bzrlib/_annotator_py.py 2009-07-06 18:59:24 +0000
+++ b/bzrlib/_annotator_py.py 2009-07-06 19:16:19 +0000
@@ -35,7 +35,6 @@
def __init__(self, vf):
"""Create a new Annotator from a VersionedFile."""
self._vf = vf
- self._special_keys = set()
self._parent_map = {}
self._text_cache = {}
# Map from key => number of nexts that will be built from this key
@@ -93,7 +92,6 @@
# _heads_provider does some graph caching, so it is only valid while
# self._parent_map hasn't changed
self._heads_provider = None
- # self._parent_map.update(parent_map)
return vf_keys_needed, ann_keys_needed
def _get_needed_texts(self, key, pb=None):
@@ -226,7 +224,6 @@
def add_special_text(self, key, parent_keys, text):
"""Add a specific text to the graph."""
- self._special_keys.add(key)
self._parent_map[key] = parent_keys
self._text_cache[key] = osutils.split_lines(text)
self._heads_provider = None
=== modified file 'bzrlib/_annotator_pyx.pyx'
--- a/bzrlib/_annotator_pyx.pyx 2009-07-06 18:59:24 +0000
+++ b/bzrlib/_annotator_pyx.pyx 2009-07-06 19:16:19 +0000
@@ -63,24 +63,47 @@
cdef object counter
cdef object text_cache
cdef object stream
+ cdef object ann_keys
cdef object stream_len
cdef object pb
+ cdef int stream_is_consumed
+ cdef int ann_key_pos
- def __init__(self, stream, text_cache, stream_len, pb=None):
+ def __init__(self, stream, text_cache, stream_len, ann_keys, pb=None):
self.counter = 0
self.stream = stream
self.stream_len = stream_len
self.text_cache = text_cache
self.stream_len = stream_len
+ self.ann_keys = list(ann_keys)
self.pb = pb
+ self.stream_is_consumed = 0
+ self.ann_key_pos = 0
def __iter__(self):
return self
+ cdef _get_ann_text(self):
+ if self.ann_key_pos >= len(self.ann_keys):
+ raise StopIteration
+ key = self.ann_keys[self.ann_key_pos]
+ self.ann_key_pos = self.ann_key_pos + 1
+ lines = self.text_cache[key]
+ num_lines = len(lines)
+ return key, lines, num_lines
+
def __next__(self):
- record = self.stream.next()
+ if self.stream_is_consumed:
+ return self._get_ann_text()
+ try:
+ record = self.stream.next()
+ except StopIteration:
+ self.stream_is_consumed = 1
+ return self._get_ann_text()
if self.pb is not None:
self.pb.update('extracting', self.counter, self.stream_len)
+ if record.storage_kind == 'absent':
+ raise errors.RevisionNotPresent(record.key, None)
self.counter = self.counter + 1
lines = osutils.chunks_to_lines(record.get_bytes_as('chunked'))
num_lines = len(lines)
@@ -222,27 +245,59 @@
self._heads_provider = None
self._ann_tuple_cache = {}
+
+ def _update_needed_children(self, key, parent_keys):
+ for parent_key in parent_keys:
+ if parent_key in self._num_needed_children:
+ self._num_needed_children[parent_key] += 1
+ else:
+ self._num_needed_children[parent_key] = 1
+
def _get_needed_keys(self, key):
- graph = _mod_graph.Graph(self._vf)
- parent_map = {}
+ """Determine the texts we need to get from the backing vf.
+
+ :return: (vf_keys_needed, ann_keys_needed)
+ vf_keys_needed These are keys that we need to get from the vf
+ ann_keys_needed Texts which we have in self._text_cache but we
+ don't have annotations for. We need to yield these
+ in the proper order so that we can get proper
+ annotations.
+ """
+ parent_map = self._parent_map
# We need 1 extra copy of the node we will be looking at when we are
# done
self._num_needed_children[key] = 1
- for key, parent_keys in graph.iter_ancestry([key]):
- if parent_keys is None:
- continue
- parent_map[key] = parent_keys
- for parent_key in parent_keys:
- if parent_key in self._num_needed_children:
- self._num_needed_children[parent_key] += 1
+ vf_keys_needed = set()
+ ann_keys_needed = set()
+ needed_keys = set([key])
+ while needed_keys:
+ parent_lookup = []
+ next_parent_map = {}
+ for key in needed_keys:
+ if key in self._parent_map:
+ # We don't need to lookup this key in the vf
+ if key not in self._text_cache:
+ # Extract this text from the vf
+ vf_keys_needed.add(key)
+ elif key not in self._annotations_cache:
+ # We do need to annotate
+ ann_keys_needed.add(key)
+ next_parent_map[key] = self._parent_map[key]
else:
- self._num_needed_children[parent_key] = 1
- self._parent_map.update(parent_map)
- # _heads_provider does some graph caching, so it is only valid while
- # self._parent_map hasn't changed
- self._heads_provider = None
- keys = parent_map.keys()
- return keys
+ parent_lookup.append(key)
+ vf_keys_needed.add(key)
+ needed_keys = set()
+ next_parent_map.update(self._vf.get_parent_map(parent_lookup))
+ for key, parent_keys in next_parent_map.iteritems():
+ self._update_needed_children(key, parent_keys)
+ for key in parent_keys:
+ if key not in parent_map:
+ needed_keys.add(key)
+ parent_map.update(next_parent_map)
+ # _heads_provider does some graph caching, so it is only valid while
+ # self._parent_map hasn't changed
+ self._heads_provider = None
+ return vf_keys_needed, ann_keys_needed
def _get_needed_texts(self, key, pb=None):
"""Get the texts we need to properly annotate key.
@@ -253,11 +308,12 @@
matcher object we are using. Currently it is always 'lines' but
future improvements may change this to a simple text string.
"""
- keys = self._get_needed_keys(key)
+ keys, ann_keys = self._get_needed_keys(key)
if pb is not None:
pb.update('getting stream', 0, len(keys))
stream = self._vf.get_record_stream(keys, 'topological', True)
- iterator = _NeededTextIterator(stream, self._text_cache, len(keys), pb)
+ iterator = _NeededTextIterator(stream, self._text_cache, len(keys),
+ ann_keys, pb)
return iterator
def _get_parent_annotations_and_matches(self, key, text, parent_key):
@@ -364,6 +420,9 @@
def add_special_text(self, key, parent_keys, text):
"""Add a specific text to the graph."""
+ self._parent_map[key] = parent_keys
+ self._text_cache[key] = osutils.split_lines(text)
+ self._heads_provider = None
def annotate(self, key):
"""Return annotated fulltext for the given key."""
More information about the bazaar-commits
mailing list