| Index: third_party/buildbot_8_4p1/README.chromium
 | 
| diff --git a/third_party/buildbot_8_4p1/README.chromium b/third_party/buildbot_8_4p1/README.chromium
 | 
| index 2e79182bbd5ab615c5f42cb99a42892bb386b690..02dc085785c1ffe9b2d5aae7d8b07eca87374f5b 100644
 | 
| --- a/third_party/buildbot_8_4p1/README.chromium
 | 
| +++ b/third_party/buildbot_8_4p1/README.chromium
 | 
| @@ -2947,3 +2947,69 @@ index ed12ea0..32e1bd3 100644
 | 
|  
 | 
|       def __init__(self, **kwargs):
 | 
|           self.factory = (self.__class__, dict(kwargs))
 | 
| +
 | 
| +
 | 
| +diff --git a/third_party/buildbot_8_4p1/buildbot/status/web/status_json.py b/third_party/buildbot_8_4p1/buildbot/status/web/status_json.py
 | 
| +index b656563..e48542d 100644
 | 
| +--- a/third_party/buildbot_8_4p1/buildbot/status/web/status_json.py
 | 
| ++++ b/third_party/buildbot_8_4p1/buildbot/status/web/status_json.py
 | 
| +@@ -16,6 +16,7 @@
 | 
| +
 | 
| + """Simple JSON exporter."""
 | 
| +
 | 
| ++import collections
 | 
| + import datetime
 | 
| + import os
 | 
| + import re
 | 
| +@@ -635,21 +636,38 @@ class SlaveJsonResource(JsonResource):
 | 
| +                     self.builders.append(builderName)
 | 
| +         return self.builders
 | 
| +
 | 
| ++    def getSlaveBuildMap(self, buildcache, buildercache):
 | 
| ++        for builderName in self.getBuilders():
 | 
| ++            if builderName not in buildercache:
 | 
| ++                buildercache.add(builderName)
 | 
| ++                builder_status = self.status.getBuilder(builderName)
 | 
| ++                for i in range(1, builder_status.buildCacheSize - 1):
 | 
| ++                    build_status = builder_status.getBuild(-i)
 | 
| ++                    if not build_status or not build_status.isFinished():
 | 
| ++                        # If not finished, it will appear in runningBuilds.
 | 
| ++                        break
 | 
| ++                    slave = buildcache[build_status.getSlavename()]
 | 
| ++                    slave.setdefault(builderName, []).append(
 | 
| ++                            build_status.getNumber())
 | 
| ++        return buildcache[self.name]
 | 
| ++
 | 
| +     def asDict(self, request):
 | 
| ++        if not hasattr(request, 'custom_data'):
 | 
| ++            request.custom_data = {}
 | 
| ++        if 'buildcache' not in request.custom_data:
 | 
| ++            # buildcache is used to cache build information across multiple
 | 
| ++            # invocations of SlaveJsonResource. It should be set to an empty
 | 
| ++            # collections.defaultdict(dict).
 | 
| ++            request.custom_data['buildcache'] = collections.defaultdict(dict)
 | 
| ++
 | 
| ++            # Tracks which builders have been stored in the buildcache.
 | 
| ++            request.custom_data['buildercache'] = set()
 | 
| ++
 | 
| +         results = self.slave_status.asDict()
 | 
| +-        # Enhance it by adding more informations.
 | 
| +-        results['builders'] = {}
 | 
| +-        for builderName in self.getBuilders():
 | 
| +-            builds = []
 | 
| +-            builder_status = self.status.getBuilder(builderName)
 | 
| +-            for i in range(1, builder_status.buildCacheSize - 1):
 | 
| +-                build_status = builder_status.getBuild(-i)
 | 
| +-                if not build_status or not build_status.isFinished():
 | 
| +-                    # If not finished, it will appear in runningBuilds.
 | 
| +-                    break
 | 
| +-                if build_status.getSlavename() == self.name:
 | 
| +-                    builds.append(build_status.getNumber())
 | 
| +-            results['builders'][builderName] = builds
 | 
| ++        # Enhance it by adding more information.
 | 
| ++        results['builders'] = self.getSlaveBuildMap(
 | 
| ++                request.custom_data['buildcache'],
 | 
| ++                request.custom_data['buildercache'])
 | 
| +         return results
 | 
| +
 | 
| +
 | 
| 
 |