@@ -627,135 +627,160 @@ class DiffBuilder(object):
627627 def __init__ (self , src , dst ):
628628 self .src = src
629629 self .dst = dst
630- self .index_storage = [{}, {}]
631- self .index_storage2 = [[], []]
632- self .__root = root = []
633- root [:] = [root , root , None ]
634630
635- def store_index (self , value , index , st ):
636- try :
637- storage = self .index_storage [st ]
638- stored = storage .get (value )
639- if stored is None :
640- storage [value ] = [index ]
641- else :
642- storage [value ].append (index )
643-
644- except TypeError :
645- self .index_storage2 [st ].append ((value , index ))
646-
647- def take_index (self , value , st ):
648- try :
649- stored = self .index_storage [st ].get (value )
650- if stored :
651- return stored .pop ()
631+ self .ops = []
632+ self .index_changes = {}
652633
653- except TypeError :
654- storage = self .index_storage2 [st ]
655- for i in range (len (storage )- 1 , - 1 , - 1 ):
656- if storage [i ][0 ] == value :
657- return storage .pop (i )[1 ]
634+ # self.index_storage = [{}, {}]
635+ # self.index_storage2 = [[], []]
636+ #
637+ # self.__root = root = []
638+ # root[:] = [root, root, None]
639+
640+ # def store_index(self, value, index, st):
641+ # try:
642+ # storage = self.index_storage[st]
643+ # stored = storage.get(value)
644+ # if stored is None:
645+ # storage[value] = [index]
646+ # else:
647+ # storage[value].append(index)
648+ #
649+ # except TypeError:
650+ # self.index_storage2[st].append((value, index))
651+ #
652+ # def take_index(self, value, st):
653+ # try:
654+ # stored = self.index_storage[st].get(value)
655+ # if stored:
656+ # return stored.pop()
657+ #
658+ # except TypeError:
659+ # storage = self.index_storage2[st]
660+ # for i in range(len(storage)-1, -1, -1):
661+ # if storage[i][0] == value:
662+ # return storage.pop(i)[1]
658663
659664 def insert (self , op ):
660- root = self .__root
661- last = root [0 ]
662- last [1 ] = root [0 ] = [last , root , op ]
663- return root [0 ]
664-
665- def remove (self , index ):
666- link_prev , link_next , _ = index
667- link_prev [1 ] = link_next
668- link_next [0 ] = link_prev
669- index [:] = []
670-
671- def iter_from (self , start ):
672- root = self .__root
673- curr = start [1 ]
674- while curr is not root :
675- yield curr [2 ]
676- curr = curr [1 ]
677-
678- def __iter__ (self ):
679- root = self .__root
680- curr = root [1 ]
681- while curr is not root :
682- yield curr [2 ]
683- curr = curr [1 ]
665+ self .ops .append (op )
666+ # root = self.__root
667+ # last = root[0]
668+ # last[1] = root[0] = [last, root, op]
669+ # return root[0]
670+ #
671+ # def remove(self, index):
672+ # link_prev, link_next, _ = index
673+ # link_prev[1] = link_next
674+ # link_next[0] = link_prev
675+ # index[:] = []
676+ #
677+ # def iter_from(self, start):
678+ # root = self.__root
679+ # curr = start[1]
680+ # while curr is not root:
681+ # yield curr[2]
682+ # curr = curr[1]
683+ #
684+ # def __iter__(self):
685+ # root = self.__root
686+ # curr = root[1]
687+ # while curr is not root:
688+ # yield curr[2]
689+ # curr = curr[1]
684690
685691 def execute (self ):
686692 self ._compare_values ('' , None , self .src , self .dst )
687693
688- root = self .__root
689- curr = root [1 ]
690- while curr is not root :
691- if curr [1 ] is not root :
692- op_first , op_second = curr [2 ], curr [1 ][2 ]
693- if op_first .location == op_second .location and \
694- type (op_first ) == RemoveOperation and \
695- type (op_second ) == AddOperation :
696- yield ReplaceOperation ({
697- 'op' : 'replace' ,
698- 'path' : op_second .location ,
699- 'value' : op_second .operation ['value' ],
700- }).operation
701- curr = curr [1 ][1 ]
702- continue
703-
704- yield curr [2 ].operation
705- curr = curr [1 ]
694+ return list (self .ops )
695+
696+ # root = self.__root
697+ # curr = root[1]
698+ # while curr is not root:
699+ # if curr[1] is not root:
700+ # op_first, op_second = curr[2], curr[1][2]
701+ # if op_first.location == op_second.location and \
702+ # type(op_first) == RemoveOperation and \
703+ # type(op_second) == AddOperation:
704+ # yield ReplaceOperation({
705+ # 'op': 'replace',
706+ # 'path': op_second.location,
707+ # 'value': op_second.operation['value'],
708+ # }).operation
709+ # curr = curr[1][1]
710+ # continue
711+ #
712+ # yield curr[2].operation
713+ # curr = curr[1]
706714
707715 def _item_added (self , path , key , item ):
708- index = self .take_index (item , _ST_REMOVE )
709- if index is not None :
710- op = index [2 ]
711- if type (op .key ) == int :
712- for v in self .iter_from (index ):
713- op .key = v ._on_undo_remove (op .path , op .key )
714-
715- self .remove (index )
716- if op .location != _path_join (path , key ):
717- new_op = MoveOperation ({
718- 'op' : 'move' ,
719- 'from' : op .location ,
720- 'path' : _path_join (path , key ),
721- })
722- self .insert (new_op )
723- else :
724- new_op = AddOperation ({
725- 'op' : 'add' ,
726- 'path' : _path_join (path , key ),
727- 'value' : item ,
728- })
729- new_index = self .insert (new_op )
730- self .store_index (item , new_index , _ST_ADD )
716+ key = self .get_index_change (path , key )
717+
718+ new_op = AddOperation ({
719+ 'op' : 'add' ,
720+ 'path' : _path_join (path , key ),
721+ 'value' : item ,
722+ })
723+ self .insert (new_op )
724+
725+ self .add_index_change (path , key , + 1 )
726+
727+ # index = self.take_index(item, _ST_REMOVE)
728+ # if index is not None:
729+ # op = index[2]
730+ # if type(op.key) == int:
731+ # for v in self.iter_from(index):
732+ # op.key = v._on_undo_remove(op.path, op.key)
733+ #
734+ # self.remove(index)
735+ # if op.location != _path_join(path, key):
736+ # new_op = MoveOperation({
737+ # 'op': 'move',
738+ # 'from': op.location,
739+ # 'path': _path_join(path, key),
740+ # })
741+ # self.insert(new_op)
742+ # else:
743+ # new_op = AddOperation({
744+ # 'op': 'add',
745+ # 'path': _path_join(path, key),
746+ # 'value': item,
747+ # })
748+ # new_index = self.insert(new_op)
749+ # self.store_index(item, new_index, _ST_ADD)
731750
732751 def _item_removed (self , path , key , item ):
752+ key = self .get_index_change (path , key )
753+
733754 new_op = RemoveOperation ({
734755 'op' : 'remove' ,
735756 'path' : _path_join (path , key ),
736757 })
737- index = self .take_index (item , _ST_ADD )
738- new_index = self .insert (new_op )
739- if index is not None :
740- op = index [2 ]
741- if type (op .key ) == int :
742- for v in self .iter_from (index ):
743- op .key = v ._on_undo_add (op .path , op .key )
744-
745- self .remove (index )
746- if new_op .location != op .location :
747- new_op = MoveOperation ({
748- 'op' : 'move' ,
749- 'from' : new_op .location ,
750- 'path' : op .location ,
751- })
752- new_index [2 ] = new_op
758+ self .insert (new_op )
753759
754- else :
755- self .remove (new_index )
760+ self .add_index_change (path , key , - 1 )
756761
757- else :
758- self .store_index (item , new_index , _ST_REMOVE )
762+ # index = self.take_index(item, _ST_ADD)
763+ # new_index = self.insert(new_op)
764+ # if index is not None:
765+ # op = index[2]
766+ # if type(op.key) == int:
767+ # for v in self.iter_from(index):
768+ # op.key = v._on_undo_add(op.path, op.key)
769+ #
770+ # self.remove(index)
771+ # if new_op.location != op.location:
772+ # new_op = MoveOperation({
773+ # 'op': 'move',
774+ # 'from': new_op.location,
775+ # 'path': op.location,
776+ # })
777+ # new_index[2] = new_op
778+ #
779+ # else:
780+ # self.remove(new_index)
781+ #
782+ # else:
783+ # self.store_index(item, new_index, _ST_REMOVE)
759784
760785 def _item_replaced (self , path , key , item ):
761786 self .insert (ReplaceOperation ({
@@ -822,6 +847,17 @@ def _compare_values(self, path, key, src, dst):
822847 else :
823848 self ._item_replaced (path , key , dst )
824849
850+ def add_index_change (self , path , key , change ):
851+ path_changes = self .index_changes .get (path , {})
852+ key_change = path_changes .get (key , 0 )
853+ key_change = key_change + change
854+ path_changes [key ] = key_change
855+
856+ def get_index_change (self , path , key ):
857+ path_changes = self .index_changes .get (path , {})
858+ keys = patch ...
859+
860+
825861
826862def _path_join (path , key ):
827863 if key is None :
0 commit comments