11package io.ably.lib.objects.type
22
3- import io.ably.lib.objects.LiveObjectsAdapter
3+ import io.ably.lib.objects.*
44import io.ably.lib.objects.ObjectMessage
55import io.ably.lib.objects.ObjectOperation
66import io.ably.lib.objects.ObjectState
7- import io.ably.lib.objects.ObjectsPool
7+ import io.ably.lib.objects.ObjectsPoolDefaults
88import io.ably.lib.objects.objectError
99import io.ably.lib.util.Log
1010
@@ -15,20 +15,18 @@ import io.ably.lib.util.Log
1515 * @spec RTLO1/RTLO2 - Base class for LiveMap/LiveCounter objects
1616 */
1717internal abstract class BaseLiveObject (
18- protected val objectId : String , // // RTLO3a
18+ internal val objectId : String , // // RTLO3a
1919 protected val adapter : LiveObjectsAdapter
2020) {
2121
2222 protected open val tag = " BaseLiveObject"
23- internal var isTombstoned = false
24- internal var tombstonedAt: Long? = null
2523
26- protected val siteTimeserials = mutableMapOf<String , String >() // RTLO3b
24+ internal val siteTimeserials = mutableMapOf<String , String >() // RTLO3b
2725
28- /* *
29- * @spec RTLO3 - Flag to track if create operation has been merged for LiveMap/LiveCounter
30- */
31- protected var createOperationIsMerged = false // RTLO3c
26+ internal var createOperationIsMerged = false // RTLO3c
27+
28+ internal var isTombstoned = false
29+ internal var tombstonedAt : Long? = null
3230
3331 fun notifyUpdated (update : Any ) {
3432 // TODO: Implement event emission for updates
@@ -40,7 +38,7 @@ internal abstract class BaseLiveObject(
4038 *
4139 * @spec RTLO4a - Serial comparison logic for LiveMap/LiveCounter operations
4240 */
43- protected fun canApplyOperation (siteCode : String? , serial : String? ): Boolean {
41+ internal fun canApplyOperation (siteCode : String? , serial : String? ): Boolean {
4442 if (serial.isNullOrEmpty()) {
4543 throw objectError(" Invalid serial: $serial " ) // RTLO4a3
4644 }
@@ -51,41 +49,31 @@ internal abstract class BaseLiveObject(
5149 return existingSiteSerial == null || serial > existingSiteSerial // RTLO4a5, RTLO4a6
5250 }
5351
54- /* *
55- * Updates the time serial for a given site code.
56- */
57- protected fun updateTimeSerial (opSiteCode : String , opSerial : String ) {
58- siteTimeserials[opSiteCode] = opSerial
59- }
60-
61- /* *
62- * Applies object delete operation.
63- *
64- * @spec RTLM10/RTLC10 - Object deletion for LiveMap/LiveCounter
65- */
66- protected fun applyObjectDelete (): Any {
67- return tombstone()
68- }
69-
7052 /* *
7153 * Marks the object as tombstoned.
72- *
73- * @spec RTLM11/RTLC11 - Tombstone functionality for LiveMap/LiveCounter
7454 */
75- protected fun tombstone (): Any {
55+ internal fun tombstone (): Any {
7656 isTombstoned = true
7757 tombstonedAt = System .currentTimeMillis()
7858 val update = clearData()
7959 // TODO: Emit lifecycle events
8060 return update
8161 }
8262
63+ /* *
64+ * Checks if the object is eligible for garbage collection.
65+ */
66+ internal fun isEligibleForGc (): Boolean {
67+ val currentTime = System .currentTimeMillis()
68+ return isTombstoned && tombstonedAt?.let { currentTime - it >= ObjectsPoolDefaults .GC_GRACE_PERIOD_MS } == true
69+ }
70+
8371 /* *
8472 * This is invoked by ObjectMessage having updated data with parent `ProtocolMessageAction` as `object_sync`
8573 * @return an update describing the changes
8674 * @spec RTLM6/RTLC6 - Overrides ObjectMessage with object data state from sync to LiveMap/LiveCounter
8775 */
88- abstract fun overrideWithObjectState (objectState : ObjectState ): Map <String , Any >
76+ abstract fun applyObjectState (objectState : ObjectState ): Map <String , Any >
8977
9078 /* *
9179 * This is invoked by ObjectMessage having updated data with parent `ProtocolMessageAction` as `object`
@@ -96,11 +84,28 @@ internal abstract class BaseLiveObject(
9684
9785 /* *
9886 * Clears the object's data and returns an update describing the changes.
87+ * This is called during tombstoning and explicit clear operations.
88+ *
89+ * This method:
90+ * 1. Calculates a diff between the current state and an empty state
91+ * 2. Clears all entries from the underlying data structure
92+ * 3. Returns a map containing metadata about what was cleared
93+ *
94+ * The returned map is used to notifying other components about what entries were removed.
95+ *
96+ * @return A map representing the diff of changes made
9997 */
10098 abstract fun clearData (): Map <String , Any >
10199
102100 /* *
103- * Called during garbage collection intervals.
101+ * Called during garbage collection intervals to clean up expired entries.
102+ *
103+ * This method should identify and remove entries that:
104+ * - Have been marked as tombstoned
105+ * - Have a tombstone timestamp older than the configured grace period
106+ *
107+ * Implementations typically use single-pass removal techniques to
108+ * efficiently clean up expired data without creating temporary collections.
104109 */
105110 abstract fun onGCInterval ()
106111}
0 commit comments