From 0e80dafade0009c34c386f17a15d10fdc15a6e09 Mon Sep 17 00:00:00 2001 From: Jatin Garg Date: Fri, 11 Mar 2022 22:15:50 +0530 Subject: [PATCH 1/2] Add recursive firing of dispose events of sub directory deletion --- packages/dds/map/src/directory.ts | 22 ++++++++++++++++++++- packages/dds/map/src/test/directory.spec.ts | 16 +++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/packages/dds/map/src/directory.ts b/packages/dds/map/src/directory.ts index a1b4e7ac777d..b65e346adde7 100644 --- a/packages/dds/map/src/directory.ts +++ b/packages/dds/map/src/directory.ts @@ -1537,7 +1537,27 @@ class SubDirectory extends TypedEventEmitter implements IDirec // This should make the subdirectory structure unreachable so it can be GC'd and won't appear in snapshots // Might want to consider cleaning out the structure more exhaustively though? const successfullyRemoved = this._subdirectories.delete(subdirName); - previousValue?.dispose(); + this.disposeSubDirectoryTree(previousValue); return successfullyRemoved; } + + private disposeSubDirectoryTree(directory: IDirectory | undefined) { + if (!directory) { + return; + } + const stack: [{node: IDirectory, visited: boolean}] = [{node: directory, visited: false}]; + while (stack.length > 0) { + const node = stack.pop(); + assert(node !== undefined, "Sub directory should be present"); + if (node.visited) { + node.node.dispose(); + } else { + stack.push({node: node.node, visited: true}); + const subDirectories = node.node.subdirectories(); + for (const [_, subDirectory] of subDirectories) { + stack.push({node: subDirectory, visited: false}); + } + } + } + } } diff --git a/packages/dds/map/src/test/directory.spec.ts b/packages/dds/map/src/test/directory.spec.ts index b6a46d132d7a..778bed6095de 100644 --- a/packages/dds/map/src/test/directory.spec.ts +++ b/packages/dds/map/src/test/directory.spec.ts @@ -184,6 +184,22 @@ describe("Directory", () => { } catch (error) { assert.strictEqual(error.errorType, "usageError", "Should throw usage error"); } + + // Check recursive dispose event firing + const subSubDirectory = newSubDirectory.createSubDirectory("rockChild"); + let rockSubDirectoryDisposed = false; + let subSubDirectoryDisposed = false; + newSubDirectory.on("disposed", (value: IDirectory) => { + rockSubDirectoryDisposed = true; + assert.equal(value.disposed, true, "rock sub directory not deleted"); + }); + subSubDirectory.on("disposed", (value: IDirectory) => { + subSubDirectoryDisposed = true; + assert.equal(value.disposed, true, "sub sub directory not deleted"); + }); + directory.deleteSubDirectory("rock"); + assert(rockSubDirectoryDisposed, "Rock sub directory should be disposed"); + assert(subSubDirectoryDisposed, "sub sub directory should be disposed"); }); it("Rejects a undefined and null key set", () => { From 29326db1863498208f422348a27b3b44e6057796 Mon Sep 17 00:00:00 2001 From: Jatin Garg Date: Mon, 14 Mar 2022 22:59:16 +0530 Subject: [PATCH 2/2] delete --- packages/dds/map/src/directory.ts | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/packages/dds/map/src/directory.ts b/packages/dds/map/src/directory.ts index b65e346adde7..ca1b0c1a0e6a 100644 --- a/packages/dds/map/src/directory.ts +++ b/packages/dds/map/src/directory.ts @@ -1545,19 +1545,11 @@ class SubDirectory extends TypedEventEmitter implements IDirec if (!directory) { return; } - const stack: [{node: IDirectory, visited: boolean}] = [{node: directory, visited: false}]; - while (stack.length > 0) { - const node = stack.pop(); - assert(node !== undefined, "Sub directory should be present"); - if (node.visited) { - node.node.dispose(); - } else { - stack.push({node: node.node, visited: true}); - const subDirectories = node.node.subdirectories(); - for (const [_, subDirectory] of subDirectories) { - stack.push({node: subDirectory, visited: false}); - } - } + // Dispose the subdirectory tree. This will dispose the subdirectories from bottom to top. + const subDirectories = directory.subdirectories(); + for (const [_, subDirectory] of subDirectories) { + this.disposeSubDirectoryTree(subDirectory); } + directory.dispose(); } }