[MERGE] faster log - hooray!
John Arbash Meinel
john at arbash-meinel.com
Wed Feb 4 14:16:07 GMT 2009
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Ian Clatworthy wrote:
...
> I didn't dig deep when the class matching failed. I simply jumped to
> the conclusion that the wrapper/lazy-delegate class was getting in
> the way, made the change to explicit importing and it all worked. :-(
Right, the specific issue is that doing:
lazy_import(globals(), """
from foo import bar
""")
...
if x == bar:
...
At this point, we have not accessed any attributes of bar, nor given it
any indication we have touched it. So the lazy object doesn't know it
needs to trigger. I worked hard such that doing "bar()" or "bar.X", etc
all trigger an import. I probably shouldn't have tried so hard.
Specifically, doing:
from module import klass
klass()
Works from a lazy import, because I override __call__. However
isinstance(foo, klass)
and
foo.__class__ == klass
Doesn't work because there is no attribute access I can trigger on.
Anyway, if we just stick to lazy importing *modules* we don't have any
problems. Because modules aren't useful on their own. You always (99.9%)
access an attribute.
...
...
...
>> + else:
>> + # We're following a development line starting at a merged revision.
>> + # We need to adjust depths down by the initial depth until we find
>> + # a depth less than it. Then we use that depth as the adjustment.
>> + # If and when we reach the mainline, depth adjustment ends.
>> + depth_adjustment = None
>> + for (rev_id, merge_depth, revno, end_of_merge
>> + ) in view_revisions:
>> + if depth_adjustment is None:
>> + depth_adjustment = merge_depth
>> + if depth_adjustment:
>> + if merge_depth < depth_adjustment:
>> + depth_adjustment = merge_depth
>> + merge_depth -= depth_adjustment
>> + yield rev_id, '.'.join(map(str, revno)), merge_depth
>>
>> ^- I think this actually needs to be a 2-pass arrangement. Where you
>> compute the overall depth_adjustment, and then adjust everything by that
>> value. Otherwise I think if you did:
>>
>> bzr log --long -r 1..1.2.3
>>
>> It would start logging 1.2.3 with a depth_adjustment of N, but then
>> finish logging mainline with a depth-adjustment of 0. Or was that the
>> specific goal? (logging it as though 1.2.3 was the mainline, but using
>> the numbering from the current branch tip?)
>
> My explicit goal is that logging -r 1..1.2.3 will show 1.2.3 at depth 0,
> it's merged revisions nested appropriately. We're genuinely treating
> 1.2.3 as the "tip" of the development line we're logging here. Using
> log --short -r1..1.2.3 will show that development line as flat and
> log --long -r1..1.2.3 should show the same line with any nested
> revisions below each merge.
>
> A multiple pass algorithm isn't required IMO. It also scales O(result)
> eliminating any chance of incremental output.
Sure, though I'll mention that this is a very concrete UI change, and
should be documented appropriately. I don't have any specific issues
with it, as I don't really care.
>
>> +def calculate_view_revisions(branch, start_revision, end_revision,
>> direction,
>> + specific_fileid, generate_merge_revisions,
>> allow_single_merge_revision):
>> + """Calculate the revisions to view.
>> +
>> + :return: An iterator of (revision_id, dotted_revno, merge_depth)
>> tuples OR
>> + a list of the same tuples.
>> + """
>> + # This method is no longer called by the main code path.
>> + # It is retained for API compatibility and may be deprecated
>> + # soon. IGC 20090116
>>
>> ^- If we aren't using it anymore, I'd rather deprecate it now rather
>> than waiting.
>
> I can't just yet because I'm pretty sure its used inside bzrlib for
> missing.py say. We also need to replace it with a public API we *do*
> want to support for bzrlib clients. There's a preview of what I'm
> thinking of (LogGenerator.iter_log_revisions()) in my log-dir branch
> above BTW, but that requires some debate with others (e.g. Vincent)
> and some evaluation by potential users like LoggerHead and qlog before
> it's made public. Oh, and dozens and dozens of interface tests. :-)
>
> I'll be sure to raise this in the covering letter for my log-dir patch.
>
The only instance of "calculate_view_revisions" I find in bzrlib is the
definition. I believe missing uses its own code (iter_log_revisions(),
IIRC). And a call in a test case.
>> def test_merges_nonsupporting_formatter(self):
>> + # This "feature" of log formatters is madness. If a log
>> + # formatter cannot display a dotted-revno, it ought to ignore it.
>> + # Otherwise, a linear sequence is always expected to be handled
>> now.
>> + raise KnownFailure('log formatters must support linear
>> sequences now')
>>
>> ^- I don't understand this change.
>
> The new code is less dumb than the old code so an overly restrictive test
> now fails. I need to ping the author that introduced this "feature" to
> see if his/her log formatter can be changed to make this (to me) weird
> limitation disappear. I can only guess that the driver was something like
> wanting a fixed-width revno column and the old dotted scheme (1.1.1.1.1)
> caused problems for logs of size > 1. Anyhow, removing this is on my
> list, just not near the top yet.
I believe the specific concern was that doing "bzr log --short -r 1.1.1"
used to raise a ValueError/IndexError exception without a nice message.
If we can show the revision now, then I think we can just nuke the whole
test.
>
> Once again, thanks for the insightful review. Apologies in sending this
> delayed response.
>
> Ian C.
>
John
=:->
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iEYEARECAAYFAkmJoycACgkQJdeBCYSNAAOZLQCeKPle7jWNOY9+aMzseZpvE8R0
ZE4AoMJIflE5afTap6lffYIOxEN5SJOK
=pXD0
-----END PGP SIGNATURE-----
More information about the bazaar
mailing list