=ddata Garbage collect valueDeltas tombstones at merge/mergeDelta #22974
This commit is contained in:
parent
c8748e8cf0
commit
cb6e9b1e49
4 changed files with 43 additions and 30 deletions
|
|
@ -331,9 +331,13 @@ final class ORMap[A, B <: ReplicatedData] private[akka] (
|
|||
val mergedValue = thisValue.merge(thatValue.asInstanceOf[thisValue.T]).asInstanceOf[B]
|
||||
mergedValues = mergedValues.updated(key, mergedValue)
|
||||
case (Some(thisValue), None) ⇒
|
||||
mergedValues = mergedValues.updated(key, thisValue)
|
||||
if (mergedKeys.contains(key))
|
||||
mergedValues = mergedValues.updated(key, thisValue)
|
||||
// else thisValue is a tombstone, but we don't want to carry it forward, as the other side does not have the element at all
|
||||
case (None, Some(thatValue)) ⇒
|
||||
mergedValues = mergedValues.updated(key, thatValue)
|
||||
if (mergedKeys.contains(key))
|
||||
mergedValues = mergedValues.updated(key, thatValue)
|
||||
// else thatValue is a tombstone, but we don't want to carry it forward, as the other side does not have the element at all
|
||||
case (None, None) ⇒ throw new IllegalStateException(s"missing value for $key")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@
|
|||
*/
|
||||
package akka.cluster.ddata
|
||||
|
||||
import akka.cluster.{ Cluster, UniqueAddress }
|
||||
import akka.annotation.InternalApi
|
||||
import akka.cluster.ddata.ORMap._
|
||||
import akka.cluster.{ Cluster, UniqueAddress }
|
||||
|
||||
object ORMultiMap {
|
||||
/**
|
||||
|
|
@ -69,9 +69,12 @@ final class ORMultiMap[A, B] private[akka] (
|
|||
|
||||
override def merge(that: T): T =
|
||||
if (withValueDeltas == that.withValueDeltas) {
|
||||
if (withValueDeltas)
|
||||
new ORMultiMap(underlying.mergeRetainingDeletedValues(that.underlying), withValueDeltas)
|
||||
else
|
||||
if (withValueDeltas) {
|
||||
val newUnderlying = underlying.mergeRetainingDeletedValues(that.underlying)
|
||||
// Garbage collect the tombstones we no longer need, i.e. those that have Set() as a value.
|
||||
val newValues = newUnderlying.values.filterNot { case (key, value) ⇒ !newUnderlying.keys.contains(key) && value.isEmpty }
|
||||
new ORMultiMap[A, B](new ORMap(newUnderlying.keys, newValues, newUnderlying.zeroTag, newUnderlying.delta), withValueDeltas)
|
||||
} else
|
||||
new ORMultiMap(underlying.merge(that.underlying), withValueDeltas)
|
||||
} else throw new IllegalArgumentException("Trying to merge two ORMultiMaps of different map sub-type")
|
||||
|
||||
|
|
@ -253,9 +256,12 @@ final class ORMultiMap[A, B] private[akka] (
|
|||
override def delta: Option[D] = underlying.delta
|
||||
|
||||
override def mergeDelta(thatDelta: D): ORMultiMap[A, B] =
|
||||
if (withValueDeltas)
|
||||
new ORMultiMap(underlying.mergeDeltaRetainingDeletedValues(thatDelta), withValueDeltas)
|
||||
else
|
||||
if (withValueDeltas) {
|
||||
val newUnderlying = underlying.mergeDeltaRetainingDeletedValues(thatDelta)
|
||||
// Garbage collect the tombstones we no longer need, i.e. those that have Set() as a value.
|
||||
val newValues = newUnderlying.values.filterNot { case (key, value) ⇒ !newUnderlying.keys.contains(key) && value.isEmpty }
|
||||
new ORMultiMap[A, B](new ORMap(newUnderlying.keys, newValues, newUnderlying.zeroTag, newUnderlying.delta), withValueDeltas)
|
||||
} else
|
||||
new ORMultiMap(underlying.mergeDelta(thatDelta), withValueDeltas)
|
||||
|
||||
override def modifiedByNodes: Set[UniqueAddress] =
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue