@@ -107,36 +107,59 @@ export default class Diff<L1 extends TItemLocation, L2 extends TItemLocation, A
107107 )
108108 }
109109
110+ static containsParent ( mappingsSnapshot : MappingSnapshot , item1 : TItem < TItemLocation > , item2 : TItem < TItemLocation > , itemTree : Folder < TItemLocation > , cache : Record < string , boolean > ) : boolean {
111+ const cacheKey = 'contains:' + Mappings . mapId ( mappingsSnapshot , item2 , ItemLocation . LOCAL ) + ':' + Mappings . mapId ( mappingsSnapshot , item2 , ItemLocation . SERVER ) +
112+ '-' + Mappings . mapId ( mappingsSnapshot , item1 , ItemLocation . LOCAL ) + ':' + Mappings . mapId ( mappingsSnapshot , item1 , ItemLocation . SERVER )
113+ if ( typeof cache [ cacheKey ] !== 'undefined' ) {
114+ return cache [ cacheKey ]
115+ }
116+ const item1InTree = itemTree . findItem ( item1 . type , Mappings . mapId ( mappingsSnapshot , item1 , itemTree . location ) )
117+ if (
118+ item1 . findItem ( ItemType . FOLDER ,
119+ Mappings . mapParentId ( mappingsSnapshot , item2 , item1 . location ) ) ||
120+ ( item1InTree && item1InTree . findItem ( ItemType . FOLDER , Mappings . mapParentId ( mappingsSnapshot , item2 , itemTree . location ) ) ) ||
121+ String ( Mappings . mapId ( mappingsSnapshot , item1 , item2 . location ) ) === String ( item2 . parentId ) ||
122+ String ( Mappings . mapParentId ( mappingsSnapshot , item2 , item1 . location ) ) === String ( item1 . id )
123+ ) {
124+ cache [ cacheKey ] = true
125+ return true
126+ }
127+ cache [ cacheKey ] = false
128+ return false
129+ }
130+
110131 static findChain (
111132 mappingsSnapshot : MappingSnapshot ,
112- actions : Action < TItemLocation , TItemLocation > [ ] , itemTree : Folder < TItemLocation > ,
133+ actions : Action < TItemLocation , TItemLocation > [ ] ,
134+ itemTree : Folder < TItemLocation > ,
113135 currentItem : TItem < TItemLocation > ,
114136 targetAction : Action < TItemLocation , TItemLocation > ,
137+ cache : Record < string , boolean > = { } ,
115138 chain : Action < TItemLocation , TItemLocation > [ ] = [ ]
116139 ) : boolean {
117- const targetItemInTree = itemTree . findFolder ( Mappings . mapId ( mappingsSnapshot , targetAction . payload , itemTree . location ) )
118- if (
119- targetAction . payload . findItem ( ItemType . FOLDER ,
120- Mappings . mapParentId ( mappingsSnapshot , currentItem , targetAction . payload . location ) ) ||
121- ( targetItemInTree && targetItemInTree . findFolder ( Mappings . mapParentId ( mappingsSnapshot , currentItem , itemTree . location ) ) )
122- ) {
140+ const currentItemLocalId = Mappings . mapId ( mappingsSnapshot , currentItem , ItemLocation . LOCAL )
141+ const currentItemServerId = Mappings . mapId ( mappingsSnapshot , currentItem , ItemLocation . SERVER )
142+ const targetPayloadLocalId = Mappings . mapId ( mappingsSnapshot , targetAction . payload , ItemLocation . LOCAL )
143+ const targetPayloadServerId = Mappings . mapId ( mappingsSnapshot , targetAction . payload , ItemLocation . SERVER )
144+ const cacheKey = `hasChain:${ currentItemLocalId } :${ currentItemServerId } -${ targetPayloadLocalId } :${ targetPayloadServerId } `
145+ if ( typeof cache [ cacheKey ] !== 'undefined' ) {
146+ return cache [ cacheKey ]
147+ }
148+ if ( Diff . containsParent ( mappingsSnapshot , targetAction . payload , currentItem , itemTree , cache ) ) {
149+ cache [ cacheKey ] = true
123150 return true
124151 }
125- const newCurrentActions = actions . filter ( targetAction =>
126- ! chain . includes ( targetAction ) && (
127- targetAction . payload . findItem ( ItemType . FOLDER , Mappings . mapParentId ( mappingsSnapshot , currentItem , targetAction . payload . location ) ) ||
128- (
129- itemTree . findFolder ( Mappings . mapId ( mappingsSnapshot , targetAction . payload , itemTree . location ) ) &&
130- itemTree . findFolder ( Mappings . mapId ( mappingsSnapshot , targetAction . payload , itemTree . location ) ) . findFolder ( Mappings . mapParentId ( mappingsSnapshot , currentItem , itemTree . location ) ) )
131- )
152+ const newCurrentActions = actions . filter ( newTargetAction =>
153+ ! chain . includes ( newTargetAction ) && Diff . containsParent ( mappingsSnapshot , newTargetAction . payload , currentItem , itemTree , cache )
132154 )
133155 if ( newCurrentActions . length ) {
134156 for ( const newCurrentAction of newCurrentActions ) {
135- if ( Diff . findChain ( mappingsSnapshot , actions , itemTree , newCurrentAction . payload , targetAction , [ ...chain , newCurrentAction ] ) ) {
157+ if ( Diff . findChain ( mappingsSnapshot , actions , itemTree , newCurrentAction . payload , targetAction , cache , [ ...chain , newCurrentAction ] ) ) {
136158 return true
137159 }
138160 }
139161 }
162+ cache [ cacheKey ] = false
140163 return false
141164 }
142165
0 commit comments