From b5de4dd57d805502c1cc00577ccd67eab1933bfb Mon Sep 17 00:00:00 2001 From: ShikiSuen Date: Thu, 2 Mar 2023 17:21:19 +0800 Subject: [PATCH] Megrez // Memory sanitization. --- .../vChewing_Megrez/Sources/Megrez/2_Walker.swift | 14 +++++++++++--- .../vChewing_Megrez/Sources/Megrez/5_Vertex.swift | 12 +++++++++++- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/Packages/vChewing_Megrez/Sources/Megrez/2_Walker.swift b/Packages/vChewing_Megrez/Sources/Megrez/2_Walker.swift index bc34c603..8553fddd 100644 --- a/Packages/vChewing_Megrez/Sources/Megrez/2_Walker.swift +++ b/Packages/vChewing_Megrez/Sources/Megrez/2_Walker.swift @@ -32,6 +32,7 @@ public extension Megrez.Compositor { } let terminal = Vertex(node: .init(keyArray: ["_TERMINAL_"])) + var root = Vertex(node: .init(keyArray: ["_ROOT_"])) for (i, vertexSpan) in vertexSpans.enumerated() { for vertex in vertexSpan { @@ -46,11 +47,10 @@ public extension Megrez.Compositor { } } - let root = Vertex(node: .init(keyArray: ["_ROOT_"])) root.distance = 0 root.edges.append(contentsOf: vertexSpans[0]) - var ordered: [Vertex] = topologicalSort(root: root) + var ordered = topologicalSort(root: &root) for (j, neta) in ordered.reversed().enumerated() { for (k, _) in neta.edges.enumerated() { relax(u: neta, v: &neta.edges[k]) @@ -58,15 +58,23 @@ public extension Megrez.Compositor { ordered[j] = neta } + var iterated = terminal var walked = [Node]() var totalLengthOfKeys = 0 - var iterated = terminal + while let itPrev = iterated.prev { walked.append(itPrev.node) iterated = itPrev totalLengthOfKeys += iterated.node.spanLength } + // 清理內容,否則會有記憶體洩漏。 + ordered.removeAll() + vertexSpans.removeAll() + iterated.destroy() + root.destroy() + terminal.destroy() + guard totalLengthOfKeys == keys.count else { print("!!! ERROR A") return (result, false) diff --git a/Packages/vChewing_Megrez/Sources/Megrez/5_Vertex.swift b/Packages/vChewing_Megrez/Sources/Megrez/5_Vertex.swift index 3a64b318..6072d337 100644 --- a/Packages/vChewing_Megrez/Sources/Megrez/5_Vertex.swift +++ b/Packages/vChewing_Megrez/Sources/Megrez/5_Vertex.swift @@ -29,6 +29,16 @@ extension Megrez.Compositor { public init(node: Node) { self.node = node } + + /// 讓一個 Vertex 順藤摸瓜地將自己的所有的連帶的 Vertex 都摧毀,再摧毀自己。 + /// 此過程必須在一套 Vertex 全部使用完畢之後執行一次,可防止記憶體洩漏。 + public func destroy() { + while prev?.prev != nil { prev?.destroy() } + prev = nil + edges.forEach { $0.destroy() } + edges.removeAll() + node = .init() + } } /// 卸勁函式。 @@ -67,7 +77,7 @@ extension Megrez.Compositor { /// 至於其遞迴版本,則類似於 Cormen 在 2001 年的著作「Introduction to Algorithms」當中的樣子。 /// - Parameter root: 根頂點。 /// - Returns: 排序結果(頂點陣列)。 - func topologicalSort(root: Vertex) -> [Vertex] { + func topologicalSort(root: inout Vertex) -> [Vertex] { class State { var iterIndex: Int let vertex: Vertex