905
905
# the parent's path is necessarily known at this point.
906
906
yield(file_id, (path, to_path), changed_content, versioned, parent,
907
907
name, kind, executable)
910
class MultiWalker(object):
911
"""Walk multiple trees simultaneously, getting combined results."""
913
def __init__(self, master_tree, other_trees):
914
"""Create a new MultiWalker.
916
All trees being walked must implement "iter_entries_by_dir()", such
917
that they yield (path, object) tuples, where that object will have a
918
'.file_id' member, that can be used to check equality.
920
:param master_tree: All trees will be 'slaved' to the master_tree. Such
921
that nodes in master_tree will be used as 'first-pass' sync points.
922
Any nodes that aren't in master_tree will be merged in a second
924
:param other_trees: A list of other trees to walk simultaneously.
926
self._master_tree = master_tree
927
self._other_trees = other_trees
930
def _step_one(iterator):
931
"""Step an iter_entries_by_dir iterator.
933
:return: (has_more, path, ie)
934
If has_more is False, path and ie will be None.
937
path, ie = iterator.next()
938
except StopIteration:
939
return False, None, None
941
return True, path, ie
944
"""Match up the values in the different trees."""
945
import pdb; pdb.set_trace()
946
master_iterator = self._master_tree.iter_entries_by_dir()
948
other_walkers = [other.iter_entries_by_dir()
949
for other in self._other_trees]
950
other_entries = [self._step_one(walker) for walker in other_walkers]
952
master_has_more = True
953
while master_has_more:
954
(master_has_more, master_path,
955
master_ie) = self._step_one(master_iterator)
956
if not master_has_more:
959
master_file_id = master_ie.file_id
961
next_other_entries = []
962
for other_walker, (other_has_more, other_path, other_ie) in \
963
zip(other_walkers, other_entries):
964
if not other_has_more:
965
other_values.append((None, None))
966
next_other_entries.append(False, None, None)
967
elif master_file_id == other_ie.file_id:
968
# This walker matched, so consume this path, and go on to
970
other_values.append((other_path, other_ie))
971
next_other_entries.append(self._step_one(other_walker))
973
# This walker did not match, step it until it either
974
# matches, or we know we are past the current walker.
975
raise NotImplementedError
976
other_entries = next_other_entries
978
# We've matched all the walkers, yield this datapoint
979
yield master_path, master_file_id, master_ie, other_values