@@ -310,13 +310,19 @@ export class DependencyGraph {
310310 } )
311311 }
312312
313+ /**
314+ * Marks all cell vertices in the sheet as dirty.
315+ */
313316 private markAllCellsAsDirtyInSheet ( sheetId : number ) : void {
314317 const sheetCells = this . addressMapping . sheetEntries ( sheetId )
315318 for ( const [ _ , vertex ] of sheetCells ) {
316319 this . graph . markNodeAsDirty ( vertex )
317320 }
318321 }
319322
323+ /**
324+ * Marks all range verticesin the sheet as dirty.
325+ */
320326 private markAllRangesAsDirtyInSheet ( sheetId : number ) : void {
321327 const sheetRanges = this . rangeMapping . rangesInSheet ( sheetId )
322328
@@ -344,37 +350,45 @@ export class DependencyGraph {
344350 }
345351
346352 /**
347- * TODO
353+ * TODO: implement
354+ *
355+ * sheetToKeep:
356+ * - existing,
357+ * - contains cell vertices,
358+ * - contains range vertices,
359+ * - contains array formula vertices,
360+ * - has dependencies and depentents
361+ *
362+ * sheetToDelete:
363+ * - placeholder,
364+ * - contains only empty cell vertices,
365+ * - contains range vertices,
366+ * - has dependents in other sheets,
367+ * - has dependencies only in same sheet (ranges)
348368 */
349- public mergeSheets ( sheetToKeep : number , sheetToDelete : number ) : void { // TODO: refactor
350- const cellsFromSheetToDelete = this . addressMapping . sheetEntries ( sheetToDelete )
351- const rangesFromSheetToDelete = Array . from ( this . rangeMapping . rangesInSheet ( sheetToDelete ) )
352-
353- for ( const [ addressToDelete , vertexToDelete ] of cellsFromSheetToDelete ) {
354- const addressToKeep = simpleCellAddress ( sheetToKeep , addressToDelete . col , addressToDelete . row )
355- const { vertex : vertexToKeep } = this . fetchCellOrCreateEmpty ( addressToKeep )
356- this . mergeVertices ( vertexToKeep , vertexToDelete )
357- this . graph . markNodeAsDirty ( vertexToKeep )
358- }
369+ public mergeSheets ( sheetToKeep : number , placeholderSheetToDelete : number ) : void {
370+ const rangeVertices = Array . from ( this . rangeMapping . rangesInSheet ( placeholderSheetToDelete ) )
359371
360- for ( const vertexToDelete of rangesFromSheetToDelete ) {
361- if ( ! ( vertexToDelete instanceof RangeVertex ) ) {
372+ for ( const vertexToDelete of rangeVertices ) {
373+ if ( ! this . graph . hasNode ( vertexToDelete ) ) {
362374 continue
363375 }
364376
365- const start = vertexToDelete . getStart ( )
366- const end = vertexToDelete . getEnd ( )
377+ const start = vertexToDelete . start
378+ const end = vertexToDelete . end
367379
368- if ( start . sheet !== sheetToDelete && end . sheet !== sheetToDelete ) {
380+ if ( start . sheet !== placeholderSheetToDelete && end . sheet !== placeholderSheetToDelete ) {
369381 continue
370382 }
371383
372384 const targetStart = simpleCellAddress ( sheetToKeep , start . col , start . row )
373385 const targetEnd = simpleCellAddress ( sheetToKeep , end . col , end . row )
374386 const vertexToKeep = this . rangeMapping . getRangeVertex ( targetStart , targetEnd )
375387
376- if ( vertexToKeep !== undefined ) {
377- this . mergeVertices ( vertexToKeep , vertexToDelete )
388+ if ( vertexToKeep ) {
389+ this . rerouteDependents ( vertexToDelete , vertexToKeep )
390+ this . removeVertexAndRerouteDependencies ( vertexToDelete , vertexToKeep )
391+ this . rangeMapping . removeVertexIfExists ( vertexToDelete )
378392 this . graph . markNodeAsDirty ( vertexToKeep )
379393 } else {
380394 this . rangeMapping . removeVertexIfExists ( vertexToDelete )
@@ -384,10 +398,24 @@ export class DependencyGraph {
384398 }
385399 }
386400
387- this . addressMapping . removeSheet ( sheetToDelete )
401+ const cellVertices = Array . from ( this . addressMapping . sheetEntries ( placeholderSheetToDelete ) )
388402
389- // TODO: adjust arrayMapping
403+ for ( const [ addressToDelete , vertexToDelete ] of cellVertices ) {
404+ const addressToKeep = simpleCellAddress ( sheetToKeep , addressToDelete . col , addressToDelete . row )
405+ const vertexToKeep = this . getCell ( addressToKeep )
390406
407+ if ( vertexToKeep ) {
408+ this . rerouteDependents ( vertexToDelete , vertexToKeep )
409+ this . removeVertexAndCleanupDependencies ( vertexToDelete )
410+ this . addressMapping . removeCell ( addressToDelete )
411+ this . graph . markNodeAsDirty ( vertexToKeep )
412+ } else {
413+ this . addressMapping . moveCell ( addressToDelete , addressToKeep )
414+ this . graph . markNodeAsDirty ( vertexToDelete )
415+ }
416+ }
417+
418+ this . addressMapping . removeSheet ( placeholderSheetToDelete )
391419 this . addStructuralNodesToChangeSet ( )
392420 }
393421
@@ -572,7 +600,7 @@ export class DependencyGraph {
572600 }
573601
574602 /**
575- * Sets an array formula vertex to empty.
603+ * Sets an array empty. .
576604 * - removes all corresponding entries from address mapping
577605 * - reroutes the edges
578606 * - removes vertex from graph and cleans up its dependencies
@@ -959,12 +987,14 @@ export class DependencyGraph {
959987 const allDeps : [ ( SimpleCellAddress | AbsoluteCellRange ) , Vertex ] [ ] = [ ]
960988 const { smallerRangeVertex, restRange} = this . rangeMapping . findSmallerRange ( ( vertex as RangeVertex ) . range ) //checking whether this range was splitted by bruteForce or not
961989 let range
990+
962991 if ( smallerRangeVertex !== undefined && this . graph . adjacentNodes ( smallerRangeVertex ) . has ( vertex ) ) {
963992 range = restRange
964993 allDeps . push ( [ new AbsoluteCellRange ( smallerRangeVertex . start , smallerRangeVertex . end ) , smallerRangeVertex ] )
965994 } else { //did we ever need to use full range
966995 range = ( vertex as RangeVertex ) . range
967996 }
997+
968998 for ( const address of range . addresses ( this ) ) {
969999 const cell = this . addressMapping . getCell ( address )
9701000 if ( cell !== undefined ) {
@@ -1106,7 +1136,8 @@ export class DependencyGraph {
11061136 verticesWithChangedSize
11071137 } = this . rangeMapping . truncateRanges ( span , coordinate )
11081138 for ( const [ existingVertex , mergedVertex ] of verticesToMerge ) {
1109- this . mergeVertices ( existingVertex , mergedVertex )
1139+ this . rerouteDependents ( mergedVertex , existingVertex )
1140+ this . removeVertexAndCleanupDependencies ( mergedVertex )
11101141 }
11111142 for ( const rangeVertex of verticesToRemove ) {
11121143 this . removeVertexAndCleanupDependencies ( rangeVertex )
@@ -1211,65 +1242,31 @@ export class DependencyGraph {
12111242 }
12121243
12131244 /**
1214- * - If vertex has dependents in other sheets, changes it to EmptyCellVertex and returns false
1215- * - Otherwise, removes it from the graph, cleans up its dependencies and returns true
1216- *
1217- * @returns True if the vertex was removed, false if it was changed to EmptyCellVertex.
1245+ * Reroutes dependent vertices of source to target. Also removes the edge target -> source if it exists.
12181246 */
1219- private removeVertexIfNoDependentsInOtherSheets ( inputVertex : Vertex ) : boolean {
1220- const dependents = this . getAdjacentNodesAddresses ( inputVertex )
1247+ private rerouteDependents ( source : Vertex , target : Vertex ) {
1248+ const dependents = this . graph . adjacentNodes ( source )
1249+ this . graph . removeEdgeIfExists ( target , source )
12211250
1222- const hasDependentInExistingSheet = dependents . some ( addr => {
1223- if ( isSimpleCellAddress ( addr ) ) {
1224- return ! this . isPlaceholder ( addr . sheet )
1225- }
1226-
1227- if ( isSimpleCellRange ( addr ) ) {
1228- return this . sheetMapping . hasSheetWithId ( addr . start . sheet , { includePlaceholders : false } ) || this . sheetMapping . hasSheetWithId ( addr . end . sheet , { includePlaceholders : false } )
1251+ dependents . forEach ( ( adjacentNode ) => {
1252+ if ( this . graph . hasNode ( adjacentNode ) ) {
1253+ this . graph . addEdge ( target , adjacentNode )
12291254 }
1230-
1231- return false
12321255 } )
12331256
1234- let dependencies : Set < [ SimpleCellAddress | SimpleCellRange , Vertex ] >
1235-
1236- if ( hasDependentInExistingSheet ) {
1237- dependencies = new Set ( this . graph . removeDependencies ( inputVertex ) )
1238- } else {
1239- dependencies = new Set ( this . graph . removeNode ( inputVertex ) )
1240- }
1241-
1242- while ( dependencies . size > 0 ) {
1243- const dependency = dependencies . values ( ) . next ( ) . value
1244- dependencies . delete ( dependency )
1245- const [ address , vertex ] = dependency
1246- if ( this . graph . hasNode ( vertex ) && this . graph . adjacentNodesCount ( vertex ) === 0 ) {
1247- if ( vertex instanceof RangeVertex || vertex instanceof EmptyCellVertex ) {
1248- this . graph . removeNode ( vertex ) . forEach ( ( candidate ) => dependencies . add ( candidate ) )
1249- }
1250- if ( vertex instanceof RangeVertex ) {
1251- this . rangeMapping . removeVertexIfExists ( vertex )
1252- } else if ( vertex instanceof EmptyCellVertex ) {
1253- this . addressMapping . removeCell ( address )
1254- }
1255- }
1256- }
1257-
1258- if ( inputVertex instanceof RangeVertex ) {
1259- this . rangeMapping . removeVertexIfExists ( inputVertex )
1260- }
1261-
1262- return ! hasDependentInExistingSheet
12631257 }
12641258
1265- private mergeVertices ( vertexToKeep : Vertex , vertexToDelete : Vertex ) {
1266- const adjNodesStored = this . graph . adjacentNodes ( vertexToDelete )
1259+ /**
1260+ * Removes a vertex from graph and reroutes its dependencies to other vertex. Also removes the edge vertexToKeep -> vertexToDelete if it exists.
1261+ */
1262+ private removeVertexAndRerouteDependencies ( vertexToDelete : Vertex , vertexToKeep : Vertex ) {
1263+ const dependencies = this . graph . removeNode ( vertexToDelete )
12671264
1268- this . removeVertexAndCleanupDependencies ( vertexToDelete )
12691265 this . graph . removeEdgeIfExists ( vertexToKeep , vertexToDelete )
1270- adjNodesStored . forEach ( ( adjacentNode ) => {
1271- if ( this . graph . hasNode ( adjacentNode ) ) {
1272- this . graph . addEdge ( vertexToKeep , adjacentNode )
1266+
1267+ dependencies . forEach ( ( [ _ , dependency ] ) => {
1268+ if ( this . graph . hasNode ( dependency ) ) {
1269+ this . graph . addEdge ( dependency , vertexToKeep )
12731270 }
12741271 } )
12751272 }
@@ -1280,6 +1277,7 @@ export class DependencyGraph {
12801277 */
12811278 private removeVertexAndCleanupDependencies ( inputVertex : Vertex ) {
12821279 const dependencies = new Set ( this . graph . removeNode ( inputVertex ) )
1280+
12831281 while ( dependencies . size > 0 ) {
12841282 const dependency = dependencies . values ( ) . next ( ) . value
12851283 dependencies . delete ( dependency )
0 commit comments