=cdd #18328 use ancestor field, for fast forward merge

AFTER:

[info] Benchmark                                  (set1Size)   Mode  Cnt     Score     Error   Units
[info] ORSetMergeBenchmark.mergeAddFromBothNodes           1  thrpt   10   717.362 ±  15.770  ops/ms
[info] ORSetMergeBenchmark.mergeAddFromBothNodes          10  thrpt   10   144.862 ±   8.313  ops/ms
[info] ORSetMergeBenchmark.mergeAddFromBothNodes          20  thrpt   10    96.004 ±   0.972  ops/ms
[info] ORSetMergeBenchmark.mergeAddFromBothNodes         100  thrpt   10    18.735 ±   0.368  ops/ms
[info] ORSetMergeBenchmark.mergeAddFromOtherNode           1  thrpt   10  1261.825 ±  51.717  ops/ms
[info] ORSetMergeBenchmark.mergeAddFromOtherNode          10  thrpt   10   162.367 ±  21.443  ops/ms
[info] ORSetMergeBenchmark.mergeAddFromOtherNode          20  thrpt   10   103.423 ±   1.569  ops/ms
[info] ORSetMergeBenchmark.mergeAddFromOtherNode         100  thrpt   10    18.690 ±   0.642  ops/ms
[info] ORSetMergeBenchmark.mergeAddFromSameNode            1  thrpt   10  3666.086 ± 330.087  ops/ms
[info] ORSetMergeBenchmark.mergeAddFromSameNode           10  thrpt   10  2404.863 ± 136.244  ops/ms
[info] ORSetMergeBenchmark.mergeAddFromSameNode           20  thrpt   10  2423.596 ± 142.533  ops/ms
[info] ORSetMergeBenchmark.mergeAddFromSameNode          100  thrpt   10  2094.802 ± 161.307  ops/ms
[info] ORSetMergeBenchmark.mergeComplex                    1  thrpt   10   326.784 ±   6.665  ops/ms
[info] ORSetMergeBenchmark.mergeComplex                   10  thrpt   10   133.394 ±   4.749  ops/ms
[info] ORSetMergeBenchmark.mergeComplex                   20  thrpt   10    88.241 ±   1.733  ops/ms
[info] ORSetMergeBenchmark.mergeComplex                  100  thrpt   10    18.117 ±   0.543  ops/ms

BEFORE:

[info] Benchmark                                  (set1Size)   Mode  Cnt     Score    Error   Units
[info] ORSetMergeBenchmark.mergeAddFromBothNodes           1  thrpt   10   737.646 ± 10.289  ops/ms
[info] ORSetMergeBenchmark.mergeAddFromBothNodes          10  thrpt   10   146.706 ±  6.331  ops/ms
[info] ORSetMergeBenchmark.mergeAddFromBothNodes          20  thrpt   10    95.553 ±  1.801  ops/ms
[info] ORSetMergeBenchmark.mergeAddFromBothNodes         100  thrpt   10    18.321 ±  0.586  ops/ms
[info] ORSetMergeBenchmark.mergeAddFromOtherNode           1  thrpt   10  1274.526 ± 23.732  ops/ms
[info] ORSetMergeBenchmark.mergeAddFromOtherNode          10  thrpt   10   162.426 ± 20.490  ops/ms
[info] ORSetMergeBenchmark.mergeAddFromOtherNode          20  thrpt   10   102.436 ±  2.435  ops/ms
[info] ORSetMergeBenchmark.mergeAddFromOtherNode         100  thrpt   10    18.911 ±  0.659  ops/ms
[info] ORSetMergeBenchmark.mergeAddFromSameNode            1  thrpt   10   653.358 ± 71.232  ops/ms
[info] ORSetMergeBenchmark.mergeAddFromSameNode           10  thrpt   10   147.385 ±  2.750  ops/ms
[info] ORSetMergeBenchmark.mergeAddFromSameNode           20  thrpt   10    94.280 ±  0.894  ops/ms
[info] ORSetMergeBenchmark.mergeAddFromSameNode          100  thrpt   10    17.922 ±  1.522  ops/ms
[info] ORSetMergeBenchmark.mergeComplex                    1  thrpt   10   335.060 ±  8.385  ops/ms
[info] ORSetMergeBenchmark.mergeComplex                   10  thrpt   10   134.438 ±  3.044  ops/ms
[info] ORSetMergeBenchmark.mergeComplex                   20  thrpt   10    86.015 ±  2.145  ops/ms
[info] ORSetMergeBenchmark.mergeComplex                  100  thrpt   10    17.611 ±  0.136  ops/ms
This commit is contained in:
Patrik Nordwall 2015-09-20 14:30:00 +02:00
parent 8026e216aa
commit e10593ec31
5 changed files with 95 additions and 28 deletions

View file

@ -154,7 +154,7 @@ object ORSet {
final class ORSet[A] private[akka] (
private[akka] val elementsMap: Map[A, ORSet.Dot],
private[akka] val vvector: VersionVector)
extends ReplicatedData with ReplicatedDataSerialization with RemovedNodePruning {
extends ReplicatedData with ReplicatedDataSerialization with RemovedNodePruning with FastMerge {
type T = ORSet[A]
@ -193,7 +193,7 @@ final class ORSet[A] private[akka] (
private[akka] def add(node: UniqueAddress, element: A): ORSet[A] = {
val newVvector = vvector + node
val newDot = new VersionVector(versions = TreeMap(node -> newVvector.versions(node)))
new ORSet(elementsMap = elementsMap.updated(element, newDot), vvector = newVvector)
assignAncestor(new ORSet(elementsMap = elementsMap.updated(element, newDot), vvector = newVvector))
}
/**
@ -210,7 +210,7 @@ final class ORSet[A] private[akka] (
* INTERNAL API
*/
private[akka] def remove(node: UniqueAddress, element: A): ORSet[A] =
copy(elementsMap = elementsMap - element)
assignAncestor(copy(elementsMap = elementsMap - element))
/**
* Removes all elements from the set, but keeps the history.
@ -222,7 +222,8 @@ final class ORSet[A] private[akka] (
/**
* INTERNAL API
*/
private[akka] def clear(node: UniqueAddress): ORSet[A] = copy(elementsMap = Map.empty)
private[akka] def clear(node: UniqueAddress): ORSet[A] =
assignAncestor(copy(elementsMap = Map.empty))
/**
* When element is in this Set but not in that Set:
@ -238,18 +239,23 @@ final class ORSet[A] private[akka] (
* Keep only common dots, and dots that are not dominated by the other sides version vector
*/
override def merge(that: ORSet[A]): ORSet[A] = {
val thisKeys = elementsMap.keySet
val thatKeys = that.elementsMap.keySet
val commonKeys = thisKeys.intersect(thatKeys)
val thisUniqueKeys = thisKeys -- commonKeys
val thatUniqueKeys = thatKeys -- commonKeys
if ((this eq that) || that.isAncestorOf(this)) this.clearAncestor()
else if (this.isAncestorOf(that)) that.clearAncestor()
else {
val thisKeys = elementsMap.keySet
val thatKeys = that.elementsMap.keySet
val commonKeys = thisKeys.intersect(thatKeys)
val thisUniqueKeys = thisKeys -- commonKeys
val thatUniqueKeys = thatKeys -- commonKeys
val entries00 = ORSet.mergeCommonKeys(commonKeys, this, that)
val entries0 = ORSet.mergeDisjointKeys(thisUniqueKeys, this.elementsMap, that.vvector, entries00)
val entries = ORSet.mergeDisjointKeys(thatUniqueKeys, that.elementsMap, this.vvector, entries0)
val mergedVvector = this.vvector.merge(that.vvector)
val entries00 = ORSet.mergeCommonKeys(commonKeys, this, that)
val entries0 = ORSet.mergeDisjointKeys(thisUniqueKeys, this.elementsMap, that.vvector, entries00)
val entries = ORSet.mergeDisjointKeys(thatUniqueKeys, that.elementsMap, this.vvector, entries0)
val mergedVvector = this.vvector.merge(that.vvector)
new ORSet(entries, mergedVvector)
clearAncestor()
new ORSet(entries, mergedVvector)
}
}
override def needPruningFrom(removedNode: UniqueAddress): Boolean =