Skip to content

Commit c4e3aea

Browse files
Make "is map entry tombstoned" check referenced object per RTLM14c
1 parent 3df9ebb commit c4e3aea

3 files changed

Lines changed: 23 additions & 11 deletions

File tree

Sources/AblyLiveObjects/Internal/InternalDefaultLiveMap.swift

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ internal final class InternalDefaultLiveMap: Sendable {
138138
return convertEntryToLiveMapValue(entry, delegate: delegate)
139139
}
140140

141-
internal func size(coreSDK: CoreSDK) throws(ARTErrorInfo) -> Int {
141+
internal func size(coreSDK: CoreSDK, delegate: LiveMapObjectPoolDelegate) throws(ARTErrorInfo) -> Int {
142142
// RTLM10c: If the channel is in the DETACHED or FAILED state, the library should throw an ErrorInfo error with statusCode 400 and code 90001
143143
let currentChannelState = coreSDK.channelState
144144
if currentChannelState == .detached || currentChannelState == .failed {
@@ -152,7 +152,7 @@ internal final class InternalDefaultLiveMap: Sendable {
152152
return mutex.withLock {
153153
// RTLM10d: Returns the number of non-tombstoned entries (per RTLM14) in the internal data map
154154
mutableState.data.values.count { entry in
155-
!Self.isEntryTombstoned(entry)
155+
!Self.isEntryTombstoned(entry, delegate: delegate)
156156
}
157157
}
158158
}
@@ -173,7 +173,7 @@ internal final class InternalDefaultLiveMap: Sendable {
173173
// RTLM11d1: Pairs with tombstoned entries (per RTLM14) are not returned
174174
var result: [(key: String, value: InternalLiveMapValue)] = []
175175

176-
for (key, entry) in mutableState.data where !Self.isEntryTombstoned(entry) {
176+
for (key, entry) in mutableState.data where !Self.isEntryTombstoned(entry, delegate: delegate) {
177177
// Convert entry to LiveMapValue using the same logic as get(key:)
178178
if let value = convertEntryToLiveMapValue(entry, delegate: delegate) {
179179
result.append((key: key, value: value))
@@ -779,9 +779,21 @@ internal final class InternalDefaultLiveMap: Sendable {
779779
// MARK: - Helper Methods
780780

781781
/// Returns whether a map entry should be considered tombstoned, per the check described in RTLM14.
782-
private static func isEntryTombstoned(_ entry: InternalObjectsMapEntry) -> Bool {
783-
// RTLM14a, RTLM14b
784-
entry.tombstone == true
782+
private static func isEntryTombstoned(_ entry: InternalObjectsMapEntry, delegate: LiveMapObjectPoolDelegate) -> Bool {
783+
// RTLM14a
784+
if entry.tombstone {
785+
return true
786+
}
787+
788+
// RTLM14c
789+
if let objectId = entry.data.objectId {
790+
if let poolEntry = delegate.getObjectFromPool(id: objectId), poolEntry.isTombstone {
791+
return false
792+
}
793+
}
794+
795+
// RTLM14b
796+
return false
785797
}
786798

787799
/// Converts an InternalObjectsMapEntry to LiveMapValue using the same logic as get(key:)

Sources/AblyLiveObjects/Public/Public Proxy Objects/PublicDefaultLiveMap.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ internal final class PublicDefaultLiveMap: LiveMap {
3434

3535
internal var size: Int {
3636
get throws(ARTErrorInfo) {
37-
try proxied.size(coreSDK: coreSDK)
37+
try proxied.size(coreSDK: coreSDK, delegate: delegate)
3838
}
3939
}
4040

Tests/AblyLiveObjectsTests/InternalDefaultLiveMapTests.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ struct InternalDefaultLiveMapTests {
284284

285285
// Define actions to test
286286
let actions: [(String, () throws -> Any)] = [
287-
("size", { try map.size(coreSDK: coreSDK) }),
287+
("size", { try map.size(coreSDK: coreSDK, delegate: delegate) }),
288288
("entries", { try map.entries(coreSDK: coreSDK, delegate: delegate) }),
289289
("keys", { try map.keys(coreSDK: coreSDK, delegate: delegate) }),
290290
("values", { try map.values(coreSDK: coreSDK, delegate: delegate) }),
@@ -330,7 +330,7 @@ struct InternalDefaultLiveMapTests {
330330
)
331331

332332
// Test size - should only count non-tombstoned entries
333-
let size = try map.size(coreSDK: coreSDK)
333+
let size = try map.size(coreSDK: coreSDK, delegate: delegate)
334334
#expect(size == 1)
335335

336336
// Test entries - should only return non-tombstoned entries
@@ -372,7 +372,7 @@ struct InternalDefaultLiveMapTests {
372372
clock: MockSimpleClock(),
373373
)
374374

375-
let size = try map.size(coreSDK: coreSDK)
375+
let size = try map.size(coreSDK: coreSDK, delegate: delegate)
376376
let entries = try map.entries(coreSDK: coreSDK, delegate: delegate)
377377
let keys = try map.keys(coreSDK: coreSDK, delegate: delegate)
378378
let values = try map.values(coreSDK: coreSDK, delegate: delegate)
@@ -422,7 +422,7 @@ struct InternalDefaultLiveMapTests {
422422
clock: MockSimpleClock(),
423423
)
424424

425-
let size = try map.size(coreSDK: coreSDK)
425+
let size = try map.size(coreSDK: coreSDK, delegate: delegate)
426426
let entries = try map.entries(coreSDK: coreSDK, delegate: delegate)
427427
let keys = try map.keys(coreSDK: coreSDK, delegate: delegate)
428428
let values = try map.values(coreSDK: coreSDK, delegate: delegate)

0 commit comments

Comments
 (0)