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 {
|
class EmojiHoarder: ObservableObject {
|
||||||
static let container = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.neon443.StickerSlack")!.appendingPathComponent("Library", conformingTo: .directory)
|
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 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 endpoint: URL = URL(string: "https://cachet.dunkirk.sh/emojis")!
|
||||||
private let encoder = JSONEncoder()
|
private let encoder = JSONEncoder()
|
||||||
private let decoder = JSONDecoder()
|
private let decoder = JSONDecoder()
|
||||||
@@ -28,10 +30,11 @@ class EmojiHoarder: ObservableObject {
|
|||||||
init(localOnly: Bool = false, skipIndex: Bool = false) {
|
init(localOnly: Bool = false, skipIndex: Bool = false) {
|
||||||
let localDB = loadLocalDB()
|
let localDB = loadLocalDB()
|
||||||
withAnimation { self.emojis = localDB }
|
withAnimation { self.emojis = localDB }
|
||||||
|
loadTrie()
|
||||||
if !skipIndex { buildTrie() }
|
if !skipIndex { buildTrie() }
|
||||||
|
|
||||||
guard !localOnly else { return }
|
guard !localOnly else { return }
|
||||||
Task.detached {
|
Task {
|
||||||
print("start loading remote db")
|
print("start loading remote db")
|
||||||
await self.loadRemoteDB()
|
await self.loadRemoteDB()
|
||||||
print("end")
|
print("end")
|
||||||
@@ -69,22 +72,48 @@ class EmojiHoarder: ObservableObject {
|
|||||||
downloadedEmojis = []
|
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() {
|
func buildTrie() {
|
||||||
let start = Date().timeIntervalSince1970
|
let start = Date().timeIntervalSince1970
|
||||||
trie.root = TrieNode()
|
|
||||||
for emoji in emojis {
|
for emoji in emojis {
|
||||||
trie.insert(word: emoji.name)
|
trie.insert(word: emoji.name)
|
||||||
}
|
}
|
||||||
buildTrieDict()
|
buildTrieDict()
|
||||||
|
saveTrie()
|
||||||
print("done building trie in", Date().timeIntervalSince1970-start)
|
print("done building trie in", Date().timeIntervalSince1970-start)
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildTrieDict() {
|
func buildTrieDict() {
|
||||||
var dict: [String:Emoji] = [:]
|
|
||||||
for emoji in emojis {
|
for emoji in emojis {
|
||||||
dict[emoji.name] = emoji
|
trie.dict[emoji.name] = emoji
|
||||||
}
|
}
|
||||||
self.trie.dict = dict
|
|
||||||
buildDownloadedEmojis()
|
buildDownloadedEmojis()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,14 +9,14 @@ import Foundation
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
import Combine
|
import Combine
|
||||||
|
|
||||||
class TrieNode: ObservableObject {
|
class TrieNode: Codable {
|
||||||
@Published var children: [Character: TrieNode] = [:]
|
var children: [String: TrieNode] = [:]
|
||||||
@Published var isEndOfWord: Bool = false
|
var isEndOfWord: Bool = false
|
||||||
}
|
}
|
||||||
|
|
||||||
class Trie: ObservableObject {
|
class Trie: ObservableObject {
|
||||||
@Published var root: TrieNode = TrieNode()
|
var root: TrieNode = TrieNode()
|
||||||
@Published var dict: [String:Emoji] = [:]
|
var dict: [String:Emoji] = [:]
|
||||||
|
|
||||||
func insert(word: String) {
|
func insert(word: String) {
|
||||||
let word = word.lowercased()
|
let word = word.lowercased()
|
||||||
@@ -25,7 +25,7 @@ class Trie: ObservableObject {
|
|||||||
let last = indices.last
|
let last = indices.last
|
||||||
|
|
||||||
for i in indices {
|
for i in indices {
|
||||||
let char = word[i]
|
let char = String(word[i])
|
||||||
if let node = currentNode.children[char] {
|
if let node = currentNode.children[char] {
|
||||||
currentNode = node
|
currentNode = node
|
||||||
} else {
|
} else {
|
||||||
@@ -42,7 +42,7 @@ class Trie: ObservableObject {
|
|||||||
var currentNode = root
|
var currentNode = root
|
||||||
|
|
||||||
for char in query.lowercased() {
|
for char in query.lowercased() {
|
||||||
if let node = currentNode.children[char] {
|
if let node = currentNode.children[String(char)] {
|
||||||
currentNode = node
|
currentNode = node
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
@@ -57,7 +57,7 @@ class Trie: ObservableObject {
|
|||||||
var currentNode = root
|
var currentNode = root
|
||||||
|
|
||||||
for char in prefixQuery {
|
for char in prefixQuery {
|
||||||
guard let child = currentNode.children[char] else {
|
guard let child = currentNode.children[String(char)] else {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
currentNode = child
|
currentNode = child
|
||||||
|
|||||||
Reference in New Issue
Block a user