Rev 410: Play around with making merge_points a lazy property. in http://bazaar.launchpad.net/~jameinel/loggerhead/history_db
John Arbash Meinel
john at arbash-meinel.com
Wed Apr 14 18:08:16 BST 2010
At http://bazaar.launchpad.net/~jameinel/loggerhead/history_db
------------------------------------------------------------
revno: 410
revision-id: john at arbash-meinel.com-20100414170757-d88fac0am1lekqo8
parent: john at arbash-meinel.com-20100413205820-ctgno1xbshj4803o
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: history_db
timestamp: Wed 2010-04-14 12:07:57 -0500
message:
Play around with making merge_points a lazy property.
At the moment, it didn't seem 100% correct anyway. And it allows us to avoid
loading the whole history (at least until I figure out how to compute it more
cheaply.)
-------------- next part --------------
=== modified file 'loggerhead/apps/branch.py'
--- a/loggerhead/apps/branch.py 2010-03-25 16:19:24 +0000
+++ b/loggerhead/apps/branch.py 2010-04-14 17:07:57 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2008, 2009 Canonical Ltd.
+# Copyright (C) 2008, 2009, 2010 Canonical Ltd.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -19,6 +19,7 @@
import logging
import urllib
import sys
+import time
import bzrlib.branch
import bzrlib.errors
@@ -76,7 +77,7 @@
" continuing without using a cache")
else:
file_cache = FileChangeCache(cache_path)
- revinfo_disk_cache = RevInfoDiskCache(cache_path)
+ revinfo_disk_cache = None # RevInfoDiskCache(cache_path)
return History(
self.branch, self.graph_cache, file_cache=file_cache,
revinfo_disk_cache=revinfo_disk_cache, cache_key=self.friendly_name)
@@ -160,14 +161,22 @@
cls = self.controllers_dict.get(path)
if cls is None:
raise httpexceptions.HTTPNotFound()
- self.branch.lock_read()
- try:
+ def do_stuff():
+ self.branch.lock_read()
try:
- c = cls(self, self.get_history)
- return c(environ, start_response)
- except:
- environ['exc_info'] = sys.exc_info()
- environ['branch'] = self
- raise
- finally:
- self.branch.unlock()
+ try:
+ c = cls(self, self.get_history)
+ return c(environ, start_response)
+ except:
+ environ['exc_info'] = sys.exc_info()
+ environ['branch'] = self
+ raise
+ finally:
+ self.branch.unlock()
+ from bzrlib.commands import apply_lsprofiled
+ t = time.time()
+ ## res = apply_lsprofiled(',,prof.txt', do_stuff)
+ res = do_stuff()
+ t = time.time() - t
+ self.log.warn('do_stuff() took %.3fs' % (t,))
+ return res
=== modified file 'loggerhead/history.py'
--- a/loggerhead/history.py 2010-04-13 20:58:20 +0000
+++ b/loggerhead/history.py 2010-04-14 17:07:57 +0000
@@ -298,10 +298,10 @@
self.last_revid = branch.last_revision()
# XXX: Remove the whole-history type operations
- caches = [RevInfoMemoryCache(whole_history_data_cache)]
- if revinfo_disk_cache:
- caches.append(revinfo_disk_cache)
- self._load_whole_history_data(caches, cache_key)
+ ### caches = [RevInfoMemoryCache(whole_history_data_cache)]
+ ### if revinfo_disk_cache:
+ ### caches.append(revinfo_disk_cache)
+ ### self._load_whole_history_data(caches, cache_key)
@property
def has_revisions(self):
@@ -345,9 +345,16 @@
# TODO: I think we could just call
# self._branch.repository.iter_reverse_revision_history(start_revid)
# or something like that.
- while tip_revid is not None:
- yield tip_revid
- tip_revid = self._get_lh_parent(tip_revid)
+ # TODO: This operation appears at the top of profiling currently
+ # when loading the 'changes' page. Especially unfortunate
+ # given that we only show ~20 revs...
+ if start_revid == self.last_revid:
+ history = reversed(self._branch.revision_history())
+ else:
+ history = self._branch.repository.iter_reverse_revision_history(
+ start_revid)
+ for rev_id in history:
+ yield rev_id
return
revid_set = set(revid_list)
@@ -668,15 +675,23 @@
# some data needs to be recalculated each time, because it may
# change as new revisions are added.
- for change in changes:
+ def merge_revids_prop(change, attr):
+ # TODO: In testing, this doesn't seem to do what I expected anyway.
+ # So for now, just skip the work
+ return []
merge_revids = self.simplify_merge_point_list(
- self.get_merge_point_list(change.revid))
- change.merge_points = [
- util.Container(revid=r,
- revno=self.get_revno(r)) for r in merge_revids]
+ self.get_merge_point_list(change.revid))
+ points = [util.Container(revid=r, revno=self.get_revno(r))
+ for r in merge_revids]
+ self.log.warn('merge_revids_prop triggered for %s => %s'
+ % (change.revid, points))
+ return points
+ for change in changes:
+ change._set_property('merge_points', merge_revids_prop)
if len(change.parents) > 0:
- change.parents = [util.Container(revid=r,
- revno=self.get_revno(r)) for r in change.parents]
+ change.parents = [
+ util.Container(revid=r, revno=self.get_revno(r))
+ for r in change.parents]
change.revno = self.get_revno(change.revid)
parity = 0
=== modified file 'loggerhead/util.py'
--- a/loggerhead/util.py 2010-03-25 16:19:24 +0000
+++ b/loggerhead/util.py 2010-04-14 17:07:57 +0000
@@ -137,6 +137,7 @@
"""
def __init__(self, _dict=None, **kw):
+ self._properties = {}
if _dict is not None:
for key, value in _dict.iteritems():
setattr(self, key, value)
@@ -153,6 +154,22 @@
out += '}'
return out
+ def __getattr__(self, attr):
+ """Used for handling things that aren't already available."""
+ if attr in self._properties:
+ val = self._properties[attr](self, attr)
+ setattr(self, attr, val)
+ return val
+ raise AttributeError('No attribute: %s' % (attr,))
+
+ def _set_property(self, attr, prop_func):
+ """Set a function that will be called when an attribute is desired.
+
+ We will cache the return value, so the function call should be
+ idempotent. We will pass 'self' and the 'attr' name when triggered.
+ """
+ self._properties[attr] = prop_func
+
def trunc(text, limit=10):
if len(text) <= limit:
More information about the bazaar-commits
mailing list