Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(417)

Unified Diff: third_party/buildbot_8_4p1/README.chromium

Issue 9703108: Switch to the good LRU implementation. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build/
Patch Set: Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/buildbot_8_4p1/README.chromium
===================================================================
--- third_party/buildbot_8_4p1/README.chromium (revision 127129)
+++ third_party/buildbot_8_4p1/README.chromium (working copy)
@@ -1199,3 +1199,149 @@
kwargs['logfiles'] = self.logfiles
# check for the usePTY flag
+
+For performance, switch to the good LRU cache implementation.
+
+Index: buildbot/status/builder.py
+===================================================================
+--- buildbot/status/builder.py (revision 127129)
++++ buildbot/status/builder.py (working copy)
+@@ -86,8 +86,10 @@
+ self.currentBuilds = []
+ self.nextBuild = None
+ self.watchers = []
+- self.buildCache = weakref.WeakValueDictionary()
+- self.buildCache_LRU = []
++ #self.buildCache = weakref.WeakValueDictionary()
++ #self.buildCache_LRU = []
++ self.buildCache = util.lru.AsyncLRUCache(self.cacheMiss,
++ self.buildCacheSize)
+ self.logCompressionLimit = False # default to no compression for tests
+ self.logCompressionMethod = "bz2"
+ self.logMaxSize = None # No default limit
+@@ -103,7 +105,7 @@
+ d = styles.Versioned.__getstate__(self)
+ d['watchers'] = []
+ del d['buildCache']
+- del d['buildCache_LRU']
++ #del d['buildCache_LRU']
+ for b in self.currentBuilds:
+ b.saveYourself()
+ # TODO: push a 'hey, build was interrupted' event
+@@ -119,8 +121,10 @@
+ # when loading, re-initialize the transient stuff. Remember that
+ # upgradeToVersion1 and such will be called after this finishes.
+ styles.Versioned.__setstate__(self, d)
+- self.buildCache = weakref.WeakValueDictionary()
+- self.buildCache_LRU = []
++ #self.buildCache = weakref.WeakValueDictionary()
++ #self.buildCache_LRU = []
++ self.buildCache = util.lru.AsyncLRUCache(self.cacheMiss,
++ self.buildCacheSize)
+ self.currentBuilds = []
+ self.watchers = []
+ self.slavenames = []
+@@ -132,6 +136,7 @@
+ # gets pickled and unpickled.
+ if buildmaster.buildCacheSize is not None:
+ self.buildCacheSize = buildmaster.buildCacheSize
++ self.buildCache.set_max_size(buildmaster.buildCacheSize)
+
+ def upgradeToVersion1(self):
+ if hasattr(self, 'slavename'):
+@@ -186,33 +191,24 @@
+ except:
+ log.msg("unable to save builder %s" % self.name)
+ log.err()
+-
+
++
+ # build cache management
+
+ def makeBuildFilename(self, number):
+ return os.path.join(self.basedir, "%d" % number)
+
+- def touchBuildCache(self, build):
+- self.buildCache[build.number] = build
+- if build in self.buildCache_LRU:
+- self.buildCache_LRU.remove(build)
+- self.buildCache_LRU = self.buildCache_LRU[-(self.buildCacheSize-1):] + [ build ]
+- return build
++# def touchBuildCache(self, build):
++# self.buildCache[build.number] = build
++# if build in self.buildCache_LRU:
++# self.buildCache_LRU.remove(build)
++# self.buildCache_LRU = self.buildCache_LRU[-(self.buildCacheSize-1):] + [ build ]
++# return build
+
+ def getBuildByNumber(self, number):
+- # first look in currentBuilds
+- for b in self.currentBuilds:
+- if b.number == number:
+- return self.touchBuildCache(b)
++ return self.buildCache.get(number)
+
+- # then in the buildCache
+- if number in self.buildCache:
+- metrics.MetricCountEvent.log("buildCache.hits", 1)
+- return self.touchBuildCache(self.buildCache[number])
+- metrics.MetricCountEvent.log("buildCache.misses", 1)
+-
+- # then fall back to loading it from disk
++ def loadBuildFromFile(self, number):
+ filename = self.makeBuildFilename(number)
+ try:
+ log.msg("Loading builder %s's build %d from on-disk pickle"
+@@ -235,12 +231,23 @@
+ build.upgradeLogfiles()
+ # check that logfiles exist
+ build.checkLogfiles()
+- return self.touchBuildCache(build)
++ #return self.touchBuildCache(build)
++ return build
+ except IOError:
+ raise IndexError("no such build %d" % number)
+ except EOFError:
+ raise IndexError("corrupted build pickle %d" % number)
+
++ def cacheMiss(self, number):
++ # first look in currentBuilds
++ for b in self.currentBuilds:
++ if b.number == number:
++ #return self.touchBuildCache(b)
++ return defer.succeed(b)
++
++ # then fall back to loading it from disk
++ return threads.deferToThread(self.loadBuildFromFile, number)
++
+ def prune(self, events_only=False):
+ # begin by pruning our own events
+ self.events = self.events[-self.eventHorizon:]
+@@ -287,7 +294,7 @@
+ is_logfile = True
+
+ if num is None: continue
+- if num in self.buildCache: continue
++ if num in self.buildCache.cache: continue
+
+ if (is_logfile and num < earliest_log) or num < earliest_build:
+ pathname = os.path.join(self.basedir, filename)
+@@ -510,7 +517,8 @@
+ assert s.number == self.nextBuildNumber - 1
+ assert s not in self.currentBuilds
+ self.currentBuilds.append(s)
+- self.touchBuildCache(s)
++ #self.touchBuildCache(s)
++ self.buildCache.put(s.number, s)
+
+ # now that the BuildStatus is prepared to answer queries, we can
+ # announce the new build to all our watchers
+@@ -620,7 +628,7 @@
+ # Collect build numbers.
+ # Important: Only grab the *cached* builds numbers to reduce I/O.
+ current_builds = [b.getNumber() for b in self.currentBuilds]
+- cached_builds = list(set(self.buildCache.keys() + current_builds))
++ cached_builds = list(set(self.buildCache.cache.keys() + current_builds))
+ cached_builds.sort()
+ result['cachedBuilds'] = cached_builds
+ result['currentBuilds'] = current_builds

Powered by Google App Engine
This is Rietveld 408576698