##// END OF EJS Templates
setdiscovery: precompute children revisions to avoid quadratic lookup...
Gregory Szorc -
r39214:274acf37 default
parent child Browse files
Show More
@@ -117,13 +117,33 b' def _takefullsample(repo, headrevs, revs'
117 117 # update from heads
118 118 revsheads = set(repo.revs('heads(%ld)', revs))
119 119 _updatesample(revs, revsheads, sample, repo.changelog.parentrevs)
120
120 121 # update from roots
121 122 revsroots = set(repo.revs('roots(%ld)', revs))
122 123
123 # TODO this is quadratic
124 parentfn = lambda rev: repo.changelog.children(repo.changelog.node(rev))
124 # _updatesample() essentially does interaction over revisions to look up
125 # their children. This lookup is expensive and doing it in a loop is
126 # quadratic. We precompute the children for all relevant revisions and
127 # make the lookup in _updatesample() a simple dict lookup.
128 #
129 # Because this function can be called multiple times during discovery, we
130 # may still perform redundant work and there is room to optimize this by
131 # keeping a persistent cache of children across invocations.
132 children = {}
125 133
126 _updatesample(revs, revsroots, sample, parentfn)
134 parentrevs = repo.changelog.parentrevs
135 for rev in repo.changelog.revs(start=min(revsroots)):
136 # Always ensure revision has an entry so we don't need to worry about
137 # missing keys.
138 children.setdefault(rev, [])
139
140 for prev in parentrevs(rev):
141 if prev == nullrev:
142 continue
143
144 children.setdefault(prev, []).append(rev)
145
146 _updatesample(revs, revsroots, sample, children.__getitem__)
127 147 assert sample
128 148 sample = _limitsample(sample, size)
129 149 if len(sample) < size:
General Comments 0
You need to be logged in to leave comments. Login now