ReverseAssociatedPeerTable
class
ReverseAssociatedPeerTable
1
2
3
4
5
6
7
8
9
10
11
private func readPeerIds(_ buffer: ReadBuffer) -> Set<PeerId> {
assert(buffer.length % 8 == 0)
let count = buffer.length / 8
var result = Set<PeerId>()
for _ in 0 ..< count {
var value: Int64 = 0
buffer.read(&value, offset: 0, length: 8)
result.insert(PeerId(value))
}
return result
}
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
static func tableSpec(_ id: Int32) -> ValueBoxTable {
return ValueBoxTable(id: id, keyType: .int64, compactValuesOnCreation: false)
}
private var cachedAssociations: [PeerId: Set<PeerId>] = [:]
private var updatedAssociations = Set<PeerId>()
private func key(_ peerId: PeerId) -> ValueBoxKey {
self.sharedKey.setInt64(0, value: peerId.toInt64())
return self.sharedKey
}
// get peerId
func get(peerId: PeerId) -> Set<PeerId> {
if let cached = self.cachedAssociations[peerId] {// from memory cache
return cached
} else {
// from db
if let value = self.valueBox.get(self.table, key: self.key(peerId)) {
let peerIds = readPeerIds(value)
self.cachedAssociations[peerId] = peerIds
return peerIds
} else {
self.cachedAssociations[peerId] = Set()
return Set()
}
}
}
// add reverse association
func addReverseAssociation(target targetPeerId: PeerId, from sourcePeerId: PeerId) {
var value = self.get(peerId: targetPeerId)
if value.contains(sourcePeerId) {
assertionFailure()
} else {
value.insert(sourcePeerId)
self.cachedAssociations[targetPeerId] = value
self.updatedAssociations.insert(targetPeerId)
}
}
// remove reverse association
func removeReverseAssociation(target targetPeerId: PeerId, from sourcePeerId: PeerId) {
var value = self.get(peerId: targetPeerId)
if !value.contains(sourcePeerId) {
assertionFailure()
} else {
value.remove(sourcePeerId)
self.cachedAssociations[targetPeerId] = value
self.updatedAssociations.insert(targetPeerId)
}
}
// clear memory cache
override func clearMemoryCache() {
self.cachedAssociations.removeAll()
assert(self.updatedAssociations.isEmpty)
}
// before commit
override func beforeCommit() {
if !self.updatedAssociations.isEmpty {
let buffer = WriteBuffer()
for peerId in self.updatedAssociations {
if let peerIds = self.cachedAssociations[peerId] {
if peerIds.isEmpty {
self.valueBox.remove(self.table, key: self.key(peerId), secure: false)
} else {
buffer.reset()
writePeerIds(buffer, peerIds)
self.valueBox.set(self.table, key: self.key(peerId), value: buffer)
}
} else {
assertionFailure()
}
}
self.updatedAssociations.removeAll()
}
}