~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/dirstate.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2007-10-09 02:46:19 UTC
  • mfrom: (2890.1.3 readv)
  • Revision ID: pqm@pqm.ubuntu.com-20071009024619-6l2c5sd2ghsyw2hx
(robertc) Bugfixes for the Transport.readv adjust_for_latency facility. (Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1846
1846
        try to keep everything in sorted blocks all the time, but sometimes
1847
1847
        it's easier to sort after the fact.
1848
1848
        """
 
1849
        # TODO: Might be faster to do a schwartzian transform?
1849
1850
        def _key(entry):
1850
1851
            # sort by: directory parts, file name, file id
1851
1852
            return entry[0][0].split('/'), entry[0][1], entry[0][2]
1859
1860
 
1860
1861
        :param new_inv: The inventory object to set current state from.
1861
1862
        """
1862
 
        if 'evil' in debug.debug_flags:
1863
 
            trace.mutter_callsite(1,
1864
 
                "set_state_from_inventory called; please mutate the tree instead")
1865
1863
        self._read_dirblocks_if_needed()
1866
1864
        # sketch:
1867
 
        # Two iterators: current data and new data, both in dirblock order. 
1868
 
        # We zip them together, which tells about entries that are new in the
1869
 
        # inventory, or removed in the inventory, or present in both and
1870
 
        # possibly changed.  
1871
 
        #
1872
 
        # You might think we could just synthesize a new dirstate directly
1873
 
        # since we're processing it in the right order.  However, we need to
1874
 
        # also consider there may be any number of parent trees and relocation
1875
 
        # pointers, and we don't want to duplicate that here.
 
1865
        # incremental algorithm:
 
1866
        # two iterators: current data and new data, both in dirblock order. 
1876
1867
        new_iterator = new_inv.iter_entries_by_dir()
1877
1868
        # we will be modifying the dirstate, so we need a stable iterator. In
1878
1869
        # future we might write one, for now we just clone the state into a
1903
1894
                if current_new_minikind == 't':
1904
1895
                    fingerprint = current_new[1].reference_revision or ''
1905
1896
                else:
1906
 
                    # We normally only insert or remove records, or update
1907
 
                    # them when it has significantly changed.  Then we want to
1908
 
                    # erase its fingerprint.  Unaffected records should
1909
 
                    # normally not be updated at all.
1910
1897
                    fingerprint = ''
1911
1898
            else:
1912
1899
                # for safety disable variables
1913
 
                new_path_utf8 = new_dirname = new_basename = new_id = \
1914
 
                    new_entry_key = None
 
1900
                new_path_utf8 = new_dirname = new_basename = new_id = new_entry_key = None
1915
1901
            # 5 cases, we dont have a value that is strictly greater than everything, so
1916
1902
            # we make both end conditions explicit
1917
1903
            if not current_old:
1926
1912
                current_old = advance(old_iterator)
1927
1913
            elif new_entry_key == current_old[0]:
1928
1914
                # same -  common case
1929
 
                # We're looking at the same path and id in both the dirstate
1930
 
                # and inventory, so just need to update the fields in the
1931
 
                # dirstate from the one in the inventory.
1932
1915
                # TODO: update the record if anything significant has changed.
1933
1916
                # the minimal required trigger is if the execute bit or cached
1934
1917
                # kind has changed.
1940
1923
                # both sides are dealt with, move on
1941
1924
                current_old = advance(old_iterator)
1942
1925
                current_new = advance(new_iterator)
1943
 
            elif (cmp_by_dirs(new_dirname, current_old[0][0]) < 0
1944
 
                  or (new_dirname == current_old[0][0]
1945
 
                      and new_entry_key[1:] < current_old[0][1:])):
 
1926
            elif (new_entry_key[0].split('/') < current_old[0][0].split('/')
 
1927
                  and new_entry_key[1:] < current_old[0][1:]):
1946
1928
                # new comes before:
1947
1929
                # add a entry for this and advance new
1948
1930
                self.update_minimal(new_entry_key, current_new_minikind,
1950
1932
                    path_utf8=new_path_utf8, fingerprint=fingerprint)
1951
1933
                current_new = advance(new_iterator)
1952
1934
            else:
1953
 
                # we've advanced past the place where the old key would be,
1954
 
                # without seeing it in the new list.  so it must be gone.
 
1935
                # old comes before:
1955
1936
                self._make_absent(current_old)
1956
1937
                current_old = advance(old_iterator)
1957
1938
        self._dirblock_state = DirState.IN_MEMORY_MODIFIED
1967
1948
        # build up paths that this id will be left at after the change is made,
1968
1949
        # so we can update their cross references in tree 0
1969
1950
        all_remaining_keys = set()
1970
 
        # If the working tree claims it is present, don't worry about it,
1971
 
        # because we are removing it. But if it is a rename, we need to remove
1972
 
        # the actual location.
1973
 
        details = current_old[1][0]
1974
 
        if details[0] == 'r':
1975
 
            all_remaining_keys.add(tuple(osutils.split(details[1])) + (current_old[0][2],))
 
1951
        # Dont check the working tree, because it's going.
1976
1952
        for details in current_old[1][1:]:
1977
1953
            if details[0] not in ('a', 'r'): # absent, relocated
1978
1954
                all_remaining_keys.add(current_old[0])
1993
1969
            if self._id_index is not None:
1994
1970
                self._id_index[current_old[0][2]].remove(current_old[0])
1995
1971
        # update all remaining keys for this id to record it as absent. The
1996
 
        # existing details may either be the record we are marking as deleted
 
1972
        # existing details may either be the record we are making as deleted
1997
1973
        # (if there were other trees with the id present at this path), or may
1998
1974
        # be relocations.
1999
1975
        for update_key in all_remaining_keys:
2005
1981
            assert present, 'could not find entry for %s' % (update_key,)
2006
1982
            update_tree_details = self._dirblocks[update_block_index][1][update_entry_index][1]
2007
1983
            # it must not be absent at the moment
2008
 
            # This doesn't seem to be strictly true, if you have a file renamed
2009
 
            # inside a directory, and you remove the directory
2010
 
            if update_tree_details[0][0] == 'a':
2011
 
                import pdb; pdb.set_trace()
2012
1984
            assert update_tree_details[0][0] != 'a' # absent
2013
1985
            update_tree_details[0] = DirState.NULL_PARENT_DETAILS
2014
1986
        self._dirblock_state = DirState.IN_MEMORY_MODIFIED
2026
1998
        :param minikind: The type for the entry ('f' == 'file', 'd' ==
2027
1999
                'directory'), etc.
2028
2000
        :param executable: Should the executable bit be set?
2029
 
        :param fingerprint: Simple fingerprint for new entry: sha1 for files, 
2030
 
            referenced revision id for subtrees, etc.
2031
 
        :param packed_stat: Packed stat value for new entry.
 
2001
        :param fingerprint: Simple fingerprint for new entry.
 
2002
        :param packed_stat: packed stat value for new entry.
2032
2003
        :param size: Size information for new entry
2033
2004
        :param path_utf8: key[0] + '/' + key[1], just passed in to avoid doing
2034
2005
                extra computation.
2035
 
 
2036
 
        If packed_stat and fingerprint are not given, they're invalidated in
2037
 
        the entry.
2038
2006
        """
2039
2007
        block = self._find_block(key)[1]
2040
2008
        if packed_stat is None:
2041
2009
            packed_stat = DirState.NULLSTAT
2042
 
        # XXX: Some callers pass '' as the packed_stat, and it seems to be
2043
 
        # sometimes present in the dirstate - this seems oddly inconsistent.
2044
 
        # mbp 20071008
2045
2010
        entry_index, present = self._find_entry_index(key, block)
2046
2011
        new_details = (minikind, fingerprint, size, executable, packed_stat)
2047
2012
        id_index = self._get_id_index()