605
624
"""Create a line for the state file for parents information."""
606
625
return '\0'.join([str(len(parent_ids))] + parent_ids)
627
def _get_fields_to_entry(self):
628
"""Get a function which converts entry fields into a entry record.
630
This handles kind, size, and executable, as well as parent records.
632
:return: A function which takes a list of fields, and returns an
633
appropriate record for storing in memory.
635
# This is intentionally unrolled for performance
636
num_present_parents = self._num_present_parents()
637
if num_present_parents == 0:
638
def fields_to_entry_0_parents(fields, _int=int, _tuple=tuple,
639
_mini_to_kind=self._minikind_to_kind):
640
path_name_file_id_key = _tuple(fields[:3])
641
return (path_name_file_id_key, [
643
_mini_to_kind[fields[3]], # kind
644
fields[4], # fingerprint
645
_int(fields[5]), # size
646
fields[6] == 'y', # executable
647
fields[7], # packed_stat or revision_id
649
return fields_to_entry_0_parents
650
elif num_present_parents == 1:
651
def fields_to_entry_1_parent(fields, _int=int, _tuple=tuple,
652
_mini_to_kind=self._minikind_to_kind):
653
path_name_file_id_key = _tuple(fields[:3])
654
return (path_name_file_id_key, [
656
_mini_to_kind[fields[3]], # kind
657
fields[4], # fingerprint
658
_int(fields[5]), # size
659
fields[6] == 'y', # executable
660
fields[7], # packed_stat or revision_id
663
_mini_to_kind[fields[8]], # kind
664
fields[9], # fingerprint
665
_int(fields[10]), # size
666
fields[11] == 'y', # executable
667
fields[12], # packed_stat or revision_id
670
return fields_to_entry_1_parent
671
elif num_present_parents == 2:
672
def fields_to_entry_2_parents(fields, _int=int, _tuple=tuple,
673
_mini_to_kind=self._minikind_to_kind):
674
path_name_file_id_key = _tuple(fields[:3])
675
return (path_name_file_id_key, [
677
_mini_to_kind[fields[3]], # kind
678
fields[4], # fingerprint
679
_int(fields[5]), # size
680
fields[6] == 'y', # executable
681
fields[7], # packed_stat or revision_id
684
_mini_to_kind[fields[8]], # kind
685
fields[9], # fingerprint
686
_int(fields[10]), # size
687
fields[11] == 'y', # executable
688
fields[12], # packed_stat or revision_id
691
_mini_to_kind[fields[13]],# kind
692
fields[14], # fingerprint
693
_int(fields[15]), # size
694
fields[16] == 'y', # executable
695
fields[17], # packed_stat or revision_id
698
return fields_to_entry_2_parents
700
def fields_to_entry_n_parents(fields, _int=int, _tuple=tuple,
701
_mini_to_kind=self._minikind_to_kind):
702
path_name_file_id_key = _tuple(fields[:3])
703
trees = [(_mini_to_kind[fields[cur]], # kind
704
fields[cur+1], # fingerprint
705
_int(fields[cur+2]), # size
706
fields[cur+3] == 'y', # executable
707
fields[cur+4], # stat or revision_id
708
) for cur in xrange(3, len(fields)-1, 5)]
709
return path_name_file_id_key, trees
710
return fields_to_entry_n_parents
608
712
def get_parent_ids(self):
609
713
"""Return a list of the parent tree ids for the directory state."""
610
714
self._read_header_if_needed()
850
958
field_count - cur, expected_field_count, entry_size,
851
959
self._num_entries, fields)
853
# Fast path the case where there are 1 or 2 parents
854
if num_present_parents == 0:
855
# key, [current tree]
856
entries = [(tuple(fields[pos:pos + 3]), [fields[pos + 3:pos + 8]])
857
for pos in xrange(cur, field_count, entry_size)]
858
elif num_present_parents == 1:
860
entries = [(tuple(fields[pos:pos + 3]),
861
# [current tree, parent 1]
862
[fields[pos + 3:pos + 8], fields[pos + 8:pos + 13], ])
863
for pos in xrange(cur, field_count, entry_size)]
864
elif num_present_parents == 2:
866
entries = [(tuple(fields[pos:pos + 3]),
867
# [current tree, parent 1,
868
[fields[pos + 3:pos + 8], fields[pos + 8:pos + 13],
870
fields[pos + 13:pos + 18], ])
871
for pos in xrange(cur, field_count, entry_size)]
874
tuple(fields[pos:pos+3]), #key
875
tuple([fields[chunk:chunk+5] for
876
chunk in xrange(pos + 3, pos+entry_size-1, 5)]))
877
for pos in xrange(cur, field_count, entry_size)
880
assert len(entries) == self._num_entries, '%s != %s entries' % (len(entries),
883
def _line_to_entry(line):
884
"""Convert freshly read tree details to the final form.
886
This converts size and minikind for use and makes it into a
890
# convert the minikind to kind
891
tree[0] = self._minikind_to_kind[tree[0]]
892
# convert the size to an int
893
tree[2] = int(tree[2])
894
tree[3] = tree[3] == 'y'
895
return line[0], map(tuple, line[1])
896
new_entries = map(_line_to_entry, entries)
897
self._entries_to_current_state(new_entries)
961
fields_to_entry = self._get_fields_to_entry()
962
entries = [fields_to_entry(fields[pos:pos+entry_size])
963
for pos in xrange(cur, field_count, entry_size)]
964
self._entries_to_current_state(entries)
898
965
self._dirblock_state = DirState.IN_MEMORY_UNMODIFIED
900
967
def _read_header(self):