From e999e81e8fef2f0840e1edde8f95ab95619f3332 Mon Sep 17 00:00:00 2001 From: William Casarin Date: Thu, 25 Jan 2024 11:49:17 -0800 Subject: [PATCH] mute: implement fast MuteItem decoder Just using strings is really bad performance wise, and is not the proper way to implement a TagConvertible. The whole point of this protocol is to parse tags efficiently. --- damus/Models/MuteItem.swift | 50 ++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/damus/Models/MuteItem.swift b/damus/Models/MuteItem.swift index 136f7ff1..69bbe2c0 100644 --- a/damus/Models/MuteItem.swift +++ b/damus/Models/MuteItem.swift @@ -147,8 +147,56 @@ enum MuteItem: Hashable, Equatable { // - MARK: TagConvertible extension MuteItem: TagConvertible { + enum MuteKeys: String { + case p, t, word, e + + init?(tag: NdbTagElem) { + let len = tag.count + if len == 1 { + switch tag.single_char { + case "p": self = .p + case "t": self = .t + case "e": self = .e + default: return nil + } + } else if len == 4 && tag.matches_str("word", tag_len: 4) { + self = .word + } else { + return nil + } + } + + var description: String { self.rawValue } + } + static func from_tag(tag: TagSequence) -> MuteItem? { - return MuteItem(tag.strings()) + guard tag.count >= 2 else { return nil } + + var i = tag.makeIterator() + + guard let t0 = i.next(), + let mkey = MuteKeys(tag: t0), + let t1 = i.next() + else { + return nil + } + + var expiry: Date? = nil + if let expiry_str = i.next(), let ts = expiry_str.u64() { + expiry = Date(timeIntervalSince1970: Double(ts)) + } + + switch mkey { + case .p: + return t1.id().map({ .user(Pubkey($0), expiry) }) + case .t: + return .hashtag(Hashtag(hashtag: t1.string()), expiry) + case .word: + return .word(t1.string(), expiry) + case .e: + guard let id = t1.id() else { return nil } + return .thread(NoteId(id), expiry) + } } }