pekko/akka-docs/rst/scala/code/docs/ddata/protobuf/TwoPhaseSetSerializer.scala
Patrik Nordwall cbe5dd2cf5 +cdd #16799 Add Distributed Data module
Previously know as [patriknw/akka-data-replication](https://github.com/patriknw/akka-data-replication),
which was originally inspired by [jboner/akka-crdt](https://github.com/jboner/akka-crdt).

The functionality is very similar to akka-data-replication 0.11.

Here is a list of the most important changes:

* The package name changed to `akka.cluster.ddata`
* The extension was renamed to `DistributedData`
* The keys changed from strings to classes with unique identifiers and type information of the data values,
  e.g. `ORSetKey[Int]("set2")`
* The optional read consistency parameter was removed from the `Update` message. If you need to read from
  other replicas before performing the update you have to first send a `Get` message and then continue with
  the ``Update`` when the ``GetSuccess`` is received.
* `BigInt` is used in `GCounter` and `PNCounter` instead of `Long`
* Improvements of java api
* Better documentation
2015-06-18 15:58:22 +02:00

75 lines
2.4 KiB
Scala

/**
* Copyright (C) 2015 Typesafe Inc. <http://www.typesafe.com>
*/
package docs.ddata.protobuf
//#serializer
import java.util.ArrayList
import java.util.Collections
import scala.collection.JavaConverters._
import akka.actor.ExtendedActorSystem
import akka.cluster.ddata.GSet
import akka.cluster.ddata.protobuf.SerializationSupport
import akka.serialization.Serializer
import docs.ddata.TwoPhaseSet
import docs.ddata.protobuf.msg.TwoPhaseSetMessages
class TwoPhaseSetSerializer(val system: ExtendedActorSystem)
extends Serializer with SerializationSupport {
override def includeManifest: Boolean = false
override def identifier = 99999
override def toBinary(obj: AnyRef): Array[Byte] = obj match {
case m: TwoPhaseSet twoPhaseSetToProto(m).toByteArray
case _ throw new IllegalArgumentException(
s"Can't serialize object of type ${obj.getClass}")
}
override def fromBinary(bytes: Array[Byte], clazz: Option[Class[_]]): AnyRef = {
twoPhaseSetFromBinary(bytes)
}
def twoPhaseSetToProto(twoPhaseSet: TwoPhaseSet): TwoPhaseSetMessages.TwoPhaseSet = {
val b = TwoPhaseSetMessages.TwoPhaseSet.newBuilder()
// using java collections and sorting for performance (avoid conversions)
val adds = new ArrayList[String]
twoPhaseSet.adds.elements.foreach(adds.add)
if (!adds.isEmpty) {
Collections.sort(adds)
b.addAllAdds(adds)
}
val removals = new ArrayList[String]
twoPhaseSet.removals.elements.foreach(removals.add)
if (!removals.isEmpty) {
Collections.sort(removals)
b.addAllRemovals(removals)
}
b.build()
}
def twoPhaseSetFromBinary(bytes: Array[Byte]): TwoPhaseSet = {
val msg = TwoPhaseSetMessages.TwoPhaseSet.parseFrom(bytes)
TwoPhaseSet(
adds = GSet(msg.getAddsList.iterator.asScala.toSet),
removals = GSet(msg.getRemovalsList.iterator.asScala.toSet))
}
}
//#serializer
class TwoPhaseSetSerializerWithCompression(system: ExtendedActorSystem)
extends TwoPhaseSetSerializer(system) {
//#compression
override def toBinary(obj: AnyRef): Array[Byte] = obj match {
case m: TwoPhaseSet compress(twoPhaseSetToProto(m))
case _ throw new IllegalArgumentException(
s"Can't serialize object of type ${obj.getClass}")
}
override def fromBinary(bytes: Array[Byte], clazz: Option[Class[_]]): AnyRef = {
twoPhaseSetFromBinary(decompress(bytes))
}
//#compression
}