363 data.insert(low, (range(rev, rev + 1), t)) |
363 data.insert(low, (range(rev, rev + 1), t)) |
364 else: |
364 else: |
365 data.insert(low + 1, (range(rev, rev + 1), t)) |
365 data.insert(low + 1, (range(rev, rev + 1), t)) |
366 |
366 |
367 |
367 |
|
368 # consider incrementaly updating the phase set the update set is not bigger |
|
369 # than this size |
|
370 # |
|
371 # Be warned, this number is picked arbitrarily, without any benchmark. It |
|
372 # should blindly pickup "small update" |
|
373 INCREMENTAL_PHASE_SETS_UPDATE_MAX_UPDATE = 100 |
|
374 |
|
375 |
368 class phasecache: |
376 class phasecache: |
369 def __init__( |
377 def __init__( |
370 self, |
378 self, |
371 repo: "localrepo.localrepository", |
379 repo: "localrepo.localrepository", |
372 phasedefaults: Optional["Phasedefaults"], |
380 phasedefaults: Optional["Phasedefaults"], |
506 lowerroots.update(ps) |
514 lowerroots.update(ps) |
507 self._phasesets[phase] = ps |
515 self._phasesets[phase] = ps |
508 self._loadedrevslen = len(cl) |
516 self._loadedrevslen = len(cl) |
509 |
517 |
510 def _ensure_phase_sets(self, repo: "localrepo.localrepository") -> None: |
518 def _ensure_phase_sets(self, repo: "localrepo.localrepository") -> None: |
511 """ensure phase information is loaded in the object and up to date""" |
519 """ensure phase information is loaded in the object""" |
512 update = False |
520 assert repo.filtername is None |
|
521 update = -1 |
|
522 cl = repo.changelog |
|
523 cl_size = len(cl) |
513 if self._phasesets is None: |
524 if self._phasesets is None: |
514 update = True |
525 update = 0 |
515 elif len(repo.changelog) > self._loadedrevslen: |
526 else: |
516 update = True |
527 if cl_size > self._loadedrevslen: |
517 if update: |
528 # check if an incremental update is worth it. |
|
529 # note we need a tradeoff here because the whole logic is not |
|
530 # stored and implemented in native code nd datastructure. |
|
531 # Otherwise the incremental update woul always be a win. |
|
532 missing = cl_size - self._loadedrevslen |
|
533 if missing <= INCREMENTAL_PHASE_SETS_UPDATE_MAX_UPDATE: |
|
534 update = self._loadedrevslen |
|
535 else: |
|
536 update = 0 |
|
537 |
|
538 if update == 0: |
518 try: |
539 try: |
519 res = self._getphaserevsnative(repo) |
540 res = self._getphaserevsnative(repo) |
520 self._loadedrevslen, self._phasesets = res |
541 self._loadedrevslen, self._phasesets = res |
521 except AttributeError: |
542 except AttributeError: |
522 self._computephaserevspure(repo) |
543 self._computephaserevspure(repo) |
523 assert self._loadedrevslen == len(repo.changelog) |
544 assert self._loadedrevslen == len(repo.changelog) |
|
545 elif update > 0: |
|
546 # good candidate for native code |
|
547 assert update == self._loadedrevslen |
|
548 if self.hasnonpublicphases(repo): |
|
549 start = self._loadedrevslen |
|
550 get_phase = self.phase |
|
551 rev_phases = [0] * missing |
|
552 parents = cl.parentrevs |
|
553 sets = {phase: set() for phase in self._phasesets} |
|
554 for phase, roots in self._phaseroots.items(): |
|
555 # XXX should really store the max somewhere |
|
556 for r in roots: |
|
557 if r >= start: |
|
558 rev_phases[r - start] = phase |
|
559 for rev in range(start, cl_size): |
|
560 phase = rev_phases[rev - start] |
|
561 p1, p2 = parents(rev) |
|
562 if p1 == nullrev: |
|
563 p1_phase = public |
|
564 elif p1 >= start: |
|
565 p1_phase = rev_phases[p1 - start] |
|
566 else: |
|
567 p1_phase = max(phase, get_phase(repo, p1)) |
|
568 if p2 == nullrev: |
|
569 p2_phase = public |
|
570 elif p2 >= start: |
|
571 p2_phase = rev_phases[p2 - start] |
|
572 else: |
|
573 p2_phase = max(phase, get_phase(repo, p2)) |
|
574 phase = max(phase, p1_phase, p2_phase) |
|
575 if phase > public: |
|
576 rev_phases[rev - start] = phase |
|
577 sets[phase].add(rev) |
|
578 |
|
579 # Be careful to preserve shallow-copied values: do not update |
|
580 # phaseroots values, replace them. |
|
581 for phase, extra in sets.items(): |
|
582 if extra: |
|
583 self._phasesets[phase] = self._phasesets[phase] | extra |
|
584 self._loadedrevslen = cl_size |
524 |
585 |
525 def invalidate(self): |
586 def invalidate(self): |
526 self._loadedrevslen = 0 |
587 self._loadedrevslen = 0 |
527 self._phasesets = None |
588 self._phasesets = None |
528 |
589 |