192
192
__slots__ = ['_node_name_stack',
193
193
'_node_merge_depth_stack',
194
194
'_pending_parents_stack',
195
'_assigned_sequence_stack',
195
'_first_child_stack',
196
196
'_left_subtree_pushed_stack',
197
197
'_generate_revno',
362
362
self._original_graph = dict(self._graph.items())
363
363
# we need to know the revision numbers of revisions to determine
364
364
# the revision numbers of their descendants
365
# this is a graph from node to [revno_tuple, sequence_number]
366
# where sequence is the number of branches made from the node,
365
# this is a graph from node to [revno_tuple, first_child]
366
# where first_child is True if no other children have seen this node
367
367
# and revno_tuple is the tuple that was assigned to the node.
368
368
# we dont know revnos to start with, so we start it seeded with
370
self._revnos = dict((revision, [None, 0]) for revision in self._graph)
371
# the global implicit root node has revno 0, but we need to know
372
# the sequence number for it too:
373
self._root_sequence = 0
370
self._revnos = dict((revision, [None, True])
371
for revision in self._graph)
372
# Each mainline revision counts how many child branches have spawned from it.
373
self._revno_to_branch_count = {}
375
375
# this is a stack storing the depth first search into the graph.
376
376
self._node_name_stack = []
382
382
self._pending_parents_stack = []
383
383
# When we first look at a node we assign it a seqence number from its
384
384
# leftmost parent.
385
self._assigned_sequence_stack = []
385
self._first_child_stack = []
386
386
# this is a set of the nodes who have been completely analysed for fast
387
387
# membership checking
388
388
self._completed_node_names = set()
439
439
node_merge_depth_stack_append=node_merge_depth_stack.append,
440
440
left_subtree_pushed_stack_append=left_subtree_pushed_stack.append,
441
441
pending_parents_stack_append=pending_parents_stack.append,
442
assigned_sequence_stack_append=self._assigned_sequence_stack.append,
443
original_graph=self._original_graph,
442
first_child_stack_append=self._first_child_stack.append,
444
443
revnos=self._revnos,
446
445
"""Add node_name to the pending node stack.
455
454
node_merge_depth_stack_append(merge_depth)
456
455
left_subtree_pushed_stack_append(False)
457
456
pending_parents_stack_append(list(parents))
458
# as we push it, assign it a sequence number against its parent:
459
parents = original_graph[node_name]
457
# as we push it, check if it is the first child
461
459
# node has parents, assign from the left most parent.
462
parent_revno = revnos[parents[0]]
463
sequence = parent_revno[1]
460
parent_info = revnos[parents[0]]
461
first_child = parent_info[1]
462
parent_info[1] = False
466
# no parents, use the root sequence
467
sequence = self._root_sequence
468
self._root_sequence +=1
469
assigned_sequence_stack_append(sequence)
464
# We don't use the same algorithm here, but we need to keep the
467
first_child_stack_append(first_child)
471
469
def pop_node(node_name_stack_pop=node_name_stack.pop,
472
470
node_merge_depth_stack_pop=node_merge_depth_stack.pop,
473
assigned_sequence_stack_pop=self._assigned_sequence_stack.pop,
471
first_child_stack_pop=self._first_child_stack.pop,
474
472
left_subtree_pushed_stack_pop=left_subtree_pushed_stack.pop,
475
473
pending_parents_stack_pop=pending_parents_stack.pop,
476
474
original_graph=self._original_graph,
477
475
revnos=self._revnos,
478
476
completed_node_names_add=self._completed_node_names.add,
479
477
scheduled_nodes_append=scheduled_nodes.append,
478
revno_to_branch_count=self._revno_to_branch_count,
481
480
"""Pop the top node off the stack
486
485
# pop off the local variables
487
486
node_name = node_name_stack_pop()
488
487
merge_depth = node_merge_depth_stack_pop()
489
sequence = assigned_sequence_stack_pop()
488
first_child = first_child_stack_pop()
490
489
# remove this node from the pending lists:
491
490
left_subtree_pushed_stack_pop()
492
491
pending_parents_stack_pop()
494
493
parents = original_graph[node_name]
496
495
# node has parents, assign from the left most parent.
497
parent_revno = revnos[parents[0]]
496
parent_revno = revnos[parents[0]][0]
499
498
# not the first child, make a new branch
500
revno = parent_revno[0] + (sequence, 1)
499
base_revno = parent_revno[0]
500
branch_count = revno_to_branch_count.get(base_revno, 0)
502
revno_to_branch_count[base_revno] = branch_count
503
revno = (parent_revno[0], branch_count, 1)
504
# revno = (parent_revno[0], branch_count, parent_revno[-1]+1)
502
# increment the sequence number within the branch
503
revno = parent_revno[0][:-1] + (parent_revno[0][-1] + 1,)
506
# as the first child, we just increase the final revision
508
revno = parent_revno[:-1] + (parent_revno[-1] + 1,)
505
510
# no parents, use the root sequence
507
# make a parallel import revision number
508
revno = (0, sequence, 1)
511
root_count = revno_to_branch_count.get(0, 0)
513
revno = (0, root_count, 1)
517
revno_to_branch_count[0] = root_count
512
519
# store the revno for this node for future reference
513
520
revnos[node_name][0] = revno
610
617
self._node_merge_depth_stack.append(merge_depth)
611
618
self._left_subtree_pushed_stack.append(False)
612
619
self._pending_parents_stack.append(list(parents))
613
# as we push it, assign it a sequence number against its parent:
620
# as we push it, figure out if this is the first child
614
621
parents = self._original_graph[node_name]
616
623
# node has parents, assign from the left most parent.
617
parent_revno = self._revnos[parents[0]]
618
sequence = parent_revno[1]
624
parent_info = self._revnos[parents[0]]
625
first_child = parent_info[1]
626
parent_info[1] = False
621
# no parents, use the root sequence
622
sequence = self._root_sequence
623
self._root_sequence +=1
624
self._assigned_sequence_stack.append(sequence)
628
# We don't use the same algorithm here, but we need to keep the
631
self._first_child_stack.append(first_child)
626
633
def _pop_node(self):
627
634
"""Pop the top node off the stack
632
639
# pop off the local variables
633
640
node_name = self._node_name_stack.pop()
634
641
merge_depth = self._node_merge_depth_stack.pop()
635
sequence = self._assigned_sequence_stack.pop()
642
first_child = self._first_child_stack.pop()
636
643
# remove this node from the pending lists:
637
644
self._left_subtree_pushed_stack.pop()
638
645
self._pending_parents_stack.pop()
640
647
parents = self._original_graph[node_name]
642
649
# node has parents, assign from the left most parent.
643
parent_revno = self._revnos[parents[0]]
650
parent_revno = self._revnos[parents[0]][0]
645
652
# not the first child, make a new branch
646
revno = parent_revno[0] + (sequence, 1)
653
base_revno = parent_revno[0]
654
branch_count = self._revno_to_branch_count.get(base_revno, 0)
656
self._revno_to_branch_count[base_revno] = branch_count
657
revno = (parent_revno[0], branch_count, 1)
658
# revno = (parent_revno[0], branch_count, parent_revno[-1]+1)
648
# increment the sequence number within the branch
649
revno = parent_revno[0][:-1] + (parent_revno[0][-1] + 1,)
660
# as the first child, we just increase the final revision
662
revno = parent_revno[:-1] + (parent_revno[-1] + 1,)
651
664
# no parents, use the root sequence
653
# make a parallel import revision number
654
revno = (0, sequence, 1)
665
root_count = self._revno_to_branch_count.get(0, 0)
667
revno = (0, root_count, 1)
671
self._revno_to_branch_count[0] = root_count
658
673
# store the revno for this node for future reference
659
674
self._revnos[node_name][0] = revno