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