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()
}
}