[MERGE] Make log revision filtering pluggable.

John Arbash Meinel john at arbash-meinel.com
Wed Aug 27 05:31:00 BST 2008


John Arbash Meinel has voted tweak.
Status is now: Conditionally approved
Comment:
So, we still have to decide what "_foo" means, so as that conversation 
settles down we can decide what to name "log_adapters".

This actually also goes for all of the "make_*" adapters as well. Mostly 
because if they are going to be public, they should have tests, to 
ensure we don't accidentally change how they work.

For some reason, this doesn't seem right to me:
+    for batch in log_rev_iterator:
+        batch = iter(batch)
+        while True:
+            step = [detail for _, detail in zip(range(num), batch)]
+            if len(step) == 0:
+                break
+            yield step
+            num = min(int(num * 1.5), 200)

But it seems that iter(iterator) just returns "iterator" (as opposed to 
iter(list) or any other "iterable" rather than an "iterator").

It is technically slightly wrong, in that it will always break at an 
iterable boundary, but as this is the primary function that *does* the 
split up, it doesn't really matter.


Since it doesn't return an iterator of LogRevision objects, I would 
probably change the name to something like: 
"make_revision_tuple_iterators()".

And correspondingly change the names of "log_revision_iterator". 
Possibly call it "rev_tuple_iterator_iterator" though I wouldn't say I 
*like* that.

...

+def _generate_deltas(repository, log_rev_iterator):
+    for revs in log_rev_iterator:
+        revisions = [rev[1] for rev in revs]
+        deltas = repository.get_deltas_for_revisions(revisions)
+        revs = [(rev[0], rev[1], delta) for rev, delta in izip(revs, 
deltas)]
+        yield revs


^- This seems to assume that "revs" can be iterated 2 times. Which I 
don't think is guaranteed by your comments. As it should be an iterator, 
not a list.

If you want to change it so that it is always a list, that is fine, but
"An iterator over iterators of ((rev_id, revno, merge_depth), rev, 
delta)."

does not work for 2 passes. You could alternatively use:

revs = list(revs)
Or even "revs = tuple(revs)". (With the advantage that if revs is a 
tuple already, tuple(tuple) returns the object, while list(list) returns 
a *new* list.)

Stuff like this *might* be a reason to directly test all of these 
functions.

In general, you should either change how the api is declared (make it an 
iterator of lists), or make sure the functions properly only iterate 
over the lists once. You can chose which way works best for you.

Instead of special casing lists, why not use a generator comprehension 
here:
+    # Convert view_revisions into (view, None, None) groups to fit with
+    # the standard interface here.
+    if type(view_revisions) == list:
+        nones = [None] * len(view_revisions)
+        log_rev_iterator = iter([zip(view_revisions, nones, nones)])
+    else:
+        def _convert():
+            for view in view_revisions:
+                yield (view, None, None)
+        log_rev_iterator = iter([_convert()])


log_rev_iterator = iter([((view, None, None) for view in 
view_revisions)])

Unless you know specifically that there is a performance reason to 
special cases lists. In which case, you should make a comment about it.

in _filter_message_re, you unpack the structure

+def _filter_message_re(searchRE, log_rev_iterator):
+    for revs in log_rev_iterator:
+        new_revs = []
+        for (rev_id, revno, merge_depth), rev, delta in revs:


versus generate_deltas you address parts of the tuples:
+def _generate_deltas(repository, log_rev_iterator):
+    for revs in log_rev_iterator:
+        revisions = [rev[1] for rev in revs]

I find the former easier to read, though I suppose unpacking and 
repacking new tuples isn't strictly a good thing.

It might be nice to be a bit more consistent in how "log_rev_iterator" 
is handled.

So the only thing I'm strict on is that _generate_deltas is incorrect if 
"revs" is a pure iterator. The rest are suggestions to make things 
better, but are above and beyond the "better than what it is now".



For details, see: 
http://bundlebuggy.aaronbentley.com/project/bzr/request/%3C1219353364.31549.149.camel%40lifeless-64%3E
Project: Bazaar



More information about the bazaar mailing list