mercurial/setdiscovery.py
changeset 42741 4e7bd6180b53
parent 42425 b9ff059fd194
child 42742 334c1ea57136
equal deleted inserted replaced
42740:1c4b5689bef5 42741:4e7bd6180b53
    90         for p in parentfn(curr):
    90         for p in parentfn(curr):
    91             if p != nullrev and (not revs or p in revs):
    91             if p != nullrev and (not revs or p in revs):
    92                 dist.setdefault(p, d + 1)
    92                 dist.setdefault(p, d + 1)
    93                 visit.append(p)
    93                 visit.append(p)
    94 
    94 
    95 def _limitsample(sample, desiredlen):
    95 def _limitsample(sample, desiredlen, randomize=True):
    96     """return a random subset of sample of at most desiredlen item"""
    96     """return a random subset of sample of at most desiredlen item.
    97     if len(sample) > desiredlen:
    97 
    98         sample = set(random.sample(sample, desiredlen))
    98     If randomize is False, though, a deterministic subset is returned.
    99     return sample
    99     This is meant for integration tests.
       
   100     """
       
   101     if len(sample) <= desiredlen:
       
   102         return sample
       
   103     if randomize:
       
   104         return set(random.sample(sample, desiredlen))
       
   105     sample = list(sample)
       
   106     sample.sort()
       
   107     return set(sample[:desiredlen])
   100 
   108 
   101 class partialdiscovery(object):
   109 class partialdiscovery(object):
   102     """an object representing ongoing discovery
   110     """an object representing ongoing discovery
   103 
   111 
   104     Feed with data from the remote repository, this object keep track of the
   112     Feed with data from the remote repository, this object keep track of the
   108     - undecided: revs we don't have information on yet
   116     - undecided: revs we don't have information on yet
   109     - missing:   revs missing remotely
   117     - missing:   revs missing remotely
   110     (all tracked revisions are known locally)
   118     (all tracked revisions are known locally)
   111     """
   119     """
   112 
   120 
   113     def __init__(self, repo, targetheads, respectsize):
   121     def __init__(self, repo, targetheads, respectsize, randomize=True):
   114         self._repo = repo
   122         self._repo = repo
   115         self._targetheads = targetheads
   123         self._targetheads = targetheads
   116         self._common = repo.changelog.incrementalmissingrevs()
   124         self._common = repo.changelog.incrementalmissingrevs()
   117         self._undecided = None
   125         self._undecided = None
   118         self.missing = set()
   126         self.missing = set()
   119         self._childrenmap = None
   127         self._childrenmap = None
   120         self._respectsize = respectsize
   128         self._respectsize = respectsize
       
   129         self.randomize = randomize
   121 
   130 
   122     def addcommons(self, commons):
   131     def addcommons(self, commons):
   123         """register nodes known as common"""
   132         """register nodes known as common"""
   124         self._common.addbases(commons)
   133         self._common.addbases(commons)
   125         if self._undecided is not None:
   134         if self._undecided is not None:
   220         if len(revs) <= size:
   229         if len(revs) <= size:
   221             return list(revs)
   230             return list(revs)
   222         sample = set(self._repo.revs('heads(%ld)', revs))
   231         sample = set(self._repo.revs('heads(%ld)', revs))
   223 
   232 
   224         if len(sample) >= size:
   233         if len(sample) >= size:
   225             return _limitsample(sample, size)
   234             return _limitsample(sample, size, randomize=self.randomize)
   226 
   235 
   227         _updatesample(None, headrevs, sample, self._parentsgetter(),
   236         _updatesample(None, headrevs, sample, self._parentsgetter(),
   228                       quicksamplesize=size)
   237                       quicksamplesize=size)
   229         return sample
   238         return sample
   230 
   239 
   247         assert sample
   256         assert sample
   248 
   257 
   249         if not self._respectsize:
   258         if not self._respectsize:
   250             size = max(size, min(len(revsroots), len(revsheads)))
   259             size = max(size, min(len(revsroots), len(revsheads)))
   251 
   260 
   252         sample = _limitsample(sample, size)
   261         sample = _limitsample(sample, size, randomize=self.randomize)
   253         if len(sample) < size:
   262         if len(sample) < size:
   254             more = size - len(sample)
   263             more = size - len(sample)
   255             sample.update(random.sample(list(revs - sample), more))
   264             takefrom = list(revs - sample)
       
   265             if self.randomize:
       
   266                 sample.update(random.sample(takefrom, more))
       
   267             else:
       
   268                 takefrom.sort()
       
   269                 sample.update(takefrom[:more])
   256         return sample
   270         return sample
   257 
   271 
   258 def findcommonheads(ui, local, remote,
   272 def findcommonheads(ui, local, remote,
   259                     initialsamplesize=100,
   273                     initialsamplesize=100,
   260                     fullsamplesize=200,
   274                     fullsamplesize=200,