mirror of
https://github.com/neon443/StickerSlack.git
synced 2026-03-11 05:19:13 +00:00
storing the trie and the dict, should be much faster
idk if ts acc helped tho
This commit is contained in:
@@ -14,6 +14,8 @@ import Haptics
|
||||
class EmojiHoarder: ObservableObject {
|
||||
static let container = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.neon443.StickerSlack")!.appendingPathComponent("Library", conformingTo: .directory)
|
||||
nonisolated static let localEmojiDB: URL = EmojiHoarder.container.appendingPathComponent("_localEmojiDB.json", conformingTo: .fileURL)
|
||||
nonisolated static let localTrie: URL = EmojiHoarder.container.appendingPathComponent("_localTrie.json", conformingTo: .fileURL)
|
||||
nonisolated static let localTrieDict: URL = EmojiHoarder.container.appendingPathComponent("_localTrieDict.json", conformingTo: .fileURL)
|
||||
private let endpoint: URL = URL(string: "https://cachet.dunkirk.sh/emojis")!
|
||||
private let encoder = JSONEncoder()
|
||||
private let decoder = JSONDecoder()
|
||||
@@ -28,10 +30,11 @@ class EmojiHoarder: ObservableObject {
|
||||
init(localOnly: Bool = false, skipIndex: Bool = false) {
|
||||
let localDB = loadLocalDB()
|
||||
withAnimation { self.emojis = localDB }
|
||||
loadTrie()
|
||||
if !skipIndex { buildTrie() }
|
||||
|
||||
guard !localOnly else { return }
|
||||
Task.detached {
|
||||
Task {
|
||||
print("start loading remote db")
|
||||
await self.loadRemoteDB()
|
||||
print("end")
|
||||
@@ -69,22 +72,48 @@ class EmojiHoarder: ObservableObject {
|
||||
downloadedEmojis = []
|
||||
}
|
||||
|
||||
func saveTrie() {
|
||||
guard let data = try? encoder.encode(trie.root) else {
|
||||
fatalError("failed to encode trie")
|
||||
}
|
||||
try! data.write(to: EmojiHoarder.localTrie)
|
||||
|
||||
guard let dataDict = try? encoder.encode(trie.dict) else {
|
||||
fatalError("failed to encode trie dict")
|
||||
}
|
||||
try! dataDict.write(to: EmojiHoarder.localTrieDict)
|
||||
}
|
||||
|
||||
func loadTrie() {
|
||||
guard FileManager.default.fileExists(atPath: EmojiHoarder.localTrie.path) else { return }
|
||||
guard let data = try? Data(contentsOf: EmojiHoarder.localTrie) else { return }
|
||||
guard let decoded = try? decoder.decode(TrieNode.self, from: data) else {
|
||||
fatalError("failed to decode trie")
|
||||
}
|
||||
self.trie.root = decoded
|
||||
|
||||
guard FileManager.default.fileExists(atPath: EmojiHoarder.localTrieDict.path) else { return }
|
||||
guard let dataDict = try? Data(contentsOf: EmojiHoarder.localTrieDict) else { return }
|
||||
guard let decodedDict = try? decoder.decode([String:Emoji].self, from: dataDict) else {
|
||||
fatalError("failed to decode dict")
|
||||
}
|
||||
self.trie.dict = decodedDict
|
||||
}
|
||||
|
||||
func buildTrie() {
|
||||
let start = Date().timeIntervalSince1970
|
||||
trie.root = TrieNode()
|
||||
for emoji in emojis {
|
||||
trie.insert(word: emoji.name)
|
||||
}
|
||||
buildTrieDict()
|
||||
saveTrie()
|
||||
print("done building trie in", Date().timeIntervalSince1970-start)
|
||||
}
|
||||
|
||||
func buildTrieDict() {
|
||||
var dict: [String:Emoji] = [:]
|
||||
for emoji in emojis {
|
||||
dict[emoji.name] = emoji
|
||||
trie.dict[emoji.name] = emoji
|
||||
}
|
||||
self.trie.dict = dict
|
||||
buildDownloadedEmojis()
|
||||
}
|
||||
|
||||
|
||||
@@ -9,14 +9,14 @@ import Foundation
|
||||
import SwiftUI
|
||||
import Combine
|
||||
|
||||
class TrieNode: ObservableObject {
|
||||
@Published var children: [Character: TrieNode] = [:]
|
||||
@Published var isEndOfWord: Bool = false
|
||||
class TrieNode: Codable {
|
||||
var children: [String: TrieNode] = [:]
|
||||
var isEndOfWord: Bool = false
|
||||
}
|
||||
|
||||
class Trie: ObservableObject {
|
||||
@Published var root: TrieNode = TrieNode()
|
||||
@Published var dict: [String:Emoji] = [:]
|
||||
var root: TrieNode = TrieNode()
|
||||
var dict: [String:Emoji] = [:]
|
||||
|
||||
func insert(word: String) {
|
||||
let word = word.lowercased()
|
||||
@@ -25,7 +25,7 @@ class Trie: ObservableObject {
|
||||
let last = indices.last
|
||||
|
||||
for i in indices {
|
||||
let char = word[i]
|
||||
let char = String(word[i])
|
||||
if let node = currentNode.children[char] {
|
||||
currentNode = node
|
||||
} else {
|
||||
@@ -42,7 +42,7 @@ class Trie: ObservableObject {
|
||||
var currentNode = root
|
||||
|
||||
for char in query.lowercased() {
|
||||
if let node = currentNode.children[char] {
|
||||
if let node = currentNode.children[String(char)] {
|
||||
currentNode = node
|
||||
} else {
|
||||
return false
|
||||
@@ -57,7 +57,7 @@ class Trie: ObservableObject {
|
||||
var currentNode = root
|
||||
|
||||
for char in prefixQuery {
|
||||
guard let child = currentNode.children[char] else {
|
||||
guard let child = currentNode.children[String(char)] else {
|
||||
return []
|
||||
}
|
||||
currentNode = child
|
||||
|
||||
Reference in New Issue
Block a user