718
718
# if we finished all children, pop it off the stack
721
def _preload_cache(self):
722
"""Populate any caches, we are about to access all items.
724
The default implementation does nothing, because CommonInventory doesn't
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:
1969
1984
self._fileid_to_entry_cache[file_id] = ie
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():
1995
if file_id not in cache:
1996
ie = self._bytes_to_entry(entry)
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))
2010
parent_id, basename = key
2011
ie = cache[child_file_id]
2012
if parent_id == last_parent_id:
2013
parent_ie = last_parent_ie
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
1972
2040
def iter_changes(self, basis):
1973
2041
"""Generate a Tree.iter_changes change list between this and basis.