~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/inventory.py

merge trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2010 Canonical Ltd
 
1
# Copyright (C) 2005-2011 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
718
718
                # if we finished all children, pop it off the stack
719
719
                stack.pop()
720
720
 
 
721
    def _preload_cache(self):
 
722
        """Populate any caches, we are about to access all items.
 
723
        
 
724
        The default implementation does nothing, because CommonInventory doesn't
 
725
        have a cache.
 
726
        """
 
727
        pass
 
728
    
721
729
    def iter_entries_by_dir(self, from_dir=None, specific_file_ids=None,
722
730
        yield_parents=False):
723
731
        """Iterate over the entries in a directory first order.
736
744
            specific_file_ids = set(specific_file_ids)
737
745
        # TODO? Perhaps this should return the from_dir so that the root is
738
746
        # yielded? or maybe an option?
 
747
        if from_dir is None and specific_file_ids is None:
 
748
            # They are iterating from the root, and have not specified any
 
749
            # specific entries to look at. All current callers fully consume the
 
750
            # iterator, so we can safely assume we are accessing all entries
 
751
            self._preload_cache()
739
752
        if from_dir is None:
740
753
            if self.root is None:
741
754
                return
836
849
                if ie.kind == 'directory':
837
850
                    descend(ie, child_path)
838
851
 
839
 
        descend(self.root, u'')
 
852
        if self.root is not None:
 
853
            descend(self.root, u'')
840
854
        return accum
841
855
 
842
856
    def directories(self):
1389
1403
    def __init__(self, search_key_name):
1390
1404
        CommonInventory.__init__(self)
1391
1405
        self._fileid_to_entry_cache = {}
 
1406
        self._fully_cached = False
1392
1407
        self._path_to_fileid_cache = {}
1393
1408
        self._search_key_name = search_key_name
1394
1409
        self.root_id = None
1955
1970
 
1956
1971
    def iter_just_entries(self):
1957
1972
        """Iterate over all entries.
1958
 
        
 
1973
 
1959
1974
        Unlike iter_entries(), just the entries are returned (not (path, ie))
1960
1975
        and the order of entries is undefined.
1961
1976
 
1969
1984
                self._fileid_to_entry_cache[file_id] = ie
1970
1985
            yield ie
1971
1986
 
 
1987
    def _preload_cache(self):
 
1988
        """Make sure all file-ids are in _fileid_to_entry_cache"""
 
1989
        if self._fully_cached:
 
1990
            return # No need to do it again
 
1991
        # The optimal sort order is to use iteritems() directly
 
1992
        cache = self._fileid_to_entry_cache
 
1993
        for key, entry in self.id_to_entry.iteritems():
 
1994
            file_id = key[0]
 
1995
            if file_id not in cache:
 
1996
                ie = self._bytes_to_entry(entry)
 
1997
                cache[file_id] = ie
 
1998
            else:
 
1999
                ie = cache[file_id]
 
2000
        last_parent_id = last_parent_ie = None
 
2001
        pid_items = self.parent_id_basename_to_file_id.iteritems()
 
2002
        for key, child_file_id in pid_items:
 
2003
            if key == ('', ''): # This is the root
 
2004
                if child_file_id != self.root_id:
 
2005
                    raise ValueError('Data inconsistency detected.'
 
2006
                        ' We expected data with key ("","") to match'
 
2007
                        ' the root id, but %s != %s'
 
2008
                        % (child_file_id, self.root_id))
 
2009
                continue
 
2010
            parent_id, basename = key
 
2011
            ie = cache[child_file_id]
 
2012
            if parent_id == last_parent_id:
 
2013
                parent_ie = last_parent_ie
 
2014
            else:
 
2015
                parent_ie = cache[parent_id]
 
2016
            if parent_ie.kind != 'directory':
 
2017
                raise ValueError('Data inconsistency detected.'
 
2018
                    ' An entry in the parent_id_basename_to_file_id map'
 
2019
                    ' has parent_id {%s} but the kind of that object'
 
2020
                    ' is %r not "directory"' % (parent_id, parent_ie.kind))
 
2021
            if parent_ie._children is None:
 
2022
                parent_ie._children = {}
 
2023
            basename = basename.decode('utf-8')
 
2024
            if basename in parent_ie._children:
 
2025
                existing_ie = parent_ie._children[basename]
 
2026
                if existing_ie != ie:
 
2027
                    raise ValueError('Data inconsistency detected.'
 
2028
                        ' Two entries with basename %r were found'
 
2029
                        ' in the parent entry {%s}'
 
2030
                        % (basename, parent_id))
 
2031
            if basename != ie.name:
 
2032
                raise ValueError('Data inconsistency detected.'
 
2033
                    ' In the parent_id_basename_to_file_id map, file_id'
 
2034
                    ' {%s} is listed as having basename %r, but in the'
 
2035
                    ' id_to_entry map it is %r'
 
2036
                    % (child_file_id, basename, ie.name))
 
2037
            parent_ie._children[basename] = ie
 
2038
        self._fully_cached = True
 
2039
 
1972
2040
    def iter_changes(self, basis):
1973
2041
        """Generate a Tree.iter_changes change list between this and basis.
1974
2042