diff --git a/Source/Modules/LangModelRelated/SubLMs/lmCoreEX.swift b/Source/Modules/LangModelRelated/SubLMs/lmCoreEX.swift index f9fb705e..f3d60bb4 100644 --- a/Source/Modules/LangModelRelated/SubLMs/lmCoreEX.swift +++ b/Source/Modules/LangModelRelated/SubLMs/lmCoreEX.swift @@ -23,26 +23,38 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/// 與之前的 LMCore 不同,LMCoreEX 不在辭典內記錄實體,而是記錄 range 範圍。 -/// 需要資料的時候,直接拿 range 去 strData 取資料。 -/// 資料記錄原理與上游 C++ 的 ParselessLM 差不多,但用的是 Swift 原生手段。 -/// 主要時間消耗仍在 For 迴圈,但這個算法可以顯著減少記憶體佔用。 - import Foundation extension vChewing { + /// 與之前的 LMCore 不同,LMCoreEX 不在辭典內記錄實體,而是記錄 range 範圍。 + /// 需要資料的時候,直接拿 range 去 strData 取資料。 + /// 資料記錄原理與上游 C++ 的 ParselessLM 差不多,但用的是 Swift 原生手段。 + /// 主要時間消耗仍在 For 迴圈,但這個算法可以顯著減少記憶體佔用。 @frozen public struct LMCoreEX { + /// 資料庫陣列。索引內容為注音字串,資料內容則為字串首尾範圍、方便自 strData 取資料。 var rangeMap: [String: [Range]] = [:] + /// 資料庫字串陣列。 var strData: String = "" + /// 聲明原始檔案內第一、二縱列的內容是否彼此顛倒。 var shouldReverse: Bool = false var allowConsolidation: Bool = false + /// 當某一筆資料內的權重資料毀損時,要施加的預設權重。 var defaultScore: Double = 0 + /// 啟用該選項的話,會強制施加預設權重、而無視原始權重資料。 var shouldForceDefaultScore: Bool = false + /// 資料陣列內承載的資料筆數。 public var count: Int { rangeMap.count } + /// 初期化該語言模型。 + /// + /// - parameters: + /// - reverse: 聲明原始檔案內第一、二縱列的內容是否彼此顛倒 + /// - consolidate: 請且僅請對使用者語言模組啟用該參數:是否自動整理格式 + /// - defaultScore: 當某一筆資料內的權重資料毀損時,要施加的預設權重 + /// - forceDefaultScore: 啟用該選項的話,會強制施加預設權重、而無視原始權重資料 public init( reverse: Bool = false, consolidate: Bool = false, defaultScore scoreDefault: Double = 0, forceDefaultScore: Bool = false @@ -54,10 +66,14 @@ extension vChewing { shouldForceDefaultScore = forceDefaultScore } + /// 檢測資料庫陣列內是否已經有載入的資料。 public func isLoaded() -> Bool { !rangeMap.isEmpty } + /// 將資料從檔案讀入至資料庫陣列內。 + /// - parameters: + /// - path: 給定路徑 @discardableResult public mutating func open(_ path: String) -> Bool { if isLoaded() { return false @@ -89,6 +105,7 @@ extension vChewing { return true } + /// 將當前語言模組的資料庫陣列自記憶體內卸除。 public mutating func close() { if isLoaded() { rangeMap.removeAll() @@ -97,6 +114,9 @@ extension vChewing { // MARK: - Advanced features + /// 將當前資料庫陣列的內容以文本的形式輸出至 macOS 內建的 Console.app。 + /// + /// 該功能僅作偵錯之用途。 public func dump() { var strDump = "" for entry in rangeMap { @@ -110,12 +130,21 @@ extension vChewing { IME.prtDebugIntel(strDump) } + /// 【該功能無法使用】根據給定的前述讀音索引鍵與當前讀音索引鍵,來獲取資料庫陣列內的對應資料陣列的字串首尾範圍資料、據此自 strData 取得字串形式的資料、生成雙元圖陣列。 + /// + /// 威注音輸入法尚未引入雙元圖支援,所以該函數並未擴充相關功能,自然不會起作用。 + /// - parameters: + /// - precedingKey: 前述讀音索引鍵 + /// - key: 當前讀音索引鍵 public func bigramsForKeys(precedingKey: String, key: String) -> [Megrez.Bigram] { // 這裡用了點廢話處理,不然函數構建體會被 Swift 格式整理工具給毀掉。 // 其實只要一句「[Megrez.Bigram]()」就夠了。 precedingKey == key ? [Megrez.Bigram]() : [Megrez.Bigram]() } + /// 根據給定的讀音索引鍵,來獲取資料庫陣列內的對應資料陣列的字串首尾範圍資料、據此自 strData 取得字串形式的資料、生成單元圖陣列。 + /// - parameters: + /// - key: 讀音索引鍵 public func unigramsFor(key: String) -> [Megrez.Unigram] { var grams: [Megrez.Unigram] = [] if let arrRangeRecords: [Range] = rangeMap[key] { @@ -136,6 +165,9 @@ extension vChewing { return grams } + /// 根據給定的讀音索引鍵來確認資料庫陣列內是否存在對應的資料。 + /// - parameters: + /// - key: 讀音索引鍵 public func hasUnigramsFor(key: String) -> Bool { rangeMap[key] != nil } @@ -145,6 +177,9 @@ extension vChewing { // MARK: - StringView Ranges Extension (by Isaac Xen) extension String { + /// 就該字串與給定分隔符、返回每一元素的首尾索引值。 + /// - parameters: + /// - splitBy: 給定分隔符 fileprivate func ranges(splitBy separator: Element) -> [Range] { var startIndex = startIndex return split(separator: separator).reduce(into: []) { ranges, substring in diff --git a/Source/Modules/LangModelRelated/SubLMs/lmCoreNS.swift b/Source/Modules/LangModelRelated/SubLMs/lmCoreNS.swift index 7e4eacb6..74a7eb26 100644 --- a/Source/Modules/LangModelRelated/SubLMs/lmCoreNS.swift +++ b/Source/Modules/LangModelRelated/SubLMs/lmCoreNS.swift @@ -22,24 +22,40 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/// 與之前的 LMCore 不同,LMCoreNS 直接讀取 plist。 -/// 這樣一來可以節省在舊 mac 機種內的資料讀入速度。 - import Foundation extension vChewing { + /// 與之前的 LMCore 不同,LMCoreNS 直接讀取 plist。 + /// 這樣一來可以節省在舊 mac 機種內的資料讀入速度。 + /// 目前僅針對輸入法原廠語彙資料檔案使用 plist 格式。 @frozen public struct LMCoreNS { + /// 資料庫陣列。索引內容為經過加密的注音字串,資料內容則為 UTF8 資料陣列。 var rangeMap: [String: [Data]] = [:] + /// 【已作廢】資料庫字串陣列。在 LMCoreNS 內沒有作用。 var strData: String = "" + /// 【已作廢】聲明原始檔案內第一、二縱列的內容是否彼此顛倒。 var shouldReverse: Bool = false + /// 請且僅請對使用者語言模組啟用該參數:是否自動整理格式。 var allowConsolidation: Bool = false + /// 當某一筆資料內的權重資料毀損時,要施加的預設權重。 var defaultScore: Double = 0 + /// 啟用該選項的話,會強制施加預設權重、而無視原始權重資料。 var shouldForceDefaultScore: Bool = false + /// 資料陣列內承載的資料筆數。 public var count: Int { rangeMap.count } + /// 初期化該語言模型。 + /// + /// 某些參數在 LMCoreNS 內已作廢,但仍保留、以方便那些想用該專案源碼做實驗的人群。 + /// + /// - parameters: + /// - reverse: 已作廢:聲明原始檔案內第一、二縱列的內容是否彼此顛倒 + /// - consolidate: 請且僅請對使用者語言模組啟用該參數:是否自動整理格式 + /// - defaultScore: 當某一筆資料內的權重資料毀損時,要施加的預設權重 + /// - forceDefaultScore: 啟用該選項的話,會強制施加預設權重、而無視原始權重資料 public init( reverse: Bool = false, consolidate: Bool = false, defaultScore scoreDefault: Double = 0, forceDefaultScore: Bool = false @@ -51,10 +67,14 @@ extension vChewing { shouldForceDefaultScore = forceDefaultScore } + /// 檢測資料庫陣列內是否已經有載入的資料。 public func isLoaded() -> Bool { !rangeMap.isEmpty } + /// 將資料從檔案讀入至資料庫陣列內。 + /// - parameters: + /// - path: 給定路徑 @discardableResult public mutating func open(_ path: String) -> Bool { if isLoaded() { return false @@ -77,6 +97,7 @@ extension vChewing { return true } + /// 將當前語言模組的資料庫陣列自記憶體內卸除。 public mutating func close() { if isLoaded() { rangeMap.removeAll() @@ -85,6 +106,9 @@ extension vChewing { // MARK: - Advanced features + /// 將當前資料庫陣列的內容以文本的形式輸出至 macOS 內建的 Console.app。 + /// + /// 該功能僅作偵錯之用途。 public func dump() { var strDump = "" for entry in rangeMap { @@ -104,12 +128,21 @@ extension vChewing { IME.prtDebugIntel(strDump) } + /// 【該功能無法使用】根據給定的前述讀音索引鍵與當前讀音索引鍵,來獲取資料庫陣列內的對應資料陣列的 UTF8 資料、就地分析、生成雙元圖陣列。 + /// + /// 威注音輸入法尚未引入雙元圖支援,所以該函數並未擴充相關功能,自然不會起作用。 + /// - parameters: + /// - precedingKey: 前述讀音索引鍵 + /// - key: 當前讀音索引鍵 public func bigramsForKeys(precedingKey: String, key: String) -> [Megrez.Bigram] { // 這裡用了點廢話處理,不然函數構建體會被 Swift 格式整理工具給毀掉。 // 其實只要一句「[Megrez.Bigram]()」就夠了。 precedingKey == key ? [Megrez.Bigram]() : [Megrez.Bigram]() } + /// 根據給定的讀音索引鍵,來獲取資料庫陣列內的對應資料陣列的 UTF8 資料、就地分析、生成單元圖陣列。 + /// - parameters: + /// - key: 讀音索引鍵 public func unigramsFor(key: String) -> [Megrez.Unigram] { var grams: [Megrez.Unigram] = [] if let arrRangeRecords: [Data] = rangeMap[cnvPhonabetToASCII(key)] { @@ -131,10 +164,20 @@ extension vChewing { return grams } + /// 根據給定的讀音索引鍵來確認資料庫陣列內是否存在對應的資料。 + /// - parameters: + /// - key: 讀音索引鍵 public func hasUnigramsFor(key: String) -> Bool { rangeMap[cnvPhonabetToASCII(key)] != nil } + /// 內部函數,用以將注音讀音索引鍵進行加密。 + /// + /// 使用這種加密字串作為索引鍵,可以增加對 plist 資料庫的存取速度。 + /// + /// 如果傳入的字串當中包含 ASCII 下畫線符號的話,則表明該字串並非注音讀音字串,會被忽略處理。 + /// - parameters: + /// - incoming: 傳入的未加密注音讀音字串 func cnvPhonabetToASCII(_ incoming: String) -> String { let dicPhonabet2ASCII = [ "ㄅ": "b", "ㄆ": "p", "ㄇ": "m", "ㄈ": "f", "ㄉ": "d", "ㄊ": "t", "ㄋ": "n", "ㄌ": "l", "ㄍ": "g", "ㄎ": "k", "ㄏ": "h", @@ -151,6 +194,11 @@ extension vChewing { return strOutput } + /// 內部函數,用以將被加密的注音讀音索引鍵進行解密。 + /// + /// 如果傳入的字串當中包含 ASCII 下畫線符號的話,則表明該字串並非注音讀音字串,會被忽略處理。 + /// - parameters: + /// - incoming: 傳入的已加密注音讀音字串 func restorePhonabetFromASCII(_ incoming: String) -> String { let dicPhonabet4ASCII = [ "b": "ㄅ", "p": "ㄆ", "m": "ㄇ", "f": "ㄈ", "d": "ㄉ", "t": "ㄊ", "n": "ㄋ", "l": "ㄌ", "g": "ㄍ", "k": "ㄎ", "h": "ㄏ",