コード例 #1
0
ファイル: api.py プロジェクト: pombredanne/trachacks
    def previous_rev(self, rev):

        self._log.debug('previous_rev(%r)' % rev)

        if not isinstance(rev, int):
            rev = self.short_rev(rev)
            if not isinstance(rev, int):
                raise NoSuchChangeset(rev)

        from p4trac.repos import _P4ChangesOutputConsumer
        output = _P4ChangesOutputConsumer(self._repos)
        self._connection.run('changes',
                             '-l',
                             '-s',
                             'submitted',
                             '-m',
                             '1',
                             '@<%i' % rev,
                             output=output)

        if output.errors:
            from p4trac.repos import PerforcError
            raise PerforcError(output.errors)

        if output.changes:
            return max(output.changes)
        else:
            return None
コード例 #2
0
ファイル: api.py プロジェクト: pombredanne/trachacks
    def next_rev(self, rev, path=''):

        # Finding the next revision is a little more difficult in Perforce
        # as we can only ask for the n most recent changes according to a
        # given criteria. We query batches of changes using a binary search
        # technique so that the number of changes queried is of the order of
        # log N where N is the number of changes greater than rev. This way
        # it is still fairly efficient if the next change is 1 or 1000 changes
        # later.

        self._log.debug('next_rev(%r,%r)' % (rev, path))

        from p4trac.repos import NodePath
        if not path:
            path = u'//'
        else:
            path = NodePath.normalisePath(path)
        node = self._repos.getNode(NodePath(path, rev))

        if node.isDirectory:
            if node.nodePath.isRoot:
                # Handle the root path specially since it encompasses all
                # changes and so can use the repository's internal cache.
                return self._repos.getNextChange(int(rev))
            else:
                queryPath = u'%s/...' % node.nodePath.path
        else:
            queryPath = node.nodePath.path

        queryPath = self._repos.fromUnicode(queryPath)

        self._log.debug(
            u'Looing for next_rev after change %i for %s' % (rev, path))

        # Perform a binary-search of sorts for the next revision
        batchSize = 50
        lowerBound = rev + 1
        upperBound = self.youngest_rev

        while lowerBound <= upperBound:

            if lowerBound + batchSize > upperBound:
                batchUpperBound = upperBound
            else:
                middle = (upperBound + lowerBound) / 2
                if middle - lowerBound < batchSize:
                    batchUpperBound = lowerBound + batchSize
                else:
                    batchUpperBound = middle

            self._log.debug(
                'Looking for changes in range [%i, %i]' % (lowerBound,
                                                           batchUpperBound))
                    
            from p4trac.repos import _P4ChangesOutputConsumer
            output = _P4ChangesOutputConsumer(self._repos)
            self._connection.run('changes', '-l', '-s', 'submitted',
                                 '-m', str(batchSize),
                                 '%s@>=%i,@<=%i' % (queryPath,
                                                    lowerBound,
                                                    batchUpperBound),
                                 output=output)

            if output.errors:
                from p4trac.repos import PerforcError
                raise PerforcError(output.errors)
                
            if output.changes:
                lowest = min(output.changes)
                assert lowest >= lowerBound
                assert lowest <= batchUpperBound

                if lowerBound + batchSize >= batchUpperBound:
                    # There are no earlier changes
                    self._log.debug('next_rev is %i' % lowest)
                    return lowest
                else:
                    # There may be another earlier changes but we know it
                    # can't be any later than lowest.
                    upperBound = lowest
            else:
                # Didn't find any changes in (lowerBound, batchUpperBound)
                # Try searching from batchUpperBound + 1 onwards
                lowerBound = batchUpperBound + 1

        return None