96 if revs: |
96 if revs: |
97 partial.update(repo, revs) |
97 partial.update(repo, revs) |
98 partial.write(repo) |
98 partial.write(repo) |
99 |
99 |
100 if repo._revbranchcache is not None: |
100 if repo._revbranchcache is not None: |
101 repo._revbranchcache.write(repo) |
101 repo._revbranchcache.write() |
102 |
102 |
103 assert partial.validfor(repo), filtername |
103 assert partial.validfor(repo), filtername |
104 repo._branchcaches[repo.filtername] = partial |
104 repo._branchcaches[repo.filtername] = partial |
105 |
105 |
106 class branchcache(dict): |
106 class branchcache(dict): |
237 """ |
237 """ |
238 starttime = time.time() |
238 starttime = time.time() |
239 cl = repo.changelog |
239 cl = repo.changelog |
240 # collect new branch entries |
240 # collect new branch entries |
241 newbranches = {} |
241 newbranches = {} |
242 urepo = repo.unfiltered() |
|
243 ucl = urepo.changelog |
|
244 getbranchinfo = repo.revbranchcache().branchinfo |
242 getbranchinfo = repo.revbranchcache().branchinfo |
245 for r in revgen: |
243 for r in revgen: |
246 branch, closesbranch = getbranchinfo(ucl, r) |
244 branch, closesbranch = getbranchinfo(r) |
247 newbranches.setdefault(branch, []).append(r) |
245 newbranches.setdefault(branch, []).append(r) |
248 if closesbranch: |
246 if closesbranch: |
249 self._closednodes.add(cl.node(r)) |
247 self._closednodes.add(cl.node(r)) |
250 |
248 |
251 # fetch current topological heads to speed up filtering |
249 # fetch current topological heads to speed up filtering |
329 and will grow with it but be 1/8th of its size. |
327 and will grow with it but be 1/8th of its size. |
330 """ |
328 """ |
331 |
329 |
332 def __init__(self, repo, readonly=True): |
330 def __init__(self, repo, readonly=True): |
333 assert repo.filtername is None |
331 assert repo.filtername is None |
|
332 self._repo = repo |
334 self._names = [] # branch names in local encoding with static index |
333 self._names = [] # branch names in local encoding with static index |
335 self._rbcrevs = array('c') # structs of type _rbcrecfmt |
334 self._rbcrevs = array('c') # structs of type _rbcrecfmt |
336 self._rbcsnameslen = 0 |
335 self._rbcsnameslen = 0 |
337 try: |
336 try: |
338 bndata = repo.vfs.read(_rbcnames) |
337 bndata = repo.vfs.read(_rbcnames) |
358 if self._rbcrevslen == 0: |
357 if self._rbcrevslen == 0: |
359 self._names = [] |
358 self._names = [] |
360 self._rbcnamescount = len(self._names) # number of good names on disk |
359 self._rbcnamescount = len(self._names) # number of good names on disk |
361 self._namesreverse = dict((b, r) for r, b in enumerate(self._names)) |
360 self._namesreverse = dict((b, r) for r, b in enumerate(self._names)) |
362 |
361 |
363 def branchinfo(self, changelog, rev): |
362 def branchinfo(self, rev): |
364 """Return branch name and close flag for rev, using and updating |
363 """Return branch name and close flag for rev, using and updating |
365 persistent cache.""" |
364 persistent cache.""" |
|
365 changelog = self._repo.changelog |
366 rbcrevidx = rev * _rbcrecsize |
366 rbcrevidx = rev * _rbcrecsize |
367 |
367 |
368 # if requested rev is missing, add and populate all missing revs |
368 # if requested rev is missing, add and populate all missing revs |
369 if len(self._rbcrevs) < rbcrevidx + _rbcrecsize: |
369 if len(self._rbcrevs) < rbcrevidx + _rbcrecsize: |
370 first = len(self._rbcrevs) // _rbcrecsize |
370 first = len(self._rbcrevs) // _rbcrecsize |
371 self._rbcrevs.extend('\0' * (len(changelog) * _rbcrecsize - |
371 self._rbcrevs.extend('\0' * (len(changelog) * _rbcrecsize - |
372 len(self._rbcrevs))) |
372 len(self._rbcrevs))) |
373 for r in xrange(first, len(changelog)): |
373 for r in xrange(first, len(changelog)): |
374 self._branchinfo(changelog, r) |
374 self._branchinfo(r) |
375 |
375 |
376 # fast path: extract data from cache, use it if node is matching |
376 # fast path: extract data from cache, use it if node is matching |
377 reponode = changelog.node(rev)[:_rbcnodelen] |
377 reponode = changelog.node(rev)[:_rbcnodelen] |
378 cachenode, branchidx = unpack( |
378 cachenode, branchidx = unpack( |
379 _rbcrecfmt, buffer(self._rbcrevs, rbcrevidx, _rbcrecsize)) |
379 _rbcrecfmt, buffer(self._rbcrevs, rbcrevidx, _rbcrecsize)) |
382 branchidx &= _rbcbranchidxmask |
382 branchidx &= _rbcbranchidxmask |
383 if cachenode == reponode: |
383 if cachenode == reponode: |
384 return self._names[branchidx], close |
384 return self._names[branchidx], close |
385 # fall back to slow path and make sure it will be written to disk |
385 # fall back to slow path and make sure it will be written to disk |
386 self._rbcrevslen = min(self._rbcrevslen, rev) |
386 self._rbcrevslen = min(self._rbcrevslen, rev) |
387 return self._branchinfo(changelog, rev) |
387 return self._branchinfo(rev) |
388 |
388 |
389 def _branchinfo(self, changelog, rev): |
389 def _branchinfo(self, rev): |
390 """Retrieve branch info from changelog and update _rbcrevs""" |
390 """Retrieve branch info from changelog and update _rbcrevs""" |
|
391 changelog = self._repo.changelog |
391 b, close = changelog.branchinfo(rev) |
392 b, close = changelog.branchinfo(rev) |
392 if b in self._namesreverse: |
393 if b in self._namesreverse: |
393 branchidx = self._namesreverse[b] |
394 branchidx = self._namesreverse[b] |
394 else: |
395 else: |
395 branchidx = len(self._names) |
396 branchidx = len(self._names) |
402 rec = array('c') |
403 rec = array('c') |
403 rec.fromstring(pack(_rbcrecfmt, reponode, branchidx)) |
404 rec.fromstring(pack(_rbcrecfmt, reponode, branchidx)) |
404 self._rbcrevs[rbcrevidx:rbcrevidx + _rbcrecsize] = rec |
405 self._rbcrevs[rbcrevidx:rbcrevidx + _rbcrecsize] = rec |
405 return b, close |
406 return b, close |
406 |
407 |
407 def write(self, repo): |
408 def write(self): |
408 """Save branch cache if it is dirty.""" |
409 """Save branch cache if it is dirty.""" |
|
410 repo = self._repo |
409 if self._rbcnamescount < len(self._names): |
411 if self._rbcnamescount < len(self._names): |
410 try: |
412 try: |
411 if self._rbcnamescount != 0: |
413 if self._rbcnamescount != 0: |
412 f = repo.vfs.open(_rbcnames, 'ab') |
414 f = repo.vfs.open(_rbcnames, 'ab') |
413 if f.tell() == self._rbcsnameslen: |
415 if f.tell() == self._rbcsnameslen: |