Home telegram - peerNameIndexTable
Post
Cancel

telegram - peerNameIndexTable

PeerNameIndexTable

struct PeerNameIndexCategories:OptionSet

1
2
3
4
var rawValue: Int32

static let chats = PeerNameIndexCategories(rawValue: 1 << 0)
static let contacts = PeerNameIndexCategories(rawValue: 1 << 1)

class PeerNameIndexCategoriesEntry

1
2
let categories: PeerNameIndexCategories
let tokens: [ValueBoxKey]

class PeerNameIndexCategoriesEntryUpdate

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
let initialCategories: PeerNameIndexCategories
let initialTokens: [ValueBoxKey]

private(set) var updatedCategories: PeerNameIndexCategories?
private(set) var updatedName: PeerIndexNameRepresentation?

func updateCategory(_ category: PeerNameIndexCategories, includes: Bool) {
    var currentCategories: PeerNameIndexCategories
    if let updatedCategories = self.updatedCategories {
        currentCategories = updatedCategories
    } else {
        currentCategories = self.initialCategories
    }
    if includes {
        currentCategories.insert(category)
        self.updatedCategories = currentCategories
    } else {
        currentCategories.remove(category)
        self.updatedCategories = currentCategories
    }
}
func updateName(_ name: PeerIndexNameRepresentation) {
    self.updatedName = name
}

class PeerNameIndexTable

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
static func tableSpec(_ id: Int32) -> ValueBoxTable {
    return ValueBoxTable(id: id, keyType: .int64, compactValuesOnCreation: false)
}

private let peerTable: PeerTable
private let peerNameTokenIndexTable: ReverseIndexReferenceTable<PeerIdReverseIndexReference>

private func key(_ peerId: PeerId) -> ValueBoxKey {
    self.sharedKey.setInt64(0, value: peerId.toInt64())
    return self.sharedKey
}

private var entryUpdates: [PeerId: PeerNameIndexCategoriesEntryUpdate] = [:]

// update
private func updateEntry(_ peerId: PeerId, _ f: (PeerNameIndexCategoriesEntryUpdate) -> Void) {
    let entryUpdate: PeerNameIndexCategoriesEntryUpdate
    if let current = self.entryUpdates[peerId] {
        entryUpdate = current
    } else {
        let entry: PeerNameIndexCategoriesEntry
        if let value = self.valueBox.get(self.table, key: self.key(peerId)) {
            entry = PeerNameIndexCategoriesEntry(buffer: value)
        } else {
            entry = PeerNameIndexCategoriesEntry(categories: [], tokens: [])
        }
        entryUpdate = PeerNameIndexCategoriesEntryUpdate(initialCategories: entry.categories, initialTokens: entry.tokens)
        self.entryUpdates[peerId] = entryUpdate
    }
    f(entryUpdate)
}

// before commit
override func beforeCommit() {
    if !self.entryUpdates.isEmpty {
        let sharedBuffer = WriteBuffer()
        for (peerId, entryUpdate) in self.entryUpdates {
            if let updatedCategories = entryUpdate.updatedCategories {
                let wasEmpty = entryUpdate.initialCategories.isEmpty
                if updatedCategories.isEmpty != wasEmpty {
                    if updatedCategories.isEmpty {
                        if !entryUpdate.initialTokens.isEmpty {
                            self.peerNameTokenIndexTable.remove(namespace: reverseIndexNamespace, reference: PeerIdReverseIndexReference(value: peerId.toInt64()), tokens: entryUpdate.initialTokens)
                        }
                        if !entryUpdate.initialCategories.isEmpty {
                            self.valueBox.remove(self.table, key: self.key(peerId), secure: false)
                        }
                    } else {
                        let updatedTokens: [ValueBoxKey]
                        if let updatedName = entryUpdate.updatedName {
                            updatedTokens = updatedName.indexTokens
                        } else {
                            if let peer = self.peerTable.get(peerId) {
                                if let associatedPeerId = peer.associatedPeerId {
                                    if let associatedPeer = self.peerTable.get(associatedPeerId) {
                                        updatedTokens = associatedPeer.indexName.indexTokens
                                    } else {
                                        updatedTokens = []
                                    }
                                } else {
                                    updatedTokens = peer.indexName.indexTokens
                                }
                            } else {
                                //assertionFailure()
                                updatedTokens = []
                            }
                        }
                        self.peerNameTokenIndexTable.add(namespace: reverseIndexNamespace, reference: PeerIdReverseIndexReference(value: peerId.toInt64()), tokens: updatedTokens)
                        sharedBuffer.reset()
                        PeerNameIndexCategoriesEntry(categories: updatedCategories, tokens: updatedTokens).write(to: sharedBuffer)
                        self.valueBox.set(self.table, key: self.key(peerId), value: sharedBuffer)
                    }
                } else {
                    if let updatedName = entryUpdate.updatedName {
                        if !entryUpdate.initialTokens.isEmpty {
                            self.peerNameTokenIndexTable.remove(namespace: reverseIndexNamespace, reference: PeerIdReverseIndexReference(value: peerId.toInt64()), tokens: entryUpdate.initialTokens)
                        }
                        let updatedTokens = updatedName.indexTokens
                        self.peerNameTokenIndexTable.add(namespace: reverseIndexNamespace, reference: PeerIdReverseIndexReference(value: peerId.toInt64()), tokens: updatedTokens)
                        sharedBuffer.reset()
                        PeerNameIndexCategoriesEntry(categories: updatedCategories, tokens: updatedTokens).write(to: sharedBuffer)
                        self.valueBox.set(self.table, key: self.key(peerId), value: sharedBuffer)
                    } else {
                        sharedBuffer.reset()
                        PeerNameIndexCategoriesEntry(categories: updatedCategories, tokens: entryUpdate.initialTokens).write(to: sharedBuffer)
                        self.valueBox.set(self.table, key: self.key(peerId), value: sharedBuffer)
                    }
                }
            } else if let updatedName = entryUpdate.updatedName {
                if !entryUpdate.initialCategories.isEmpty {
                    if !entryUpdate.initialTokens.isEmpty {
                        self.peerNameTokenIndexTable.remove(namespace: reverseIndexNamespace, reference: PeerIdReverseIndexReference(value: peerId.toInt64()), tokens: entryUpdate.initialTokens)
                    }
                    let updatedTokens = updatedName.indexTokens
                    self.peerNameTokenIndexTable.add(namespace: reverseIndexNamespace, reference: PeerIdReverseIndexReference(value: peerId.toInt64()), tokens: updatedTokens)
                    sharedBuffer.reset()
                    PeerNameIndexCategoriesEntry(categories: entryUpdate.initialCategories, tokens: updatedTokens).write(to: sharedBuffer)
                    self.valueBox.set(self.table, key: self.key(peerId), value: sharedBuffer)
                }
            }
        }
        self.entryUpdates.removeAll()
    }
}
This post is licensed under CC BY 4.0 by the author.