diff --git a/akka-distributed-data/src/main/java/akka/cluster/ddata/protobuf/msg/ReplicatedDataMessages.java b/akka-distributed-data/src/main/java/akka/cluster/ddata/protobuf/msg/ReplicatedDataMessages.java
index 306256493a..1f25776e93 100644
--- a/akka-distributed-data/src/main/java/akka/cluster/ddata/protobuf/msg/ReplicatedDataMessages.java
+++ b/akka-distributed-data/src/main/java/akka/cluster/ddata/protobuf/msg/ReplicatedDataMessages.java
@@ -99,6 +99,106 @@ public final class ReplicatedDataMessages {
// @@protoc_insertion_point(enum_scope:akka.cluster.ddata.ORSetDeltaOp)
}
+ /**
+ * Protobuf enum {@code akka.cluster.ddata.ORMapDeltaOp}
+ */
+ public enum ORMapDeltaOp
+ implements akka.protobuf.ProtocolMessageEnum {
+ /**
+ * ORMapPut = 0;
+ */
+ ORMapPut(0, 0),
+ /**
+ * ORMapRemove = 1;
+ */
+ ORMapRemove(1, 1),
+ /**
+ * ORMapRemoveKey = 2;
+ */
+ ORMapRemoveKey(2, 2),
+ /**
+ * ORMapUpdate = 3;
+ */
+ ORMapUpdate(3, 3),
+ ;
+
+ /**
+ * ORMapPut = 0;
+ */
+ public static final int ORMapPut_VALUE = 0;
+ /**
+ * ORMapRemove = 1;
+ */
+ public static final int ORMapRemove_VALUE = 1;
+ /**
+ * ORMapRemoveKey = 2;
+ */
+ public static final int ORMapRemoveKey_VALUE = 2;
+ /**
+ * ORMapUpdate = 3;
+ */
+ public static final int ORMapUpdate_VALUE = 3;
+
+
+ public final int getNumber() { return value; }
+
+ public static ORMapDeltaOp valueOf(int value) {
+ switch (value) {
+ case 0: return ORMapPut;
+ case 1: return ORMapRemove;
+ case 2: return ORMapRemoveKey;
+ case 3: return ORMapUpdate;
+ default: return null;
+ }
+ }
+
+ public static akka.protobuf.Internal.EnumLiteMap
+ internalGetValueMap() {
+ return internalValueMap;
+ }
+ private static akka.protobuf.Internal.EnumLiteMap
+ internalValueMap =
+ new akka.protobuf.Internal.EnumLiteMap() {
+ public ORMapDeltaOp findValueByNumber(int number) {
+ return ORMapDeltaOp.valueOf(number);
+ }
+ };
+
+ public final akka.protobuf.Descriptors.EnumValueDescriptor
+ getValueDescriptor() {
+ return getDescriptor().getValues().get(index);
+ }
+ public final akka.protobuf.Descriptors.EnumDescriptor
+ getDescriptorForType() {
+ return getDescriptor();
+ }
+ public static final akka.protobuf.Descriptors.EnumDescriptor
+ getDescriptor() {
+ return akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.getDescriptor().getEnumTypes().get(1);
+ }
+
+ private static final ORMapDeltaOp[] VALUES = values();
+
+ public static ORMapDeltaOp valueOf(
+ akka.protobuf.Descriptors.EnumValueDescriptor desc) {
+ if (desc.getType() != getDescriptor()) {
+ throw new java.lang.IllegalArgumentException(
+ "EnumValueDescriptor is not for this type.");
+ }
+ return VALUES[desc.getIndex()];
+ }
+
+ private final int index;
+ private final int value;
+
+ private ORMapDeltaOp(int index, int value) {
+ this.index = index;
+ this.value = value;
+ }
+
+ // @@protoc_insertion_point(enum_scope:akka.cluster.ddata.ORMapDeltaOp)
+ }
+
public interface GSetOrBuilder
extends akka.protobuf.MessageOrBuilder {
@@ -9599,6 +9699,2651 @@ public final class ReplicatedDataMessages {
// @@protoc_insertion_point(class_scope:akka.cluster.ddata.ORMap)
}
+ public interface ORMapDeltaGroupOrBuilder
+ extends akka.protobuf.MessageOrBuilder {
+
+ // repeated .akka.cluster.ddata.ORMapDeltaGroup.Entry entries = 1;
+ /**
+ * repeated .akka.cluster.ddata.ORMapDeltaGroup.Entry entries = 1;
+ */
+ java.util.List
+ getEntriesList();
+ /**
+ * repeated .akka.cluster.ddata.ORMapDeltaGroup.Entry entries = 1;
+ */
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry getEntries(int index);
+ /**
+ * repeated .akka.cluster.ddata.ORMapDeltaGroup.Entry entries = 1;
+ */
+ int getEntriesCount();
+ /**
+ * repeated .akka.cluster.ddata.ORMapDeltaGroup.Entry entries = 1;
+ */
+ java.util.List extends akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.EntryOrBuilder>
+ getEntriesOrBuilderList();
+ /**
+ * repeated .akka.cluster.ddata.ORMapDeltaGroup.Entry entries = 1;
+ */
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.EntryOrBuilder getEntriesOrBuilder(
+ int index);
+ }
+ /**
+ * Protobuf type {@code akka.cluster.ddata.ORMapDeltaGroup}
+ */
+ public static final class ORMapDeltaGroup extends
+ akka.protobuf.GeneratedMessage
+ implements ORMapDeltaGroupOrBuilder {
+ // Use ORMapDeltaGroup.newBuilder() to construct.
+ private ORMapDeltaGroup(akka.protobuf.GeneratedMessage.Builder> builder) {
+ super(builder);
+ this.unknownFields = builder.getUnknownFields();
+ }
+ private ORMapDeltaGroup(boolean noInit) { this.unknownFields = akka.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+ private static final ORMapDeltaGroup defaultInstance;
+ public static ORMapDeltaGroup getDefaultInstance() {
+ return defaultInstance;
+ }
+
+ public ORMapDeltaGroup getDefaultInstanceForType() {
+ return defaultInstance;
+ }
+
+ private final akka.protobuf.UnknownFieldSet unknownFields;
+ @java.lang.Override
+ public final akka.protobuf.UnknownFieldSet
+ getUnknownFields() {
+ return this.unknownFields;
+ }
+ private ORMapDeltaGroup(
+ akka.protobuf.CodedInputStream input,
+ akka.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws akka.protobuf.InvalidProtocolBufferException {
+ initFields();
+ int mutable_bitField0_ = 0;
+ akka.protobuf.UnknownFieldSet.Builder unknownFields =
+ akka.protobuf.UnknownFieldSet.newBuilder();
+ try {
+ boolean done = false;
+ while (!done) {
+ int tag = input.readTag();
+ switch (tag) {
+ case 0:
+ done = true;
+ break;
+ default: {
+ if (!parseUnknownField(input, unknownFields,
+ extensionRegistry, tag)) {
+ done = true;
+ }
+ break;
+ }
+ case 10: {
+ if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+ entries_ = new java.util.ArrayList();
+ mutable_bitField0_ |= 0x00000001;
+ }
+ entries_.add(input.readMessage(akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry.PARSER, extensionRegistry));
+ break;
+ }
+ }
+ }
+ } catch (akka.protobuf.InvalidProtocolBufferException e) {
+ throw e.setUnfinishedMessage(this);
+ } catch (java.io.IOException e) {
+ throw new akka.protobuf.InvalidProtocolBufferException(
+ e.getMessage()).setUnfinishedMessage(this);
+ } finally {
+ if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+ entries_ = java.util.Collections.unmodifiableList(entries_);
+ }
+ this.unknownFields = unknownFields.build();
+ makeExtensionsImmutable();
+ }
+ }
+ public static final akka.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.internal_static_akka_cluster_ddata_ORMapDeltaGroup_descriptor;
+ }
+
+ protected akka.protobuf.GeneratedMessage.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.internal_static_akka_cluster_ddata_ORMapDeltaGroup_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.class, akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Builder.class);
+ }
+
+ public static akka.protobuf.Parser PARSER =
+ new akka.protobuf.AbstractParser() {
+ public ORMapDeltaGroup parsePartialFrom(
+ akka.protobuf.CodedInputStream input,
+ akka.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws akka.protobuf.InvalidProtocolBufferException {
+ return new ORMapDeltaGroup(input, extensionRegistry);
+ }
+ };
+
+ @java.lang.Override
+ public akka.protobuf.Parser getParserForType() {
+ return PARSER;
+ }
+
+ public interface MapEntryOrBuilder
+ extends akka.protobuf.MessageOrBuilder {
+
+ // optional string stringKey = 1;
+ /**
+ * optional string stringKey = 1;
+ */
+ boolean hasStringKey();
+ /**
+ * optional string stringKey = 1;
+ */
+ java.lang.String getStringKey();
+ /**
+ * optional string stringKey = 1;
+ */
+ akka.protobuf.ByteString
+ getStringKeyBytes();
+
+ // required .akka.cluster.ddata.OtherMessage value = 2;
+ /**
+ * required .akka.cluster.ddata.OtherMessage value = 2;
+ */
+ boolean hasValue();
+ /**
+ * required .akka.cluster.ddata.OtherMessage value = 2;
+ */
+ akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage getValue();
+ /**
+ * required .akka.cluster.ddata.OtherMessage value = 2;
+ */
+ akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessageOrBuilder getValueOrBuilder();
+
+ // optional sint32 intKey = 3;
+ /**
+ * optional sint32 intKey = 3;
+ */
+ boolean hasIntKey();
+ /**
+ * optional sint32 intKey = 3;
+ */
+ int getIntKey();
+
+ // optional sint64 longKey = 4;
+ /**
+ * optional sint64 longKey = 4;
+ */
+ boolean hasLongKey();
+ /**
+ * optional sint64 longKey = 4;
+ */
+ long getLongKey();
+
+ // optional .akka.cluster.ddata.OtherMessage otherKey = 5;
+ /**
+ * optional .akka.cluster.ddata.OtherMessage otherKey = 5;
+ */
+ boolean hasOtherKey();
+ /**
+ * optional .akka.cluster.ddata.OtherMessage otherKey = 5;
+ */
+ akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage getOtherKey();
+ /**
+ * optional .akka.cluster.ddata.OtherMessage otherKey = 5;
+ */
+ akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessageOrBuilder getOtherKeyOrBuilder();
+ }
+ /**
+ * Protobuf type {@code akka.cluster.ddata.ORMapDeltaGroup.MapEntry}
+ */
+ public static final class MapEntry extends
+ akka.protobuf.GeneratedMessage
+ implements MapEntryOrBuilder {
+ // Use MapEntry.newBuilder() to construct.
+ private MapEntry(akka.protobuf.GeneratedMessage.Builder> builder) {
+ super(builder);
+ this.unknownFields = builder.getUnknownFields();
+ }
+ private MapEntry(boolean noInit) { this.unknownFields = akka.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+ private static final MapEntry defaultInstance;
+ public static MapEntry getDefaultInstance() {
+ return defaultInstance;
+ }
+
+ public MapEntry getDefaultInstanceForType() {
+ return defaultInstance;
+ }
+
+ private final akka.protobuf.UnknownFieldSet unknownFields;
+ @java.lang.Override
+ public final akka.protobuf.UnknownFieldSet
+ getUnknownFields() {
+ return this.unknownFields;
+ }
+ private MapEntry(
+ akka.protobuf.CodedInputStream input,
+ akka.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws akka.protobuf.InvalidProtocolBufferException {
+ initFields();
+ int mutable_bitField0_ = 0;
+ akka.protobuf.UnknownFieldSet.Builder unknownFields =
+ akka.protobuf.UnknownFieldSet.newBuilder();
+ try {
+ boolean done = false;
+ while (!done) {
+ int tag = input.readTag();
+ switch (tag) {
+ case 0:
+ done = true;
+ break;
+ default: {
+ if (!parseUnknownField(input, unknownFields,
+ extensionRegistry, tag)) {
+ done = true;
+ }
+ break;
+ }
+ case 10: {
+ bitField0_ |= 0x00000001;
+ stringKey_ = input.readBytes();
+ break;
+ }
+ case 18: {
+ akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage.Builder subBuilder = null;
+ if (((bitField0_ & 0x00000002) == 0x00000002)) {
+ subBuilder = value_.toBuilder();
+ }
+ value_ = input.readMessage(akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage.PARSER, extensionRegistry);
+ if (subBuilder != null) {
+ subBuilder.mergeFrom(value_);
+ value_ = subBuilder.buildPartial();
+ }
+ bitField0_ |= 0x00000002;
+ break;
+ }
+ case 24: {
+ bitField0_ |= 0x00000004;
+ intKey_ = input.readSInt32();
+ break;
+ }
+ case 32: {
+ bitField0_ |= 0x00000008;
+ longKey_ = input.readSInt64();
+ break;
+ }
+ case 42: {
+ akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage.Builder subBuilder = null;
+ if (((bitField0_ & 0x00000010) == 0x00000010)) {
+ subBuilder = otherKey_.toBuilder();
+ }
+ otherKey_ = input.readMessage(akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage.PARSER, extensionRegistry);
+ if (subBuilder != null) {
+ subBuilder.mergeFrom(otherKey_);
+ otherKey_ = subBuilder.buildPartial();
+ }
+ bitField0_ |= 0x00000010;
+ break;
+ }
+ }
+ }
+ } catch (akka.protobuf.InvalidProtocolBufferException e) {
+ throw e.setUnfinishedMessage(this);
+ } catch (java.io.IOException e) {
+ throw new akka.protobuf.InvalidProtocolBufferException(
+ e.getMessage()).setUnfinishedMessage(this);
+ } finally {
+ this.unknownFields = unknownFields.build();
+ makeExtensionsImmutable();
+ }
+ }
+ public static final akka.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.internal_static_akka_cluster_ddata_ORMapDeltaGroup_MapEntry_descriptor;
+ }
+
+ protected akka.protobuf.GeneratedMessage.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.internal_static_akka_cluster_ddata_ORMapDeltaGroup_MapEntry_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry.class, akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry.Builder.class);
+ }
+
+ public static akka.protobuf.Parser PARSER =
+ new akka.protobuf.AbstractParser() {
+ public MapEntry parsePartialFrom(
+ akka.protobuf.CodedInputStream input,
+ akka.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws akka.protobuf.InvalidProtocolBufferException {
+ return new MapEntry(input, extensionRegistry);
+ }
+ };
+
+ @java.lang.Override
+ public akka.protobuf.Parser getParserForType() {
+ return PARSER;
+ }
+
+ private int bitField0_;
+ // optional string stringKey = 1;
+ public static final int STRINGKEY_FIELD_NUMBER = 1;
+ private java.lang.Object stringKey_;
+ /**
+ * optional string stringKey = 1;
+ */
+ public boolean hasStringKey() {
+ return ((bitField0_ & 0x00000001) == 0x00000001);
+ }
+ /**
+ * optional string stringKey = 1;
+ */
+ public java.lang.String getStringKey() {
+ java.lang.Object ref = stringKey_;
+ if (ref instanceof java.lang.String) {
+ return (java.lang.String) ref;
+ } else {
+ akka.protobuf.ByteString bs =
+ (akka.protobuf.ByteString) ref;
+ java.lang.String s = bs.toStringUtf8();
+ if (bs.isValidUtf8()) {
+ stringKey_ = s;
+ }
+ return s;
+ }
+ }
+ /**
+ * optional string stringKey = 1;
+ */
+ public akka.protobuf.ByteString
+ getStringKeyBytes() {
+ java.lang.Object ref = stringKey_;
+ if (ref instanceof java.lang.String) {
+ akka.protobuf.ByteString b =
+ akka.protobuf.ByteString.copyFromUtf8(
+ (java.lang.String) ref);
+ stringKey_ = b;
+ return b;
+ } else {
+ return (akka.protobuf.ByteString) ref;
+ }
+ }
+
+ // required .akka.cluster.ddata.OtherMessage value = 2;
+ public static final int VALUE_FIELD_NUMBER = 2;
+ private akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage value_;
+ /**
+ * required .akka.cluster.ddata.OtherMessage value = 2;
+ */
+ public boolean hasValue() {
+ return ((bitField0_ & 0x00000002) == 0x00000002);
+ }
+ /**
+ * required .akka.cluster.ddata.OtherMessage value = 2;
+ */
+ public akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage getValue() {
+ return value_;
+ }
+ /**
+ * required .akka.cluster.ddata.OtherMessage value = 2;
+ */
+ public akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessageOrBuilder getValueOrBuilder() {
+ return value_;
+ }
+
+ // optional sint32 intKey = 3;
+ public static final int INTKEY_FIELD_NUMBER = 3;
+ private int intKey_;
+ /**
+ * optional sint32 intKey = 3;
+ */
+ public boolean hasIntKey() {
+ return ((bitField0_ & 0x00000004) == 0x00000004);
+ }
+ /**
+ * optional sint32 intKey = 3;
+ */
+ public int getIntKey() {
+ return intKey_;
+ }
+
+ // optional sint64 longKey = 4;
+ public static final int LONGKEY_FIELD_NUMBER = 4;
+ private long longKey_;
+ /**
+ * optional sint64 longKey = 4;
+ */
+ public boolean hasLongKey() {
+ return ((bitField0_ & 0x00000008) == 0x00000008);
+ }
+ /**
+ * optional sint64 longKey = 4;
+ */
+ public long getLongKey() {
+ return longKey_;
+ }
+
+ // optional .akka.cluster.ddata.OtherMessage otherKey = 5;
+ public static final int OTHERKEY_FIELD_NUMBER = 5;
+ private akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage otherKey_;
+ /**
+ * optional .akka.cluster.ddata.OtherMessage otherKey = 5;
+ */
+ public boolean hasOtherKey() {
+ return ((bitField0_ & 0x00000010) == 0x00000010);
+ }
+ /**
+ * optional .akka.cluster.ddata.OtherMessage otherKey = 5;
+ */
+ public akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage getOtherKey() {
+ return otherKey_;
+ }
+ /**
+ * optional .akka.cluster.ddata.OtherMessage otherKey = 5;
+ */
+ public akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessageOrBuilder getOtherKeyOrBuilder() {
+ return otherKey_;
+ }
+
+ private void initFields() {
+ stringKey_ = "";
+ value_ = akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage.getDefaultInstance();
+ intKey_ = 0;
+ longKey_ = 0L;
+ otherKey_ = akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage.getDefaultInstance();
+ }
+ private byte memoizedIsInitialized = -1;
+ public final boolean isInitialized() {
+ byte isInitialized = memoizedIsInitialized;
+ if (isInitialized != -1) return isInitialized == 1;
+
+ if (!hasValue()) {
+ memoizedIsInitialized = 0;
+ return false;
+ }
+ if (!getValue().isInitialized()) {
+ memoizedIsInitialized = 0;
+ return false;
+ }
+ if (hasOtherKey()) {
+ if (!getOtherKey().isInitialized()) {
+ memoizedIsInitialized = 0;
+ return false;
+ }
+ }
+ memoizedIsInitialized = 1;
+ return true;
+ }
+
+ public void writeTo(akka.protobuf.CodedOutputStream output)
+ throws java.io.IOException {
+ getSerializedSize();
+ if (((bitField0_ & 0x00000001) == 0x00000001)) {
+ output.writeBytes(1, getStringKeyBytes());
+ }
+ if (((bitField0_ & 0x00000002) == 0x00000002)) {
+ output.writeMessage(2, value_);
+ }
+ if (((bitField0_ & 0x00000004) == 0x00000004)) {
+ output.writeSInt32(3, intKey_);
+ }
+ if (((bitField0_ & 0x00000008) == 0x00000008)) {
+ output.writeSInt64(4, longKey_);
+ }
+ if (((bitField0_ & 0x00000010) == 0x00000010)) {
+ output.writeMessage(5, otherKey_);
+ }
+ getUnknownFields().writeTo(output);
+ }
+
+ private int memoizedSerializedSize = -1;
+ public int getSerializedSize() {
+ int size = memoizedSerializedSize;
+ if (size != -1) return size;
+
+ size = 0;
+ if (((bitField0_ & 0x00000001) == 0x00000001)) {
+ size += akka.protobuf.CodedOutputStream
+ .computeBytesSize(1, getStringKeyBytes());
+ }
+ if (((bitField0_ & 0x00000002) == 0x00000002)) {
+ size += akka.protobuf.CodedOutputStream
+ .computeMessageSize(2, value_);
+ }
+ if (((bitField0_ & 0x00000004) == 0x00000004)) {
+ size += akka.protobuf.CodedOutputStream
+ .computeSInt32Size(3, intKey_);
+ }
+ if (((bitField0_ & 0x00000008) == 0x00000008)) {
+ size += akka.protobuf.CodedOutputStream
+ .computeSInt64Size(4, longKey_);
+ }
+ if (((bitField0_ & 0x00000010) == 0x00000010)) {
+ size += akka.protobuf.CodedOutputStream
+ .computeMessageSize(5, otherKey_);
+ }
+ size += getUnknownFields().getSerializedSize();
+ memoizedSerializedSize = size;
+ return size;
+ }
+
+ private static final long serialVersionUID = 0L;
+ @java.lang.Override
+ protected java.lang.Object writeReplace()
+ throws java.io.ObjectStreamException {
+ return super.writeReplace();
+ }
+
+ public static akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry parseFrom(
+ akka.protobuf.ByteString data)
+ throws akka.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry parseFrom(
+ akka.protobuf.ByteString data,
+ akka.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws akka.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry parseFrom(byte[] data)
+ throws akka.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry parseFrom(
+ byte[] data,
+ akka.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws akka.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry parseFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input);
+ }
+ public static akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry parseFrom(
+ java.io.InputStream input,
+ akka.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input, extensionRegistry);
+ }
+ public static akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry parseDelimitedFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return PARSER.parseDelimitedFrom(input);
+ }
+ public static akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry parseDelimitedFrom(
+ java.io.InputStream input,
+ akka.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseDelimitedFrom(input, extensionRegistry);
+ }
+ public static akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry parseFrom(
+ akka.protobuf.CodedInputStream input)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input);
+ }
+ public static akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry parseFrom(
+ akka.protobuf.CodedInputStream input,
+ akka.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input, extensionRegistry);
+ }
+
+ public static Builder newBuilder() { return Builder.create(); }
+ public Builder newBuilderForType() { return newBuilder(); }
+ public static Builder newBuilder(akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry prototype) {
+ return newBuilder().mergeFrom(prototype);
+ }
+ public Builder toBuilder() { return newBuilder(this); }
+
+ @java.lang.Override
+ protected Builder newBuilderForType(
+ akka.protobuf.GeneratedMessage.BuilderParent parent) {
+ Builder builder = new Builder(parent);
+ return builder;
+ }
+ /**
+ * Protobuf type {@code akka.cluster.ddata.ORMapDeltaGroup.MapEntry}
+ */
+ public static final class Builder extends
+ akka.protobuf.GeneratedMessage.Builder
+ implements akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntryOrBuilder {
+ public static final akka.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.internal_static_akka_cluster_ddata_ORMapDeltaGroup_MapEntry_descriptor;
+ }
+
+ protected akka.protobuf.GeneratedMessage.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.internal_static_akka_cluster_ddata_ORMapDeltaGroup_MapEntry_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry.class, akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry.Builder.class);
+ }
+
+ // Construct using akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry.newBuilder()
+ private Builder() {
+ maybeForceBuilderInitialization();
+ }
+
+ private Builder(
+ akka.protobuf.GeneratedMessage.BuilderParent parent) {
+ super(parent);
+ maybeForceBuilderInitialization();
+ }
+ private void maybeForceBuilderInitialization() {
+ if (akka.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+ getValueFieldBuilder();
+ getOtherKeyFieldBuilder();
+ }
+ }
+ private static Builder create() {
+ return new Builder();
+ }
+
+ public Builder clear() {
+ super.clear();
+ stringKey_ = "";
+ bitField0_ = (bitField0_ & ~0x00000001);
+ if (valueBuilder_ == null) {
+ value_ = akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage.getDefaultInstance();
+ } else {
+ valueBuilder_.clear();
+ }
+ bitField0_ = (bitField0_ & ~0x00000002);
+ intKey_ = 0;
+ bitField0_ = (bitField0_ & ~0x00000004);
+ longKey_ = 0L;
+ bitField0_ = (bitField0_ & ~0x00000008);
+ if (otherKeyBuilder_ == null) {
+ otherKey_ = akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage.getDefaultInstance();
+ } else {
+ otherKeyBuilder_.clear();
+ }
+ bitField0_ = (bitField0_ & ~0x00000010);
+ return this;
+ }
+
+ public Builder clone() {
+ return create().mergeFrom(buildPartial());
+ }
+
+ public akka.protobuf.Descriptors.Descriptor
+ getDescriptorForType() {
+ return akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.internal_static_akka_cluster_ddata_ORMapDeltaGroup_MapEntry_descriptor;
+ }
+
+ public akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry getDefaultInstanceForType() {
+ return akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry.getDefaultInstance();
+ }
+
+ public akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry build() {
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry result = buildPartial();
+ if (!result.isInitialized()) {
+ throw newUninitializedMessageException(result);
+ }
+ return result;
+ }
+
+ public akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry buildPartial() {
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry result = new akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry(this);
+ int from_bitField0_ = bitField0_;
+ int to_bitField0_ = 0;
+ if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+ to_bitField0_ |= 0x00000001;
+ }
+ result.stringKey_ = stringKey_;
+ if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+ to_bitField0_ |= 0x00000002;
+ }
+ if (valueBuilder_ == null) {
+ result.value_ = value_;
+ } else {
+ result.value_ = valueBuilder_.build();
+ }
+ if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+ to_bitField0_ |= 0x00000004;
+ }
+ result.intKey_ = intKey_;
+ if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+ to_bitField0_ |= 0x00000008;
+ }
+ result.longKey_ = longKey_;
+ if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
+ to_bitField0_ |= 0x00000010;
+ }
+ if (otherKeyBuilder_ == null) {
+ result.otherKey_ = otherKey_;
+ } else {
+ result.otherKey_ = otherKeyBuilder_.build();
+ }
+ result.bitField0_ = to_bitField0_;
+ onBuilt();
+ return result;
+ }
+
+ public Builder mergeFrom(akka.protobuf.Message other) {
+ if (other instanceof akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry) {
+ return mergeFrom((akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry)other);
+ } else {
+ super.mergeFrom(other);
+ return this;
+ }
+ }
+
+ public Builder mergeFrom(akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry other) {
+ if (other == akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry.getDefaultInstance()) return this;
+ if (other.hasStringKey()) {
+ bitField0_ |= 0x00000001;
+ stringKey_ = other.stringKey_;
+ onChanged();
+ }
+ if (other.hasValue()) {
+ mergeValue(other.getValue());
+ }
+ if (other.hasIntKey()) {
+ setIntKey(other.getIntKey());
+ }
+ if (other.hasLongKey()) {
+ setLongKey(other.getLongKey());
+ }
+ if (other.hasOtherKey()) {
+ mergeOtherKey(other.getOtherKey());
+ }
+ this.mergeUnknownFields(other.getUnknownFields());
+ return this;
+ }
+
+ public final boolean isInitialized() {
+ if (!hasValue()) {
+
+ return false;
+ }
+ if (!getValue().isInitialized()) {
+
+ return false;
+ }
+ if (hasOtherKey()) {
+ if (!getOtherKey().isInitialized()) {
+
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public Builder mergeFrom(
+ akka.protobuf.CodedInputStream input,
+ akka.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry parsedMessage = null;
+ try {
+ parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+ } catch (akka.protobuf.InvalidProtocolBufferException e) {
+ parsedMessage = (akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry) e.getUnfinishedMessage();
+ throw e;
+ } finally {
+ if (parsedMessage != null) {
+ mergeFrom(parsedMessage);
+ }
+ }
+ return this;
+ }
+ private int bitField0_;
+
+ // optional string stringKey = 1;
+ private java.lang.Object stringKey_ = "";
+ /**
+ * optional string stringKey = 1;
+ */
+ public boolean hasStringKey() {
+ return ((bitField0_ & 0x00000001) == 0x00000001);
+ }
+ /**
+ * optional string stringKey = 1;
+ */
+ public java.lang.String getStringKey() {
+ java.lang.Object ref = stringKey_;
+ if (!(ref instanceof java.lang.String)) {
+ java.lang.String s = ((akka.protobuf.ByteString) ref)
+ .toStringUtf8();
+ stringKey_ = s;
+ return s;
+ } else {
+ return (java.lang.String) ref;
+ }
+ }
+ /**
+ * optional string stringKey = 1;
+ */
+ public akka.protobuf.ByteString
+ getStringKeyBytes() {
+ java.lang.Object ref = stringKey_;
+ if (ref instanceof String) {
+ akka.protobuf.ByteString b =
+ akka.protobuf.ByteString.copyFromUtf8(
+ (java.lang.String) ref);
+ stringKey_ = b;
+ return b;
+ } else {
+ return (akka.protobuf.ByteString) ref;
+ }
+ }
+ /**
+ * optional string stringKey = 1;
+ */
+ public Builder setStringKey(
+ java.lang.String value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000001;
+ stringKey_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * optional string stringKey = 1;
+ */
+ public Builder clearStringKey() {
+ bitField0_ = (bitField0_ & ~0x00000001);
+ stringKey_ = getDefaultInstance().getStringKey();
+ onChanged();
+ return this;
+ }
+ /**
+ * optional string stringKey = 1;
+ */
+ public Builder setStringKeyBytes(
+ akka.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000001;
+ stringKey_ = value;
+ onChanged();
+ return this;
+ }
+
+ // required .akka.cluster.ddata.OtherMessage value = 2;
+ private akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage value_ = akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage.getDefaultInstance();
+ private akka.protobuf.SingleFieldBuilder<
+ akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage, akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage.Builder, akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessageOrBuilder> valueBuilder_;
+ /**
+ * required .akka.cluster.ddata.OtherMessage value = 2;
+ */
+ public boolean hasValue() {
+ return ((bitField0_ & 0x00000002) == 0x00000002);
+ }
+ /**
+ * required .akka.cluster.ddata.OtherMessage value = 2;
+ */
+ public akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage getValue() {
+ if (valueBuilder_ == null) {
+ return value_;
+ } else {
+ return valueBuilder_.getMessage();
+ }
+ }
+ /**
+ * required .akka.cluster.ddata.OtherMessage value = 2;
+ */
+ public Builder setValue(akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage value) {
+ if (valueBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ value_ = value;
+ onChanged();
+ } else {
+ valueBuilder_.setMessage(value);
+ }
+ bitField0_ |= 0x00000002;
+ return this;
+ }
+ /**
+ * required .akka.cluster.ddata.OtherMessage value = 2;
+ */
+ public Builder setValue(
+ akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage.Builder builderForValue) {
+ if (valueBuilder_ == null) {
+ value_ = builderForValue.build();
+ onChanged();
+ } else {
+ valueBuilder_.setMessage(builderForValue.build());
+ }
+ bitField0_ |= 0x00000002;
+ return this;
+ }
+ /**
+ * required .akka.cluster.ddata.OtherMessage value = 2;
+ */
+ public Builder mergeValue(akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage value) {
+ if (valueBuilder_ == null) {
+ if (((bitField0_ & 0x00000002) == 0x00000002) &&
+ value_ != akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage.getDefaultInstance()) {
+ value_ =
+ akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage.newBuilder(value_).mergeFrom(value).buildPartial();
+ } else {
+ value_ = value;
+ }
+ onChanged();
+ } else {
+ valueBuilder_.mergeFrom(value);
+ }
+ bitField0_ |= 0x00000002;
+ return this;
+ }
+ /**
+ * required .akka.cluster.ddata.OtherMessage value = 2;
+ */
+ public Builder clearValue() {
+ if (valueBuilder_ == null) {
+ value_ = akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage.getDefaultInstance();
+ onChanged();
+ } else {
+ valueBuilder_.clear();
+ }
+ bitField0_ = (bitField0_ & ~0x00000002);
+ return this;
+ }
+ /**
+ * required .akka.cluster.ddata.OtherMessage value = 2;
+ */
+ public akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage.Builder getValueBuilder() {
+ bitField0_ |= 0x00000002;
+ onChanged();
+ return getValueFieldBuilder().getBuilder();
+ }
+ /**
+ * required .akka.cluster.ddata.OtherMessage value = 2;
+ */
+ public akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessageOrBuilder getValueOrBuilder() {
+ if (valueBuilder_ != null) {
+ return valueBuilder_.getMessageOrBuilder();
+ } else {
+ return value_;
+ }
+ }
+ /**
+ * required .akka.cluster.ddata.OtherMessage value = 2;
+ */
+ private akka.protobuf.SingleFieldBuilder<
+ akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage, akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage.Builder, akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessageOrBuilder>
+ getValueFieldBuilder() {
+ if (valueBuilder_ == null) {
+ valueBuilder_ = new akka.protobuf.SingleFieldBuilder<
+ akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage, akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage.Builder, akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessageOrBuilder>(
+ value_,
+ getParentForChildren(),
+ isClean());
+ value_ = null;
+ }
+ return valueBuilder_;
+ }
+
+ // optional sint32 intKey = 3;
+ private int intKey_ ;
+ /**
+ * optional sint32 intKey = 3;
+ */
+ public boolean hasIntKey() {
+ return ((bitField0_ & 0x00000004) == 0x00000004);
+ }
+ /**
+ * optional sint32 intKey = 3;
+ */
+ public int getIntKey() {
+ return intKey_;
+ }
+ /**
+ * optional sint32 intKey = 3;
+ */
+ public Builder setIntKey(int value) {
+ bitField0_ |= 0x00000004;
+ intKey_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * optional sint32 intKey = 3;
+ */
+ public Builder clearIntKey() {
+ bitField0_ = (bitField0_ & ~0x00000004);
+ intKey_ = 0;
+ onChanged();
+ return this;
+ }
+
+ // optional sint64 longKey = 4;
+ private long longKey_ ;
+ /**
+ * optional sint64 longKey = 4;
+ */
+ public boolean hasLongKey() {
+ return ((bitField0_ & 0x00000008) == 0x00000008);
+ }
+ /**
+ * optional sint64 longKey = 4;
+ */
+ public long getLongKey() {
+ return longKey_;
+ }
+ /**
+ * optional sint64 longKey = 4;
+ */
+ public Builder setLongKey(long value) {
+ bitField0_ |= 0x00000008;
+ longKey_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * optional sint64 longKey = 4;
+ */
+ public Builder clearLongKey() {
+ bitField0_ = (bitField0_ & ~0x00000008);
+ longKey_ = 0L;
+ onChanged();
+ return this;
+ }
+
+ // optional .akka.cluster.ddata.OtherMessage otherKey = 5;
+ private akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage otherKey_ = akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage.getDefaultInstance();
+ private akka.protobuf.SingleFieldBuilder<
+ akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage, akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage.Builder, akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessageOrBuilder> otherKeyBuilder_;
+ /**
+ * optional .akka.cluster.ddata.OtherMessage otherKey = 5;
+ */
+ public boolean hasOtherKey() {
+ return ((bitField0_ & 0x00000010) == 0x00000010);
+ }
+ /**
+ * optional .akka.cluster.ddata.OtherMessage otherKey = 5;
+ */
+ public akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage getOtherKey() {
+ if (otherKeyBuilder_ == null) {
+ return otherKey_;
+ } else {
+ return otherKeyBuilder_.getMessage();
+ }
+ }
+ /**
+ * optional .akka.cluster.ddata.OtherMessage otherKey = 5;
+ */
+ public Builder setOtherKey(akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage value) {
+ if (otherKeyBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ otherKey_ = value;
+ onChanged();
+ } else {
+ otherKeyBuilder_.setMessage(value);
+ }
+ bitField0_ |= 0x00000010;
+ return this;
+ }
+ /**
+ * optional .akka.cluster.ddata.OtherMessage otherKey = 5;
+ */
+ public Builder setOtherKey(
+ akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage.Builder builderForValue) {
+ if (otherKeyBuilder_ == null) {
+ otherKey_ = builderForValue.build();
+ onChanged();
+ } else {
+ otherKeyBuilder_.setMessage(builderForValue.build());
+ }
+ bitField0_ |= 0x00000010;
+ return this;
+ }
+ /**
+ * optional .akka.cluster.ddata.OtherMessage otherKey = 5;
+ */
+ public Builder mergeOtherKey(akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage value) {
+ if (otherKeyBuilder_ == null) {
+ if (((bitField0_ & 0x00000010) == 0x00000010) &&
+ otherKey_ != akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage.getDefaultInstance()) {
+ otherKey_ =
+ akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage.newBuilder(otherKey_).mergeFrom(value).buildPartial();
+ } else {
+ otherKey_ = value;
+ }
+ onChanged();
+ } else {
+ otherKeyBuilder_.mergeFrom(value);
+ }
+ bitField0_ |= 0x00000010;
+ return this;
+ }
+ /**
+ * optional .akka.cluster.ddata.OtherMessage otherKey = 5;
+ */
+ public Builder clearOtherKey() {
+ if (otherKeyBuilder_ == null) {
+ otherKey_ = akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage.getDefaultInstance();
+ onChanged();
+ } else {
+ otherKeyBuilder_.clear();
+ }
+ bitField0_ = (bitField0_ & ~0x00000010);
+ return this;
+ }
+ /**
+ * optional .akka.cluster.ddata.OtherMessage otherKey = 5;
+ */
+ public akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage.Builder getOtherKeyBuilder() {
+ bitField0_ |= 0x00000010;
+ onChanged();
+ return getOtherKeyFieldBuilder().getBuilder();
+ }
+ /**
+ * optional .akka.cluster.ddata.OtherMessage otherKey = 5;
+ */
+ public akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessageOrBuilder getOtherKeyOrBuilder() {
+ if (otherKeyBuilder_ != null) {
+ return otherKeyBuilder_.getMessageOrBuilder();
+ } else {
+ return otherKey_;
+ }
+ }
+ /**
+ * optional .akka.cluster.ddata.OtherMessage otherKey = 5;
+ */
+ private akka.protobuf.SingleFieldBuilder<
+ akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage, akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage.Builder, akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessageOrBuilder>
+ getOtherKeyFieldBuilder() {
+ if (otherKeyBuilder_ == null) {
+ otherKeyBuilder_ = new akka.protobuf.SingleFieldBuilder<
+ akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage, akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessage.Builder, akka.cluster.ddata.protobuf.msg.ReplicatorMessages.OtherMessageOrBuilder>(
+ otherKey_,
+ getParentForChildren(),
+ isClean());
+ otherKey_ = null;
+ }
+ return otherKeyBuilder_;
+ }
+
+ // @@protoc_insertion_point(builder_scope:akka.cluster.ddata.ORMapDeltaGroup.MapEntry)
+ }
+
+ static {
+ defaultInstance = new MapEntry(true);
+ defaultInstance.initFields();
+ }
+
+ // @@protoc_insertion_point(class_scope:akka.cluster.ddata.ORMapDeltaGroup.MapEntry)
+ }
+
+ public interface EntryOrBuilder
+ extends akka.protobuf.MessageOrBuilder {
+
+ // required .akka.cluster.ddata.ORMapDeltaOp operation = 1;
+ /**
+ * required .akka.cluster.ddata.ORMapDeltaOp operation = 1;
+ */
+ boolean hasOperation();
+ /**
+ * required .akka.cluster.ddata.ORMapDeltaOp operation = 1;
+ */
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaOp getOperation();
+
+ // required .akka.cluster.ddata.ORSet underlying = 2;
+ /**
+ * required .akka.cluster.ddata.ORSet underlying = 2;
+ */
+ boolean hasUnderlying();
+ /**
+ * required .akka.cluster.ddata.ORSet underlying = 2;
+ */
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORSet getUnderlying();
+ /**
+ * required .akka.cluster.ddata.ORSet underlying = 2;
+ */
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORSetOrBuilder getUnderlyingOrBuilder();
+
+ // required sint32 zeroTag = 3;
+ /**
+ * required sint32 zeroTag = 3;
+ */
+ boolean hasZeroTag();
+ /**
+ * required sint32 zeroTag = 3;
+ */
+ int getZeroTag();
+
+ // optional .akka.cluster.ddata.ORMapDeltaGroup.MapEntry entryData = 4;
+ /**
+ * optional .akka.cluster.ddata.ORMapDeltaGroup.MapEntry entryData = 4;
+ */
+ boolean hasEntryData();
+ /**
+ * optional .akka.cluster.ddata.ORMapDeltaGroup.MapEntry entryData = 4;
+ */
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry getEntryData();
+ /**
+ * optional .akka.cluster.ddata.ORMapDeltaGroup.MapEntry entryData = 4;
+ */
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntryOrBuilder getEntryDataOrBuilder();
+ }
+ /**
+ * Protobuf type {@code akka.cluster.ddata.ORMapDeltaGroup.Entry}
+ */
+ public static final class Entry extends
+ akka.protobuf.GeneratedMessage
+ implements EntryOrBuilder {
+ // Use Entry.newBuilder() to construct.
+ private Entry(akka.protobuf.GeneratedMessage.Builder> builder) {
+ super(builder);
+ this.unknownFields = builder.getUnknownFields();
+ }
+ private Entry(boolean noInit) { this.unknownFields = akka.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+ private static final Entry defaultInstance;
+ public static Entry getDefaultInstance() {
+ return defaultInstance;
+ }
+
+ public Entry getDefaultInstanceForType() {
+ return defaultInstance;
+ }
+
+ private final akka.protobuf.UnknownFieldSet unknownFields;
+ @java.lang.Override
+ public final akka.protobuf.UnknownFieldSet
+ getUnknownFields() {
+ return this.unknownFields;
+ }
+ private Entry(
+ akka.protobuf.CodedInputStream input,
+ akka.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws akka.protobuf.InvalidProtocolBufferException {
+ initFields();
+ int mutable_bitField0_ = 0;
+ akka.protobuf.UnknownFieldSet.Builder unknownFields =
+ akka.protobuf.UnknownFieldSet.newBuilder();
+ try {
+ boolean done = false;
+ while (!done) {
+ int tag = input.readTag();
+ switch (tag) {
+ case 0:
+ done = true;
+ break;
+ default: {
+ if (!parseUnknownField(input, unknownFields,
+ extensionRegistry, tag)) {
+ done = true;
+ }
+ break;
+ }
+ case 8: {
+ int rawValue = input.readEnum();
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaOp value = akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaOp.valueOf(rawValue);
+ if (value == null) {
+ unknownFields.mergeVarintField(1, rawValue);
+ } else {
+ bitField0_ |= 0x00000001;
+ operation_ = value;
+ }
+ break;
+ }
+ case 18: {
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORSet.Builder subBuilder = null;
+ if (((bitField0_ & 0x00000002) == 0x00000002)) {
+ subBuilder = underlying_.toBuilder();
+ }
+ underlying_ = input.readMessage(akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORSet.PARSER, extensionRegistry);
+ if (subBuilder != null) {
+ subBuilder.mergeFrom(underlying_);
+ underlying_ = subBuilder.buildPartial();
+ }
+ bitField0_ |= 0x00000002;
+ break;
+ }
+ case 24: {
+ bitField0_ |= 0x00000004;
+ zeroTag_ = input.readSInt32();
+ break;
+ }
+ case 34: {
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry.Builder subBuilder = null;
+ if (((bitField0_ & 0x00000008) == 0x00000008)) {
+ subBuilder = entryData_.toBuilder();
+ }
+ entryData_ = input.readMessage(akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry.PARSER, extensionRegistry);
+ if (subBuilder != null) {
+ subBuilder.mergeFrom(entryData_);
+ entryData_ = subBuilder.buildPartial();
+ }
+ bitField0_ |= 0x00000008;
+ break;
+ }
+ }
+ }
+ } catch (akka.protobuf.InvalidProtocolBufferException e) {
+ throw e.setUnfinishedMessage(this);
+ } catch (java.io.IOException e) {
+ throw new akka.protobuf.InvalidProtocolBufferException(
+ e.getMessage()).setUnfinishedMessage(this);
+ } finally {
+ this.unknownFields = unknownFields.build();
+ makeExtensionsImmutable();
+ }
+ }
+ public static final akka.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.internal_static_akka_cluster_ddata_ORMapDeltaGroup_Entry_descriptor;
+ }
+
+ protected akka.protobuf.GeneratedMessage.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.internal_static_akka_cluster_ddata_ORMapDeltaGroup_Entry_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry.class, akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry.Builder.class);
+ }
+
+ public static akka.protobuf.Parser PARSER =
+ new akka.protobuf.AbstractParser() {
+ public Entry parsePartialFrom(
+ akka.protobuf.CodedInputStream input,
+ akka.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws akka.protobuf.InvalidProtocolBufferException {
+ return new Entry(input, extensionRegistry);
+ }
+ };
+
+ @java.lang.Override
+ public akka.protobuf.Parser getParserForType() {
+ return PARSER;
+ }
+
+ private int bitField0_;
+ // required .akka.cluster.ddata.ORMapDeltaOp operation = 1;
+ public static final int OPERATION_FIELD_NUMBER = 1;
+ private akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaOp operation_;
+ /**
+ * required .akka.cluster.ddata.ORMapDeltaOp operation = 1;
+ */
+ public boolean hasOperation() {
+ return ((bitField0_ & 0x00000001) == 0x00000001);
+ }
+ /**
+ * required .akka.cluster.ddata.ORMapDeltaOp operation = 1;
+ */
+ public akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaOp getOperation() {
+ return operation_;
+ }
+
+ // required .akka.cluster.ddata.ORSet underlying = 2;
+ public static final int UNDERLYING_FIELD_NUMBER = 2;
+ private akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORSet underlying_;
+ /**
+ * required .akka.cluster.ddata.ORSet underlying = 2;
+ */
+ public boolean hasUnderlying() {
+ return ((bitField0_ & 0x00000002) == 0x00000002);
+ }
+ /**
+ * required .akka.cluster.ddata.ORSet underlying = 2;
+ */
+ public akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORSet getUnderlying() {
+ return underlying_;
+ }
+ /**
+ * required .akka.cluster.ddata.ORSet underlying = 2;
+ */
+ public akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORSetOrBuilder getUnderlyingOrBuilder() {
+ return underlying_;
+ }
+
+ // required sint32 zeroTag = 3;
+ public static final int ZEROTAG_FIELD_NUMBER = 3;
+ private int zeroTag_;
+ /**
+ * required sint32 zeroTag = 3;
+ */
+ public boolean hasZeroTag() {
+ return ((bitField0_ & 0x00000004) == 0x00000004);
+ }
+ /**
+ * required sint32 zeroTag = 3;
+ */
+ public int getZeroTag() {
+ return zeroTag_;
+ }
+
+ // optional .akka.cluster.ddata.ORMapDeltaGroup.MapEntry entryData = 4;
+ public static final int ENTRYDATA_FIELD_NUMBER = 4;
+ private akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry entryData_;
+ /**
+ * optional .akka.cluster.ddata.ORMapDeltaGroup.MapEntry entryData = 4;
+ */
+ public boolean hasEntryData() {
+ return ((bitField0_ & 0x00000008) == 0x00000008);
+ }
+ /**
+ * optional .akka.cluster.ddata.ORMapDeltaGroup.MapEntry entryData = 4;
+ */
+ public akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry getEntryData() {
+ return entryData_;
+ }
+ /**
+ * optional .akka.cluster.ddata.ORMapDeltaGroup.MapEntry entryData = 4;
+ */
+ public akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntryOrBuilder getEntryDataOrBuilder() {
+ return entryData_;
+ }
+
+ private void initFields() {
+ operation_ = akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaOp.ORMapPut;
+ underlying_ = akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORSet.getDefaultInstance();
+ zeroTag_ = 0;
+ entryData_ = akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry.getDefaultInstance();
+ }
+ private byte memoizedIsInitialized = -1;
+ public final boolean isInitialized() {
+ byte isInitialized = memoizedIsInitialized;
+ if (isInitialized != -1) return isInitialized == 1;
+
+ if (!hasOperation()) {
+ memoizedIsInitialized = 0;
+ return false;
+ }
+ if (!hasUnderlying()) {
+ memoizedIsInitialized = 0;
+ return false;
+ }
+ if (!hasZeroTag()) {
+ memoizedIsInitialized = 0;
+ return false;
+ }
+ if (!getUnderlying().isInitialized()) {
+ memoizedIsInitialized = 0;
+ return false;
+ }
+ if (hasEntryData()) {
+ if (!getEntryData().isInitialized()) {
+ memoizedIsInitialized = 0;
+ return false;
+ }
+ }
+ memoizedIsInitialized = 1;
+ return true;
+ }
+
+ public void writeTo(akka.protobuf.CodedOutputStream output)
+ throws java.io.IOException {
+ getSerializedSize();
+ if (((bitField0_ & 0x00000001) == 0x00000001)) {
+ output.writeEnum(1, operation_.getNumber());
+ }
+ if (((bitField0_ & 0x00000002) == 0x00000002)) {
+ output.writeMessage(2, underlying_);
+ }
+ if (((bitField0_ & 0x00000004) == 0x00000004)) {
+ output.writeSInt32(3, zeroTag_);
+ }
+ if (((bitField0_ & 0x00000008) == 0x00000008)) {
+ output.writeMessage(4, entryData_);
+ }
+ getUnknownFields().writeTo(output);
+ }
+
+ private int memoizedSerializedSize = -1;
+ public int getSerializedSize() {
+ int size = memoizedSerializedSize;
+ if (size != -1) return size;
+
+ size = 0;
+ if (((bitField0_ & 0x00000001) == 0x00000001)) {
+ size += akka.protobuf.CodedOutputStream
+ .computeEnumSize(1, operation_.getNumber());
+ }
+ if (((bitField0_ & 0x00000002) == 0x00000002)) {
+ size += akka.protobuf.CodedOutputStream
+ .computeMessageSize(2, underlying_);
+ }
+ if (((bitField0_ & 0x00000004) == 0x00000004)) {
+ size += akka.protobuf.CodedOutputStream
+ .computeSInt32Size(3, zeroTag_);
+ }
+ if (((bitField0_ & 0x00000008) == 0x00000008)) {
+ size += akka.protobuf.CodedOutputStream
+ .computeMessageSize(4, entryData_);
+ }
+ size += getUnknownFields().getSerializedSize();
+ memoizedSerializedSize = size;
+ return size;
+ }
+
+ private static final long serialVersionUID = 0L;
+ @java.lang.Override
+ protected java.lang.Object writeReplace()
+ throws java.io.ObjectStreamException {
+ return super.writeReplace();
+ }
+
+ public static akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry parseFrom(
+ akka.protobuf.ByteString data)
+ throws akka.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry parseFrom(
+ akka.protobuf.ByteString data,
+ akka.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws akka.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry parseFrom(byte[] data)
+ throws akka.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry parseFrom(
+ byte[] data,
+ akka.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws akka.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry parseFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input);
+ }
+ public static akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry parseFrom(
+ java.io.InputStream input,
+ akka.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input, extensionRegistry);
+ }
+ public static akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry parseDelimitedFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return PARSER.parseDelimitedFrom(input);
+ }
+ public static akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry parseDelimitedFrom(
+ java.io.InputStream input,
+ akka.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseDelimitedFrom(input, extensionRegistry);
+ }
+ public static akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry parseFrom(
+ akka.protobuf.CodedInputStream input)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input);
+ }
+ public static akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry parseFrom(
+ akka.protobuf.CodedInputStream input,
+ akka.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input, extensionRegistry);
+ }
+
+ public static Builder newBuilder() { return Builder.create(); }
+ public Builder newBuilderForType() { return newBuilder(); }
+ public static Builder newBuilder(akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry prototype) {
+ return newBuilder().mergeFrom(prototype);
+ }
+ public Builder toBuilder() { return newBuilder(this); }
+
+ @java.lang.Override
+ protected Builder newBuilderForType(
+ akka.protobuf.GeneratedMessage.BuilderParent parent) {
+ Builder builder = new Builder(parent);
+ return builder;
+ }
+ /**
+ * Protobuf type {@code akka.cluster.ddata.ORMapDeltaGroup.Entry}
+ */
+ public static final class Builder extends
+ akka.protobuf.GeneratedMessage.Builder
+ implements akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.EntryOrBuilder {
+ public static final akka.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.internal_static_akka_cluster_ddata_ORMapDeltaGroup_Entry_descriptor;
+ }
+
+ protected akka.protobuf.GeneratedMessage.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.internal_static_akka_cluster_ddata_ORMapDeltaGroup_Entry_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry.class, akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry.Builder.class);
+ }
+
+ // Construct using akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry.newBuilder()
+ private Builder() {
+ maybeForceBuilderInitialization();
+ }
+
+ private Builder(
+ akka.protobuf.GeneratedMessage.BuilderParent parent) {
+ super(parent);
+ maybeForceBuilderInitialization();
+ }
+ private void maybeForceBuilderInitialization() {
+ if (akka.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+ getUnderlyingFieldBuilder();
+ getEntryDataFieldBuilder();
+ }
+ }
+ private static Builder create() {
+ return new Builder();
+ }
+
+ public Builder clear() {
+ super.clear();
+ operation_ = akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaOp.ORMapPut;
+ bitField0_ = (bitField0_ & ~0x00000001);
+ if (underlyingBuilder_ == null) {
+ underlying_ = akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORSet.getDefaultInstance();
+ } else {
+ underlyingBuilder_.clear();
+ }
+ bitField0_ = (bitField0_ & ~0x00000002);
+ zeroTag_ = 0;
+ bitField0_ = (bitField0_ & ~0x00000004);
+ if (entryDataBuilder_ == null) {
+ entryData_ = akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry.getDefaultInstance();
+ } else {
+ entryDataBuilder_.clear();
+ }
+ bitField0_ = (bitField0_ & ~0x00000008);
+ return this;
+ }
+
+ public Builder clone() {
+ return create().mergeFrom(buildPartial());
+ }
+
+ public akka.protobuf.Descriptors.Descriptor
+ getDescriptorForType() {
+ return akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.internal_static_akka_cluster_ddata_ORMapDeltaGroup_Entry_descriptor;
+ }
+
+ public akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry getDefaultInstanceForType() {
+ return akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry.getDefaultInstance();
+ }
+
+ public akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry build() {
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry result = buildPartial();
+ if (!result.isInitialized()) {
+ throw newUninitializedMessageException(result);
+ }
+ return result;
+ }
+
+ public akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry buildPartial() {
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry result = new akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry(this);
+ int from_bitField0_ = bitField0_;
+ int to_bitField0_ = 0;
+ if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+ to_bitField0_ |= 0x00000001;
+ }
+ result.operation_ = operation_;
+ if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+ to_bitField0_ |= 0x00000002;
+ }
+ if (underlyingBuilder_ == null) {
+ result.underlying_ = underlying_;
+ } else {
+ result.underlying_ = underlyingBuilder_.build();
+ }
+ if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+ to_bitField0_ |= 0x00000004;
+ }
+ result.zeroTag_ = zeroTag_;
+ if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
+ to_bitField0_ |= 0x00000008;
+ }
+ if (entryDataBuilder_ == null) {
+ result.entryData_ = entryData_;
+ } else {
+ result.entryData_ = entryDataBuilder_.build();
+ }
+ result.bitField0_ = to_bitField0_;
+ onBuilt();
+ return result;
+ }
+
+ public Builder mergeFrom(akka.protobuf.Message other) {
+ if (other instanceof akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry) {
+ return mergeFrom((akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry)other);
+ } else {
+ super.mergeFrom(other);
+ return this;
+ }
+ }
+
+ public Builder mergeFrom(akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry other) {
+ if (other == akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry.getDefaultInstance()) return this;
+ if (other.hasOperation()) {
+ setOperation(other.getOperation());
+ }
+ if (other.hasUnderlying()) {
+ mergeUnderlying(other.getUnderlying());
+ }
+ if (other.hasZeroTag()) {
+ setZeroTag(other.getZeroTag());
+ }
+ if (other.hasEntryData()) {
+ mergeEntryData(other.getEntryData());
+ }
+ this.mergeUnknownFields(other.getUnknownFields());
+ return this;
+ }
+
+ public final boolean isInitialized() {
+ if (!hasOperation()) {
+
+ return false;
+ }
+ if (!hasUnderlying()) {
+
+ return false;
+ }
+ if (!hasZeroTag()) {
+
+ return false;
+ }
+ if (!getUnderlying().isInitialized()) {
+
+ return false;
+ }
+ if (hasEntryData()) {
+ if (!getEntryData().isInitialized()) {
+
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public Builder mergeFrom(
+ akka.protobuf.CodedInputStream input,
+ akka.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry parsedMessage = null;
+ try {
+ parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+ } catch (akka.protobuf.InvalidProtocolBufferException e) {
+ parsedMessage = (akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry) e.getUnfinishedMessage();
+ throw e;
+ } finally {
+ if (parsedMessage != null) {
+ mergeFrom(parsedMessage);
+ }
+ }
+ return this;
+ }
+ private int bitField0_;
+
+ // required .akka.cluster.ddata.ORMapDeltaOp operation = 1;
+ private akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaOp operation_ = akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaOp.ORMapPut;
+ /**
+ * required .akka.cluster.ddata.ORMapDeltaOp operation = 1;
+ */
+ public boolean hasOperation() {
+ return ((bitField0_ & 0x00000001) == 0x00000001);
+ }
+ /**
+ * required .akka.cluster.ddata.ORMapDeltaOp operation = 1;
+ */
+ public akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaOp getOperation() {
+ return operation_;
+ }
+ /**
+ * required .akka.cluster.ddata.ORMapDeltaOp operation = 1;
+ */
+ public Builder setOperation(akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaOp value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000001;
+ operation_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * required .akka.cluster.ddata.ORMapDeltaOp operation = 1;
+ */
+ public Builder clearOperation() {
+ bitField0_ = (bitField0_ & ~0x00000001);
+ operation_ = akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaOp.ORMapPut;
+ onChanged();
+ return this;
+ }
+
+ // required .akka.cluster.ddata.ORSet underlying = 2;
+ private akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORSet underlying_ = akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORSet.getDefaultInstance();
+ private akka.protobuf.SingleFieldBuilder<
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORSet, akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORSet.Builder, akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORSetOrBuilder> underlyingBuilder_;
+ /**
+ * required .akka.cluster.ddata.ORSet underlying = 2;
+ */
+ public boolean hasUnderlying() {
+ return ((bitField0_ & 0x00000002) == 0x00000002);
+ }
+ /**
+ * required .akka.cluster.ddata.ORSet underlying = 2;
+ */
+ public akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORSet getUnderlying() {
+ if (underlyingBuilder_ == null) {
+ return underlying_;
+ } else {
+ return underlyingBuilder_.getMessage();
+ }
+ }
+ /**
+ * required .akka.cluster.ddata.ORSet underlying = 2;
+ */
+ public Builder setUnderlying(akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORSet value) {
+ if (underlyingBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ underlying_ = value;
+ onChanged();
+ } else {
+ underlyingBuilder_.setMessage(value);
+ }
+ bitField0_ |= 0x00000002;
+ return this;
+ }
+ /**
+ * required .akka.cluster.ddata.ORSet underlying = 2;
+ */
+ public Builder setUnderlying(
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORSet.Builder builderForValue) {
+ if (underlyingBuilder_ == null) {
+ underlying_ = builderForValue.build();
+ onChanged();
+ } else {
+ underlyingBuilder_.setMessage(builderForValue.build());
+ }
+ bitField0_ |= 0x00000002;
+ return this;
+ }
+ /**
+ * required .akka.cluster.ddata.ORSet underlying = 2;
+ */
+ public Builder mergeUnderlying(akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORSet value) {
+ if (underlyingBuilder_ == null) {
+ if (((bitField0_ & 0x00000002) == 0x00000002) &&
+ underlying_ != akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORSet.getDefaultInstance()) {
+ underlying_ =
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORSet.newBuilder(underlying_).mergeFrom(value).buildPartial();
+ } else {
+ underlying_ = value;
+ }
+ onChanged();
+ } else {
+ underlyingBuilder_.mergeFrom(value);
+ }
+ bitField0_ |= 0x00000002;
+ return this;
+ }
+ /**
+ * required .akka.cluster.ddata.ORSet underlying = 2;
+ */
+ public Builder clearUnderlying() {
+ if (underlyingBuilder_ == null) {
+ underlying_ = akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORSet.getDefaultInstance();
+ onChanged();
+ } else {
+ underlyingBuilder_.clear();
+ }
+ bitField0_ = (bitField0_ & ~0x00000002);
+ return this;
+ }
+ /**
+ * required .akka.cluster.ddata.ORSet underlying = 2;
+ */
+ public akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORSet.Builder getUnderlyingBuilder() {
+ bitField0_ |= 0x00000002;
+ onChanged();
+ return getUnderlyingFieldBuilder().getBuilder();
+ }
+ /**
+ * required .akka.cluster.ddata.ORSet underlying = 2;
+ */
+ public akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORSetOrBuilder getUnderlyingOrBuilder() {
+ if (underlyingBuilder_ != null) {
+ return underlyingBuilder_.getMessageOrBuilder();
+ } else {
+ return underlying_;
+ }
+ }
+ /**
+ * required .akka.cluster.ddata.ORSet underlying = 2;
+ */
+ private akka.protobuf.SingleFieldBuilder<
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORSet, akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORSet.Builder, akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORSetOrBuilder>
+ getUnderlyingFieldBuilder() {
+ if (underlyingBuilder_ == null) {
+ underlyingBuilder_ = new akka.protobuf.SingleFieldBuilder<
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORSet, akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORSet.Builder, akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORSetOrBuilder>(
+ underlying_,
+ getParentForChildren(),
+ isClean());
+ underlying_ = null;
+ }
+ return underlyingBuilder_;
+ }
+
+ // required sint32 zeroTag = 3;
+ private int zeroTag_ ;
+ /**
+ * required sint32 zeroTag = 3;
+ */
+ public boolean hasZeroTag() {
+ return ((bitField0_ & 0x00000004) == 0x00000004);
+ }
+ /**
+ * required sint32 zeroTag = 3;
+ */
+ public int getZeroTag() {
+ return zeroTag_;
+ }
+ /**
+ * required sint32 zeroTag = 3;
+ */
+ public Builder setZeroTag(int value) {
+ bitField0_ |= 0x00000004;
+ zeroTag_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * required sint32 zeroTag = 3;
+ */
+ public Builder clearZeroTag() {
+ bitField0_ = (bitField0_ & ~0x00000004);
+ zeroTag_ = 0;
+ onChanged();
+ return this;
+ }
+
+ // optional .akka.cluster.ddata.ORMapDeltaGroup.MapEntry entryData = 4;
+ private akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry entryData_ = akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry.getDefaultInstance();
+ private akka.protobuf.SingleFieldBuilder<
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry, akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry.Builder, akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntryOrBuilder> entryDataBuilder_;
+ /**
+ * optional .akka.cluster.ddata.ORMapDeltaGroup.MapEntry entryData = 4;
+ */
+ public boolean hasEntryData() {
+ return ((bitField0_ & 0x00000008) == 0x00000008);
+ }
+ /**
+ * optional .akka.cluster.ddata.ORMapDeltaGroup.MapEntry entryData = 4;
+ */
+ public akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry getEntryData() {
+ if (entryDataBuilder_ == null) {
+ return entryData_;
+ } else {
+ return entryDataBuilder_.getMessage();
+ }
+ }
+ /**
+ * optional .akka.cluster.ddata.ORMapDeltaGroup.MapEntry entryData = 4;
+ */
+ public Builder setEntryData(akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry value) {
+ if (entryDataBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ entryData_ = value;
+ onChanged();
+ } else {
+ entryDataBuilder_.setMessage(value);
+ }
+ bitField0_ |= 0x00000008;
+ return this;
+ }
+ /**
+ * optional .akka.cluster.ddata.ORMapDeltaGroup.MapEntry entryData = 4;
+ */
+ public Builder setEntryData(
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry.Builder builderForValue) {
+ if (entryDataBuilder_ == null) {
+ entryData_ = builderForValue.build();
+ onChanged();
+ } else {
+ entryDataBuilder_.setMessage(builderForValue.build());
+ }
+ bitField0_ |= 0x00000008;
+ return this;
+ }
+ /**
+ * optional .akka.cluster.ddata.ORMapDeltaGroup.MapEntry entryData = 4;
+ */
+ public Builder mergeEntryData(akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry value) {
+ if (entryDataBuilder_ == null) {
+ if (((bitField0_ & 0x00000008) == 0x00000008) &&
+ entryData_ != akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry.getDefaultInstance()) {
+ entryData_ =
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry.newBuilder(entryData_).mergeFrom(value).buildPartial();
+ } else {
+ entryData_ = value;
+ }
+ onChanged();
+ } else {
+ entryDataBuilder_.mergeFrom(value);
+ }
+ bitField0_ |= 0x00000008;
+ return this;
+ }
+ /**
+ * optional .akka.cluster.ddata.ORMapDeltaGroup.MapEntry entryData = 4;
+ */
+ public Builder clearEntryData() {
+ if (entryDataBuilder_ == null) {
+ entryData_ = akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry.getDefaultInstance();
+ onChanged();
+ } else {
+ entryDataBuilder_.clear();
+ }
+ bitField0_ = (bitField0_ & ~0x00000008);
+ return this;
+ }
+ /**
+ * optional .akka.cluster.ddata.ORMapDeltaGroup.MapEntry entryData = 4;
+ */
+ public akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry.Builder getEntryDataBuilder() {
+ bitField0_ |= 0x00000008;
+ onChanged();
+ return getEntryDataFieldBuilder().getBuilder();
+ }
+ /**
+ * optional .akka.cluster.ddata.ORMapDeltaGroup.MapEntry entryData = 4;
+ */
+ public akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntryOrBuilder getEntryDataOrBuilder() {
+ if (entryDataBuilder_ != null) {
+ return entryDataBuilder_.getMessageOrBuilder();
+ } else {
+ return entryData_;
+ }
+ }
+ /**
+ * optional .akka.cluster.ddata.ORMapDeltaGroup.MapEntry entryData = 4;
+ */
+ private akka.protobuf.SingleFieldBuilder<
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry, akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry.Builder, akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntryOrBuilder>
+ getEntryDataFieldBuilder() {
+ if (entryDataBuilder_ == null) {
+ entryDataBuilder_ = new akka.protobuf.SingleFieldBuilder<
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry, akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntry.Builder, akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.MapEntryOrBuilder>(
+ entryData_,
+ getParentForChildren(),
+ isClean());
+ entryData_ = null;
+ }
+ return entryDataBuilder_;
+ }
+
+ // @@protoc_insertion_point(builder_scope:akka.cluster.ddata.ORMapDeltaGroup.Entry)
+ }
+
+ static {
+ defaultInstance = new Entry(true);
+ defaultInstance.initFields();
+ }
+
+ // @@protoc_insertion_point(class_scope:akka.cluster.ddata.ORMapDeltaGroup.Entry)
+ }
+
+ // repeated .akka.cluster.ddata.ORMapDeltaGroup.Entry entries = 1;
+ public static final int ENTRIES_FIELD_NUMBER = 1;
+ private java.util.List entries_;
+ /**
+ * repeated .akka.cluster.ddata.ORMapDeltaGroup.Entry entries = 1;
+ */
+ public java.util.List getEntriesList() {
+ return entries_;
+ }
+ /**
+ * repeated .akka.cluster.ddata.ORMapDeltaGroup.Entry entries = 1;
+ */
+ public java.util.List extends akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.EntryOrBuilder>
+ getEntriesOrBuilderList() {
+ return entries_;
+ }
+ /**
+ * repeated .akka.cluster.ddata.ORMapDeltaGroup.Entry entries = 1;
+ */
+ public int getEntriesCount() {
+ return entries_.size();
+ }
+ /**
+ * repeated .akka.cluster.ddata.ORMapDeltaGroup.Entry entries = 1;
+ */
+ public akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry getEntries(int index) {
+ return entries_.get(index);
+ }
+ /**
+ * repeated .akka.cluster.ddata.ORMapDeltaGroup.Entry entries = 1;
+ */
+ public akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.EntryOrBuilder getEntriesOrBuilder(
+ int index) {
+ return entries_.get(index);
+ }
+
+ private void initFields() {
+ entries_ = java.util.Collections.emptyList();
+ }
+ private byte memoizedIsInitialized = -1;
+ public final boolean isInitialized() {
+ byte isInitialized = memoizedIsInitialized;
+ if (isInitialized != -1) return isInitialized == 1;
+
+ for (int i = 0; i < getEntriesCount(); i++) {
+ if (!getEntries(i).isInitialized()) {
+ memoizedIsInitialized = 0;
+ return false;
+ }
+ }
+ memoizedIsInitialized = 1;
+ return true;
+ }
+
+ public void writeTo(akka.protobuf.CodedOutputStream output)
+ throws java.io.IOException {
+ getSerializedSize();
+ for (int i = 0; i < entries_.size(); i++) {
+ output.writeMessage(1, entries_.get(i));
+ }
+ getUnknownFields().writeTo(output);
+ }
+
+ private int memoizedSerializedSize = -1;
+ public int getSerializedSize() {
+ int size = memoizedSerializedSize;
+ if (size != -1) return size;
+
+ size = 0;
+ for (int i = 0; i < entries_.size(); i++) {
+ size += akka.protobuf.CodedOutputStream
+ .computeMessageSize(1, entries_.get(i));
+ }
+ size += getUnknownFields().getSerializedSize();
+ memoizedSerializedSize = size;
+ return size;
+ }
+
+ private static final long serialVersionUID = 0L;
+ @java.lang.Override
+ protected java.lang.Object writeReplace()
+ throws java.io.ObjectStreamException {
+ return super.writeReplace();
+ }
+
+ public static akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup parseFrom(
+ akka.protobuf.ByteString data)
+ throws akka.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup parseFrom(
+ akka.protobuf.ByteString data,
+ akka.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws akka.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup parseFrom(byte[] data)
+ throws akka.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup parseFrom(
+ byte[] data,
+ akka.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws akka.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup parseFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input);
+ }
+ public static akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup parseFrom(
+ java.io.InputStream input,
+ akka.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input, extensionRegistry);
+ }
+ public static akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup parseDelimitedFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return PARSER.parseDelimitedFrom(input);
+ }
+ public static akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup parseDelimitedFrom(
+ java.io.InputStream input,
+ akka.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseDelimitedFrom(input, extensionRegistry);
+ }
+ public static akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup parseFrom(
+ akka.protobuf.CodedInputStream input)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input);
+ }
+ public static akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup parseFrom(
+ akka.protobuf.CodedInputStream input,
+ akka.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input, extensionRegistry);
+ }
+
+ public static Builder newBuilder() { return Builder.create(); }
+ public Builder newBuilderForType() { return newBuilder(); }
+ public static Builder newBuilder(akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup prototype) {
+ return newBuilder().mergeFrom(prototype);
+ }
+ public Builder toBuilder() { return newBuilder(this); }
+
+ @java.lang.Override
+ protected Builder newBuilderForType(
+ akka.protobuf.GeneratedMessage.BuilderParent parent) {
+ Builder builder = new Builder(parent);
+ return builder;
+ }
+ /**
+ * Protobuf type {@code akka.cluster.ddata.ORMapDeltaGroup}
+ */
+ public static final class Builder extends
+ akka.protobuf.GeneratedMessage.Builder
+ implements akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroupOrBuilder {
+ public static final akka.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.internal_static_akka_cluster_ddata_ORMapDeltaGroup_descriptor;
+ }
+
+ protected akka.protobuf.GeneratedMessage.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.internal_static_akka_cluster_ddata_ORMapDeltaGroup_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.class, akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Builder.class);
+ }
+
+ // Construct using akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.newBuilder()
+ private Builder() {
+ maybeForceBuilderInitialization();
+ }
+
+ private Builder(
+ akka.protobuf.GeneratedMessage.BuilderParent parent) {
+ super(parent);
+ maybeForceBuilderInitialization();
+ }
+ private void maybeForceBuilderInitialization() {
+ if (akka.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+ getEntriesFieldBuilder();
+ }
+ }
+ private static Builder create() {
+ return new Builder();
+ }
+
+ public Builder clear() {
+ super.clear();
+ if (entriesBuilder_ == null) {
+ entries_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000001);
+ } else {
+ entriesBuilder_.clear();
+ }
+ return this;
+ }
+
+ public Builder clone() {
+ return create().mergeFrom(buildPartial());
+ }
+
+ public akka.protobuf.Descriptors.Descriptor
+ getDescriptorForType() {
+ return akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.internal_static_akka_cluster_ddata_ORMapDeltaGroup_descriptor;
+ }
+
+ public akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup getDefaultInstanceForType() {
+ return akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.getDefaultInstance();
+ }
+
+ public akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup build() {
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup result = buildPartial();
+ if (!result.isInitialized()) {
+ throw newUninitializedMessageException(result);
+ }
+ return result;
+ }
+
+ public akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup buildPartial() {
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup result = new akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup(this);
+ int from_bitField0_ = bitField0_;
+ if (entriesBuilder_ == null) {
+ if (((bitField0_ & 0x00000001) == 0x00000001)) {
+ entries_ = java.util.Collections.unmodifiableList(entries_);
+ bitField0_ = (bitField0_ & ~0x00000001);
+ }
+ result.entries_ = entries_;
+ } else {
+ result.entries_ = entriesBuilder_.build();
+ }
+ onBuilt();
+ return result;
+ }
+
+ public Builder mergeFrom(akka.protobuf.Message other) {
+ if (other instanceof akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup) {
+ return mergeFrom((akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup)other);
+ } else {
+ super.mergeFrom(other);
+ return this;
+ }
+ }
+
+ public Builder mergeFrom(akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup other) {
+ if (other == akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.getDefaultInstance()) return this;
+ if (entriesBuilder_ == null) {
+ if (!other.entries_.isEmpty()) {
+ if (entries_.isEmpty()) {
+ entries_ = other.entries_;
+ bitField0_ = (bitField0_ & ~0x00000001);
+ } else {
+ ensureEntriesIsMutable();
+ entries_.addAll(other.entries_);
+ }
+ onChanged();
+ }
+ } else {
+ if (!other.entries_.isEmpty()) {
+ if (entriesBuilder_.isEmpty()) {
+ entriesBuilder_.dispose();
+ entriesBuilder_ = null;
+ entries_ = other.entries_;
+ bitField0_ = (bitField0_ & ~0x00000001);
+ entriesBuilder_ =
+ akka.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
+ getEntriesFieldBuilder() : null;
+ } else {
+ entriesBuilder_.addAllMessages(other.entries_);
+ }
+ }
+ }
+ this.mergeUnknownFields(other.getUnknownFields());
+ return this;
+ }
+
+ public final boolean isInitialized() {
+ for (int i = 0; i < getEntriesCount(); i++) {
+ if (!getEntries(i).isInitialized()) {
+
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public Builder mergeFrom(
+ akka.protobuf.CodedInputStream input,
+ akka.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup parsedMessage = null;
+ try {
+ parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+ } catch (akka.protobuf.InvalidProtocolBufferException e) {
+ parsedMessage = (akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup) e.getUnfinishedMessage();
+ throw e;
+ } finally {
+ if (parsedMessage != null) {
+ mergeFrom(parsedMessage);
+ }
+ }
+ return this;
+ }
+ private int bitField0_;
+
+ // repeated .akka.cluster.ddata.ORMapDeltaGroup.Entry entries = 1;
+ private java.util.List entries_ =
+ java.util.Collections.emptyList();
+ private void ensureEntriesIsMutable() {
+ if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+ entries_ = new java.util.ArrayList(entries_);
+ bitField0_ |= 0x00000001;
+ }
+ }
+
+ private akka.protobuf.RepeatedFieldBuilder<
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry, akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry.Builder, akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.EntryOrBuilder> entriesBuilder_;
+
+ /**
+ * repeated .akka.cluster.ddata.ORMapDeltaGroup.Entry entries = 1;
+ */
+ public java.util.List getEntriesList() {
+ if (entriesBuilder_ == null) {
+ return java.util.Collections.unmodifiableList(entries_);
+ } else {
+ return entriesBuilder_.getMessageList();
+ }
+ }
+ /**
+ * repeated .akka.cluster.ddata.ORMapDeltaGroup.Entry entries = 1;
+ */
+ public int getEntriesCount() {
+ if (entriesBuilder_ == null) {
+ return entries_.size();
+ } else {
+ return entriesBuilder_.getCount();
+ }
+ }
+ /**
+ * repeated .akka.cluster.ddata.ORMapDeltaGroup.Entry entries = 1;
+ */
+ public akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry getEntries(int index) {
+ if (entriesBuilder_ == null) {
+ return entries_.get(index);
+ } else {
+ return entriesBuilder_.getMessage(index);
+ }
+ }
+ /**
+ * repeated .akka.cluster.ddata.ORMapDeltaGroup.Entry entries = 1;
+ */
+ public Builder setEntries(
+ int index, akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry value) {
+ if (entriesBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureEntriesIsMutable();
+ entries_.set(index, value);
+ onChanged();
+ } else {
+ entriesBuilder_.setMessage(index, value);
+ }
+ return this;
+ }
+ /**
+ * repeated .akka.cluster.ddata.ORMapDeltaGroup.Entry entries = 1;
+ */
+ public Builder setEntries(
+ int index, akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry.Builder builderForValue) {
+ if (entriesBuilder_ == null) {
+ ensureEntriesIsMutable();
+ entries_.set(index, builderForValue.build());
+ onChanged();
+ } else {
+ entriesBuilder_.setMessage(index, builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * repeated .akka.cluster.ddata.ORMapDeltaGroup.Entry entries = 1;
+ */
+ public Builder addEntries(akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry value) {
+ if (entriesBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureEntriesIsMutable();
+ entries_.add(value);
+ onChanged();
+ } else {
+ entriesBuilder_.addMessage(value);
+ }
+ return this;
+ }
+ /**
+ * repeated .akka.cluster.ddata.ORMapDeltaGroup.Entry entries = 1;
+ */
+ public Builder addEntries(
+ int index, akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry value) {
+ if (entriesBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ ensureEntriesIsMutable();
+ entries_.add(index, value);
+ onChanged();
+ } else {
+ entriesBuilder_.addMessage(index, value);
+ }
+ return this;
+ }
+ /**
+ * repeated .akka.cluster.ddata.ORMapDeltaGroup.Entry entries = 1;
+ */
+ public Builder addEntries(
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry.Builder builderForValue) {
+ if (entriesBuilder_ == null) {
+ ensureEntriesIsMutable();
+ entries_.add(builderForValue.build());
+ onChanged();
+ } else {
+ entriesBuilder_.addMessage(builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * repeated .akka.cluster.ddata.ORMapDeltaGroup.Entry entries = 1;
+ */
+ public Builder addEntries(
+ int index, akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry.Builder builderForValue) {
+ if (entriesBuilder_ == null) {
+ ensureEntriesIsMutable();
+ entries_.add(index, builderForValue.build());
+ onChanged();
+ } else {
+ entriesBuilder_.addMessage(index, builderForValue.build());
+ }
+ return this;
+ }
+ /**
+ * repeated .akka.cluster.ddata.ORMapDeltaGroup.Entry entries = 1;
+ */
+ public Builder addAllEntries(
+ java.lang.Iterable extends akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry> values) {
+ if (entriesBuilder_ == null) {
+ ensureEntriesIsMutable();
+ super.addAll(values, entries_);
+ onChanged();
+ } else {
+ entriesBuilder_.addAllMessages(values);
+ }
+ return this;
+ }
+ /**
+ * repeated .akka.cluster.ddata.ORMapDeltaGroup.Entry entries = 1;
+ */
+ public Builder clearEntries() {
+ if (entriesBuilder_ == null) {
+ entries_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000001);
+ onChanged();
+ } else {
+ entriesBuilder_.clear();
+ }
+ return this;
+ }
+ /**
+ * repeated .akka.cluster.ddata.ORMapDeltaGroup.Entry entries = 1;
+ */
+ public Builder removeEntries(int index) {
+ if (entriesBuilder_ == null) {
+ ensureEntriesIsMutable();
+ entries_.remove(index);
+ onChanged();
+ } else {
+ entriesBuilder_.remove(index);
+ }
+ return this;
+ }
+ /**
+ * repeated .akka.cluster.ddata.ORMapDeltaGroup.Entry entries = 1;
+ */
+ public akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry.Builder getEntriesBuilder(
+ int index) {
+ return getEntriesFieldBuilder().getBuilder(index);
+ }
+ /**
+ * repeated .akka.cluster.ddata.ORMapDeltaGroup.Entry entries = 1;
+ */
+ public akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.EntryOrBuilder getEntriesOrBuilder(
+ int index) {
+ if (entriesBuilder_ == null) {
+ return entries_.get(index); } else {
+ return entriesBuilder_.getMessageOrBuilder(index);
+ }
+ }
+ /**
+ * repeated .akka.cluster.ddata.ORMapDeltaGroup.Entry entries = 1;
+ */
+ public java.util.List extends akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.EntryOrBuilder>
+ getEntriesOrBuilderList() {
+ if (entriesBuilder_ != null) {
+ return entriesBuilder_.getMessageOrBuilderList();
+ } else {
+ return java.util.Collections.unmodifiableList(entries_);
+ }
+ }
+ /**
+ * repeated .akka.cluster.ddata.ORMapDeltaGroup.Entry entries = 1;
+ */
+ public akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry.Builder addEntriesBuilder() {
+ return getEntriesFieldBuilder().addBuilder(
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry.getDefaultInstance());
+ }
+ /**
+ * repeated .akka.cluster.ddata.ORMapDeltaGroup.Entry entries = 1;
+ */
+ public akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry.Builder addEntriesBuilder(
+ int index) {
+ return getEntriesFieldBuilder().addBuilder(
+ index, akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry.getDefaultInstance());
+ }
+ /**
+ * repeated .akka.cluster.ddata.ORMapDeltaGroup.Entry entries = 1;
+ */
+ public java.util.List
+ getEntriesBuilderList() {
+ return getEntriesFieldBuilder().getBuilderList();
+ }
+ private akka.protobuf.RepeatedFieldBuilder<
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry, akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry.Builder, akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.EntryOrBuilder>
+ getEntriesFieldBuilder() {
+ if (entriesBuilder_ == null) {
+ entriesBuilder_ = new akka.protobuf.RepeatedFieldBuilder<
+ akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry, akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.Entry.Builder, akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMapDeltaGroup.EntryOrBuilder>(
+ entries_,
+ ((bitField0_ & 0x00000001) == 0x00000001),
+ getParentForChildren(),
+ isClean());
+ entries_ = null;
+ }
+ return entriesBuilder_;
+ }
+
+ // @@protoc_insertion_point(builder_scope:akka.cluster.ddata.ORMapDeltaGroup)
+ }
+
+ static {
+ defaultInstance = new ORMapDeltaGroup(true);
+ defaultInstance.initFields();
+ }
+
+ // @@protoc_insertion_point(class_scope:akka.cluster.ddata.ORMapDeltaGroup)
+ }
+
public interface LWWMapOrBuilder
extends akka.protobuf.MessageOrBuilder {
@@ -13524,6 +16269,16 @@ public final class ReplicatedDataMessages {
*/
akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMultiMap.EntryOrBuilder getEntriesOrBuilder(
int index);
+
+ // optional bool withValueDeltas = 3;
+ /**
+ * optional bool withValueDeltas = 3;
+ */
+ boolean hasWithValueDeltas();
+ /**
+ * optional bool withValueDeltas = 3;
+ */
+ boolean getWithValueDeltas();
}
/**
* Protobuf type {@code akka.cluster.ddata.ORMultiMap}
@@ -13597,6 +16352,11 @@ public final class ReplicatedDataMessages {
entries_.add(input.readMessage(akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORMultiMap.Entry.PARSER, extensionRegistry));
break;
}
+ case 24: {
+ bitField0_ |= 0x00000002;
+ withValueDeltas_ = input.readBool();
+ break;
+ }
}
}
} catch (akka.protobuf.InvalidProtocolBufferException e) {
@@ -14743,9 +17503,26 @@ public final class ReplicatedDataMessages {
return entries_.get(index);
}
+ // optional bool withValueDeltas = 3;
+ public static final int WITHVALUEDELTAS_FIELD_NUMBER = 3;
+ private boolean withValueDeltas_;
+ /**
+ * optional bool withValueDeltas = 3;
+ */
+ public boolean hasWithValueDeltas() {
+ return ((bitField0_ & 0x00000002) == 0x00000002);
+ }
+ /**
+ * optional bool withValueDeltas = 3;
+ */
+ public boolean getWithValueDeltas() {
+ return withValueDeltas_;
+ }
+
private void initFields() {
keys_ = akka.cluster.ddata.protobuf.msg.ReplicatedDataMessages.ORSet.getDefaultInstance();
entries_ = java.util.Collections.emptyList();
+ withValueDeltas_ = false;
}
private byte memoizedIsInitialized = -1;
public final boolean isInitialized() {
@@ -14779,6 +17556,9 @@ public final class ReplicatedDataMessages {
for (int i = 0; i < entries_.size(); i++) {
output.writeMessage(2, entries_.get(i));
}
+ if (((bitField0_ & 0x00000002) == 0x00000002)) {
+ output.writeBool(3, withValueDeltas_);
+ }
getUnknownFields().writeTo(output);
}
@@ -14796,6 +17576,10 @@ public final class ReplicatedDataMessages {
size += akka.protobuf.CodedOutputStream
.computeMessageSize(2, entries_.get(i));
}
+ if (((bitField0_ & 0x00000002) == 0x00000002)) {
+ size += akka.protobuf.CodedOutputStream
+ .computeBoolSize(3, withValueDeltas_);
+ }
size += getUnknownFields().getSerializedSize();
memoizedSerializedSize = size;
return size;
@@ -14926,6 +17710,8 @@ public final class ReplicatedDataMessages {
} else {
entriesBuilder_.clear();
}
+ withValueDeltas_ = false;
+ bitField0_ = (bitField0_ & ~0x00000004);
return this;
}
@@ -14971,6 +17757,10 @@ public final class ReplicatedDataMessages {
} else {
result.entries_ = entriesBuilder_.build();
}
+ if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+ to_bitField0_ |= 0x00000002;
+ }
+ result.withValueDeltas_ = withValueDeltas_;
result.bitField0_ = to_bitField0_;
onBuilt();
return result;
@@ -15016,6 +17806,9 @@ public final class ReplicatedDataMessages {
}
}
}
+ if (other.hasWithValueDeltas()) {
+ setWithValueDeltas(other.getWithValueDeltas());
+ }
this.mergeUnknownFields(other.getUnknownFields());
return this;
}
@@ -15414,6 +18207,39 @@ public final class ReplicatedDataMessages {
return entriesBuilder_;
}
+ // optional bool withValueDeltas = 3;
+ private boolean withValueDeltas_ ;
+ /**
+ * optional bool withValueDeltas = 3;
+ */
+ public boolean hasWithValueDeltas() {
+ return ((bitField0_ & 0x00000004) == 0x00000004);
+ }
+ /**
+ * optional bool withValueDeltas = 3;
+ */
+ public boolean getWithValueDeltas() {
+ return withValueDeltas_;
+ }
+ /**
+ * optional bool withValueDeltas = 3;
+ */
+ public Builder setWithValueDeltas(boolean value) {
+ bitField0_ |= 0x00000004;
+ withValueDeltas_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * optional bool withValueDeltas = 3;
+ */
+ public Builder clearWithValueDeltas() {
+ bitField0_ = (bitField0_ & ~0x00000004);
+ withValueDeltas_ = false;
+ onChanged();
+ return this;
+ }
+
// @@protoc_insertion_point(builder_scope:akka.cluster.ddata.ORMultiMap)
}
@@ -15480,6 +18306,21 @@ public final class ReplicatedDataMessages {
private static
akka.protobuf.GeneratedMessage.FieldAccessorTable
internal_static_akka_cluster_ddata_ORMap_Entry_fieldAccessorTable;
+ private static akka.protobuf.Descriptors.Descriptor
+ internal_static_akka_cluster_ddata_ORMapDeltaGroup_descriptor;
+ private static
+ akka.protobuf.GeneratedMessage.FieldAccessorTable
+ internal_static_akka_cluster_ddata_ORMapDeltaGroup_fieldAccessorTable;
+ private static akka.protobuf.Descriptors.Descriptor
+ internal_static_akka_cluster_ddata_ORMapDeltaGroup_MapEntry_descriptor;
+ private static
+ akka.protobuf.GeneratedMessage.FieldAccessorTable
+ internal_static_akka_cluster_ddata_ORMapDeltaGroup_MapEntry_fieldAccessorTable;
+ private static akka.protobuf.Descriptors.Descriptor
+ internal_static_akka_cluster_ddata_ORMapDeltaGroup_Entry_descriptor;
+ private static
+ akka.protobuf.GeneratedMessage.FieldAccessorTable
+ internal_static_akka_cluster_ddata_ORMapDeltaGroup_Entry_fieldAccessorTable;
private static akka.protobuf.Descriptors.Descriptor
internal_static_akka_cluster_ddata_LWWMap_descriptor;
private static
@@ -15552,29 +18393,43 @@ public final class ReplicatedDataMessages {
" \002(\0132 .akka.cluster.ddata.OtherMessage\022\016" +
"\n\006intKey\030\003 \001(\021\022\017\n\007longKey\030\004 \001(\022\0222\n\010other" +
"Key\030\005 \001(\0132 .akka.cluster.ddata.OtherMess" +
- "age\"\206\002\n\006LWWMap\022\'\n\004keys\030\001 \002(\0132\031.akka.clus" +
- "ter.ddata.ORSet\0221\n\007entries\030\002 \003(\0132 .akka." +
- "cluster.ddata.LWWMap.Entry\032\237\001\n\005Entry\022\021\n\t" +
- "stringKey\030\001 \001(\t\022.\n\005value\030\002 \002(\0132\037.akka.cl" +
- "uster.ddata.LWWRegister\022\016\n\006intKey\030\003 \001(\021\022" +
- "\017\n\007longKey\030\004 \001(\022\0222\n\010otherKey\030\005 \001(\0132 .akk" +
- "a.cluster.ddata.OtherMessage\"\220\002\n\014PNCount",
- "erMap\022\'\n\004keys\030\001 \002(\0132\031.akka.cluster.ddata" +
- ".ORSet\0227\n\007entries\030\002 \003(\0132&.akka.cluster.d" +
- "data.PNCounterMap.Entry\032\235\001\n\005Entry\022\021\n\tstr" +
- "ingKey\030\001 \001(\t\022,\n\005value\030\002 \002(\0132\035.akka.clust" +
- "er.ddata.PNCounter\022\016\n\006intKey\030\003 \001(\021\022\017\n\007lo" +
- "ngKey\030\004 \001(\022\0222\n\010otherKey\030\005 \001(\0132 .akka.clu" +
- "ster.ddata.OtherMessage\"\210\002\n\nORMultiMap\022\'" +
- "\n\004keys\030\001 \002(\0132\031.akka.cluster.ddata.ORSet\022" +
- "5\n\007entries\030\002 \003(\0132$.akka.cluster.ddata.OR" +
- "MultiMap.Entry\032\231\001\n\005Entry\022\021\n\tstringKey\030\001 ",
- "\001(\t\022(\n\005value\030\002 \002(\0132\031.akka.cluster.ddata." +
- "ORSet\022\016\n\006intKey\030\003 \001(\021\022\017\n\007longKey\030\004 \001(\022\0222" +
- "\n\010otherKey\030\005 \001(\0132 .akka.cluster.ddata.Ot" +
- "herMessage*-\n\014ORSetDeltaOp\022\007\n\003Add\020\000\022\n\n\006R" +
- "emove\020\001\022\010\n\004Full\020\002B#\n\037akka.cluster.ddata." +
- "protobuf.msgH\001"
+ "age\"\263\003\n\017ORMapDeltaGroup\022:\n\007entries\030\001 \003(\013" +
+ "2).akka.cluster.ddata.ORMapDeltaGroup.En" +
+ "try\032\243\001\n\010MapEntry\022\021\n\tstringKey\030\001 \001(\t\022/\n\005v" +
+ "alue\030\002 \002(\0132 .akka.cluster.ddata.OtherMes" +
+ "sage\022\016\n\006intKey\030\003 \001(\021\022\017\n\007longKey\030\004 \001(\022\0222\n" +
+ "\010otherKey\030\005 \001(\0132 .akka.cluster.ddata.Oth" +
+ "erMessage\032\275\001\n\005Entry\0223\n\toperation\030\001 \002(\0162 ",
+ ".akka.cluster.ddata.ORMapDeltaOp\022-\n\nunde" +
+ "rlying\030\002 \002(\0132\031.akka.cluster.ddata.ORSet\022" +
+ "\017\n\007zeroTag\030\003 \002(\021\022?\n\tentryData\030\004 \001(\0132,.ak" +
+ "ka.cluster.ddata.ORMapDeltaGroup.MapEntr" +
+ "y\"\206\002\n\006LWWMap\022\'\n\004keys\030\001 \002(\0132\031.akka.cluste" +
+ "r.ddata.ORSet\0221\n\007entries\030\002 \003(\0132 .akka.cl" +
+ "uster.ddata.LWWMap.Entry\032\237\001\n\005Entry\022\021\n\tst" +
+ "ringKey\030\001 \001(\t\022.\n\005value\030\002 \002(\0132\037.akka.clus" +
+ "ter.ddata.LWWRegister\022\016\n\006intKey\030\003 \001(\021\022\017\n" +
+ "\007longKey\030\004 \001(\022\0222\n\010otherKey\030\005 \001(\0132 .akka.",
+ "cluster.ddata.OtherMessage\"\220\002\n\014PNCounter" +
+ "Map\022\'\n\004keys\030\001 \002(\0132\031.akka.cluster.ddata.O" +
+ "RSet\0227\n\007entries\030\002 \003(\0132&.akka.cluster.dda" +
+ "ta.PNCounterMap.Entry\032\235\001\n\005Entry\022\021\n\tstrin" +
+ "gKey\030\001 \001(\t\022,\n\005value\030\002 \002(\0132\035.akka.cluster" +
+ ".ddata.PNCounter\022\016\n\006intKey\030\003 \001(\021\022\017\n\007long" +
+ "Key\030\004 \001(\022\0222\n\010otherKey\030\005 \001(\0132 .akka.clust" +
+ "er.ddata.OtherMessage\"\241\002\n\nORMultiMap\022\'\n\004" +
+ "keys\030\001 \002(\0132\031.akka.cluster.ddata.ORSet\0225\n" +
+ "\007entries\030\002 \003(\0132$.akka.cluster.ddata.ORMu",
+ "ltiMap.Entry\022\027\n\017withValueDeltas\030\003 \001(\010\032\231\001" +
+ "\n\005Entry\022\021\n\tstringKey\030\001 \001(\t\022(\n\005value\030\002 \002(" +
+ "\0132\031.akka.cluster.ddata.ORSet\022\016\n\006intKey\030\003" +
+ " \001(\021\022\017\n\007longKey\030\004 \001(\022\0222\n\010otherKey\030\005 \001(\0132" +
+ " .akka.cluster.ddata.OtherMessage*-\n\014ORS" +
+ "etDeltaOp\022\007\n\003Add\020\000\022\n\n\006Remove\020\001\022\010\n\004Full\020\002" +
+ "*R\n\014ORMapDeltaOp\022\014\n\010ORMapPut\020\000\022\017\n\013ORMapR" +
+ "emove\020\001\022\022\n\016ORMapRemoveKey\020\002\022\017\n\013ORMapUpda" +
+ "te\020\003B#\n\037akka.cluster.ddata.protobuf.msgH" +
+ "\001"
};
akka.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
new akka.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
@@ -15647,8 +18502,26 @@ public final class ReplicatedDataMessages {
akka.protobuf.GeneratedMessage.FieldAccessorTable(
internal_static_akka_cluster_ddata_ORMap_Entry_descriptor,
new java.lang.String[] { "StringKey", "Value", "IntKey", "LongKey", "OtherKey", });
- internal_static_akka_cluster_ddata_LWWMap_descriptor =
+ internal_static_akka_cluster_ddata_ORMapDeltaGroup_descriptor =
getDescriptor().getMessageTypes().get(8);
+ internal_static_akka_cluster_ddata_ORMapDeltaGroup_fieldAccessorTable = new
+ akka.protobuf.GeneratedMessage.FieldAccessorTable(
+ internal_static_akka_cluster_ddata_ORMapDeltaGroup_descriptor,
+ new java.lang.String[] { "Entries", });
+ internal_static_akka_cluster_ddata_ORMapDeltaGroup_MapEntry_descriptor =
+ internal_static_akka_cluster_ddata_ORMapDeltaGroup_descriptor.getNestedTypes().get(0);
+ internal_static_akka_cluster_ddata_ORMapDeltaGroup_MapEntry_fieldAccessorTable = new
+ akka.protobuf.GeneratedMessage.FieldAccessorTable(
+ internal_static_akka_cluster_ddata_ORMapDeltaGroup_MapEntry_descriptor,
+ new java.lang.String[] { "StringKey", "Value", "IntKey", "LongKey", "OtherKey", });
+ internal_static_akka_cluster_ddata_ORMapDeltaGroup_Entry_descriptor =
+ internal_static_akka_cluster_ddata_ORMapDeltaGroup_descriptor.getNestedTypes().get(1);
+ internal_static_akka_cluster_ddata_ORMapDeltaGroup_Entry_fieldAccessorTable = new
+ akka.protobuf.GeneratedMessage.FieldAccessorTable(
+ internal_static_akka_cluster_ddata_ORMapDeltaGroup_Entry_descriptor,
+ new java.lang.String[] { "Operation", "Underlying", "ZeroTag", "EntryData", });
+ internal_static_akka_cluster_ddata_LWWMap_descriptor =
+ getDescriptor().getMessageTypes().get(9);
internal_static_akka_cluster_ddata_LWWMap_fieldAccessorTable = new
akka.protobuf.GeneratedMessage.FieldAccessorTable(
internal_static_akka_cluster_ddata_LWWMap_descriptor,
@@ -15660,7 +18533,7 @@ public final class ReplicatedDataMessages {
internal_static_akka_cluster_ddata_LWWMap_Entry_descriptor,
new java.lang.String[] { "StringKey", "Value", "IntKey", "LongKey", "OtherKey", });
internal_static_akka_cluster_ddata_PNCounterMap_descriptor =
- getDescriptor().getMessageTypes().get(9);
+ getDescriptor().getMessageTypes().get(10);
internal_static_akka_cluster_ddata_PNCounterMap_fieldAccessorTable = new
akka.protobuf.GeneratedMessage.FieldAccessorTable(
internal_static_akka_cluster_ddata_PNCounterMap_descriptor,
@@ -15672,11 +18545,11 @@ public final class ReplicatedDataMessages {
internal_static_akka_cluster_ddata_PNCounterMap_Entry_descriptor,
new java.lang.String[] { "StringKey", "Value", "IntKey", "LongKey", "OtherKey", });
internal_static_akka_cluster_ddata_ORMultiMap_descriptor =
- getDescriptor().getMessageTypes().get(10);
+ getDescriptor().getMessageTypes().get(11);
internal_static_akka_cluster_ddata_ORMultiMap_fieldAccessorTable = new
akka.protobuf.GeneratedMessage.FieldAccessorTable(
internal_static_akka_cluster_ddata_ORMultiMap_descriptor,
- new java.lang.String[] { "Keys", "Entries", });
+ new java.lang.String[] { "Keys", "Entries", "WithValueDeltas", });
internal_static_akka_cluster_ddata_ORMultiMap_Entry_descriptor =
internal_static_akka_cluster_ddata_ORMultiMap_descriptor.getNestedTypes().get(0);
internal_static_akka_cluster_ddata_ORMultiMap_Entry_fieldAccessorTable = new
diff --git a/akka-distributed-data/src/main/protobuf/ReplicatedDataMessages.proto b/akka-distributed-data/src/main/protobuf/ReplicatedDataMessages.proto
index 6a5020923c..33efe55f5a 100644
--- a/akka-distributed-data/src/main/protobuf/ReplicatedDataMessages.proto
+++ b/akka-distributed-data/src/main/protobuf/ReplicatedDataMessages.proto
@@ -72,7 +72,32 @@ message ORMap {
}
required ORSet keys = 1;
- repeated Entry entries = 2;
+ repeated Entry entries = 2;
+}
+
+message ORMapDeltaGroup {
+ message MapEntry {
+ optional string stringKey = 1;
+ required OtherMessage value = 2;
+ optional sint32 intKey = 3;
+ optional sint64 longKey = 4;
+ optional OtherMessage otherKey = 5;
+ }
+ message Entry {
+ required ORMapDeltaOp operation = 1;
+ required ORSet underlying = 2;
+ required sint32 zeroTag = 3;
+ optional MapEntry entryData = 4;
+ }
+
+ repeated Entry entries = 1;
+}
+
+enum ORMapDeltaOp {
+ ORMapPut = 0;
+ ORMapRemove = 1;
+ ORMapRemoveKey = 2;
+ ORMapUpdate = 3;
}
message LWWMap {
@@ -85,7 +110,7 @@ message LWWMap {
}
required ORSet keys = 1;
- repeated Entry entries = 2;
+ repeated Entry entries = 2;
}
message PNCounterMap {
@@ -98,21 +123,22 @@ message PNCounterMap {
}
required ORSet keys = 1;
- repeated Entry entries = 2;
+ repeated Entry entries = 2;
}
message ORMultiMap {
- message Entry {
- optional string stringKey = 1;
- required ORSet value = 2;
- optional sint32 intKey = 3;
- optional sint64 longKey = 4;
- optional OtherMessage otherKey = 5;
- }
-
- required ORSet keys = 1;
- repeated Entry entries = 2;
-}
+ message Entry {
+ optional string stringKey = 1;
+ required ORSet value = 2;
+ optional sint32 intKey = 3;
+ optional sint64 longKey = 4;
+ optional OtherMessage otherKey = 5;
+ }
+
+ required ORSet keys = 1;
+ repeated Entry entries = 2;
+ optional bool withValueDeltas = 3;
+ }
diff --git a/akka-distributed-data/src/main/scala/akka/cluster/ddata/LWWMap.scala b/akka-distributed-data/src/main/scala/akka/cluster/ddata/LWWMap.scala
index e36a521757..2af60a8aad 100644
--- a/akka-distributed-data/src/main/scala/akka/cluster/ddata/LWWMap.scala
+++ b/akka-distributed-data/src/main/scala/akka/cluster/ddata/LWWMap.scala
@@ -6,9 +6,10 @@ package akka.cluster.ddata
import akka.cluster.Cluster
import akka.cluster.UniqueAddress
import akka.annotation.InternalApi
+import akka.cluster.ddata.ORMap.LWWMapTag
object LWWMap {
- private val _empty: LWWMap[Any, Any] = new LWWMap(ORMap.empty)
+ private val _empty: LWWMap[Any, Any] = new LWWMap(ORMap.emptyWithLWWMapTag)
def empty[A, B]: LWWMap[A, B] = _empty.asInstanceOf[LWWMap[A, B]]
def apply(): LWWMap[Any, Any] = _empty
/**
@@ -47,10 +48,11 @@ object LWWMap {
@SerialVersionUID(1L)
final class LWWMap[A, B] private[akka] (
private[akka] val underlying: ORMap[A, LWWRegister[B]])
- extends ReplicatedData with ReplicatedDataSerialization with RemovedNodePruning {
+ extends DeltaReplicatedData with ReplicatedDataSerialization with RemovedNodePruning {
import LWWRegister.{ Clock, defaultClock }
type T = LWWMap[A, B]
+ type D = ORMap.DeltaOp
/**
* Scala API: All entries of the map.
@@ -141,6 +143,14 @@ final class LWWMap[A, B] private[akka] (
@InternalApi private[akka] def remove(node: UniqueAddress, key: A): LWWMap[A, B] =
new LWWMap(underlying.remove(node, key))
+ override def resetDelta: LWWMap[A, B] =
+ new LWWMap(underlying.resetDelta)
+
+ override def delta: Option[D] = underlying.delta
+
+ override def mergeDelta(thatDelta: D): LWWMap[A, B] =
+ new LWWMap(underlying.mergeDelta(thatDelta))
+
override def merge(that: LWWMap[A, B]): LWWMap[A, B] =
new LWWMap(underlying.merge(that.underlying))
diff --git a/akka-distributed-data/src/main/scala/akka/cluster/ddata/ORMap.scala b/akka-distributed-data/src/main/scala/akka/cluster/ddata/ORMap.scala
index b8cf38edd4..1240e7fdbd 100644
--- a/akka-distributed-data/src/main/scala/akka/cluster/ddata/ORMap.scala
+++ b/akka-distributed-data/src/main/scala/akka/cluster/ddata/ORMap.scala
@@ -7,6 +7,9 @@ import akka.cluster.Cluster
import akka.cluster.UniqueAddress
import akka.util.HashCode
import akka.annotation.InternalApi
+import akka.cluster.ddata.ORMap.{ AtomicDeltaOp, ZeroTag }
+
+import scala.collection.immutable
object ORMap {
private val _empty: ORMap[Any, ReplicatedData] = new ORMap(ORSet.empty, Map.empty)
@@ -22,6 +25,125 @@ object ORMap {
*/
def unapply[A, B <: ReplicatedData](m: ORMap[A, B]): Option[Map[A, B]] = Some(m.entries)
+ sealed trait DeltaOp extends ReplicatedDelta with RequiresCausalDeliveryOfDeltas {
+ type T = DeltaOp
+ override def zero: DeltaReplicatedData
+ }
+
+ /**
+ * INTERNAL API
+ */
+ @InternalApi private[akka] def emptyWithPNCounterMapTag[A, B <: ReplicatedData]: ORMap[A, B] = new ORMap(ORSet.empty, Map.empty, zeroTag = PNCounterMapTag)
+
+ /**
+ * INTERNAL API
+ */
+ @InternalApi private[akka] def emptyWithORMultiMapTag[A, B <: ReplicatedData]: ORMap[A, B] = new ORMap(ORSet.empty, Map.empty, zeroTag = ORMultiMapTag)
+
+ /**
+ * INTERNAL API
+ */
+ @InternalApi private[akka] def emptyWithORMultiMapWithValueDeltasTag[A, B <: ReplicatedData]: ORMap[A, B] = new ORMap(ORSet.empty, Map.empty, zeroTag = ORMultiMapWithValueDeltasTag)
+
+ /**
+ * INTERNAL API
+ */
+ @InternalApi private[akka] def emptyWithLWWMapTag[A, B <: ReplicatedData]: ORMap[A, B] = new ORMap(ORSet.empty, Map.empty, zeroTag = LWWMapTag)
+
+ /**
+ * INTERNAL API
+ * Tags for ORMap.DeltaOp's, so that when the Replicator needs to re-create full value from delta,
+ * the right map type will be used
+ */
+ @InternalApi private[akka] trait ZeroTag {
+ def zero: DeltaReplicatedData
+ def value: Int
+ }
+
+ /**
+ * INTERNAL API
+ */
+ @InternalApi private[akka] case object VanillaORMapTag extends ZeroTag {
+ override def zero: DeltaReplicatedData = ORMap.empty
+ override final val value: Int = 0
+ }
+
+ /**
+ * INTERNAL API
+ */
+ @InternalApi private[akka] case object PNCounterMapTag extends ZeroTag {
+ override def zero: DeltaReplicatedData = PNCounterMap.empty
+ override final val value: Int = 1
+ }
+
+ /**
+ * INTERNAL API
+ */
+ @InternalApi private[akka] case object ORMultiMapTag extends ZeroTag {
+ override def zero: DeltaReplicatedData = ORMultiMap.empty
+ override final val value: Int = 2
+ }
+
+ /**
+ * INTERNAL API
+ */
+ @InternalApi private[akka] case object ORMultiMapWithValueDeltasTag extends ZeroTag {
+ override def zero: DeltaReplicatedData = ORMultiMap.emptyWithValueDeltas
+ override final val value: Int = 3
+ }
+
+ /**
+ * INTERNAL API
+ */
+ @InternalApi private[akka] case object LWWMapTag extends ZeroTag {
+ override def zero: DeltaReplicatedData = LWWMap.empty
+ override final val value: Int = 4
+ }
+
+ /**
+ * INTERNAL API
+ */
+ @InternalApi private[akka] sealed abstract class AtomicDeltaOp[A, B <: ReplicatedData] extends DeltaOp {
+ def underlying: ORSet.DeltaOp
+ def zeroTag: ZeroTag
+ override def zero: DeltaReplicatedData = zeroTag.zero
+
+ override def merge(that: DeltaOp): DeltaOp = that match {
+ case other: AtomicDeltaOp[A, B] ⇒ DeltaGroup(Vector(this, other))
+ case DeltaGroup(ops) ⇒ DeltaGroup(this +: ops)
+ }
+ }
+
+ // PutDeltaOp contains ORSet delta and full value
+ /** INTERNAL API */
+ @InternalApi private[akka] final case class PutDeltaOp[A, B <: ReplicatedData](underlying: ORSet.DeltaOp, value: (A, B), zeroTag: ZeroTag = VanillaORMapTag) extends AtomicDeltaOp[A, B] {
+ }
+
+ // UpdateDeltaOp contains ORSet delta and either delta of value (in case where underlying type supports deltas) or full value
+ /** INTERNAL API */
+ @InternalApi private[akka] final case class UpdateDeltaOp[A, X <: ReplicatedDelta](underlying: ORSet.DeltaOp, values: Map[A, X], zeroTag: ZeroTag = VanillaORMapTag) extends AtomicDeltaOp[A, X] {
+ }
+
+ // RemoveDeltaOp does not contain any value at all - the propagated 'value' map is empty
+ /** INTERNAL API */
+ @InternalApi private[akka] final case class RemoveDeltaOp[A, B <: ReplicatedData](underlying: ORSet.DeltaOp, zeroTag: ZeroTag = VanillaORMapTag) extends AtomicDeltaOp[A, B] {
+ }
+
+ // RemoveKeyDeltaOp contains a single value - to provide the recipient with the removed key for value map
+ /** INTERNAL API */
+ @InternalApi private[akka] final case class RemoveKeyDeltaOp[A, B <: ReplicatedData](underlying: ORSet.DeltaOp, removedKey: A, zeroTag: ZeroTag = VanillaORMapTag) extends AtomicDeltaOp[A, B] {
+ }
+
+ // DeltaGroup is effectively a causally ordered list of individual deltas
+ /** INTERNAL API */
+ @InternalApi private[akka] final case class DeltaGroup[A, B <: ReplicatedData](ops: immutable.IndexedSeq[DeltaOp]) extends DeltaOp {
+ override def merge(that: DeltaOp): DeltaOp = that match {
+ case DeltaGroup(thatOps) ⇒ DeltaGroup(ops ++ thatOps)
+ case that: AtomicDeltaOp[A, B] ⇒ DeltaGroup(ops :+ that)
+ }
+
+ override def zero: DeltaReplicatedData = ops.headOption.fold(ORMap.empty[A, B].asInstanceOf[DeltaReplicatedData])(_.zero)
+ }
}
/**
@@ -34,11 +156,16 @@ object ORMap {
*/
@SerialVersionUID(1L)
final class ORMap[A, B <: ReplicatedData] private[akka] (
- private[akka] val keys: ORSet[A],
- private[akka] val values: Map[A, B])
- extends ReplicatedData with ReplicatedDataSerialization with RemovedNodePruning {
+ private[akka] val keys: ORSet[A],
+ private[akka] val values: Map[A, B],
+ private[akka] val zeroTag: ZeroTag = ORMap.VanillaORMapTag,
+ override val delta: Option[ORMap.DeltaOp] = None)
+ extends DeltaReplicatedData with ReplicatedDataSerialization with RemovedNodePruning {
+
+ import ORMap.{ PutDeltaOp, UpdateDeltaOp, RemoveDeltaOp, RemoveKeyDeltaOp }
type T = ORMap[A, B]
+ type D = ORMap.DeltaOp
/**
* Scala API: All entries of the map.
@@ -100,8 +227,11 @@ final class ORMap[A, B <: ReplicatedData] private[akka] (
"`ORMap.put` must not be used to replace an existing `ORSet` " +
"value, because important history can be lost when replacing the `ORSet` and " +
"undesired effects of merging will occur. Use `ORMultiMap` or `ORMap.updated` instead.")
- else
- new ORMap(keys.add(node, key), values.updated(key, value))
+ else {
+ val putDeltaOp = PutDeltaOp(keys.resetDelta.add(node, key).delta.get, key → value, zeroTag)
+ // put forcibly damages history, so we propagate full value that will overwrite previous values
+ new ORMap(keys.add(node, key), values.updated(key, value), zeroTag, Some(newDelta(putDeltaOp)))
+ }
/**
* Scala API: Replace a value by applying the `modify` function on the existing value.
@@ -124,12 +254,30 @@ final class ORMap[A, B <: ReplicatedData] private[akka] (
/**
* INTERNAL API
*/
- @InternalApi private[akka] def updated(node: UniqueAddress, key: A, initial: B)(modify: B ⇒ B): ORMap[A, B] = {
- val newValue = values.get(key) match {
- case Some(old) ⇒ modify(old)
- case _ ⇒ modify(initial)
+ @InternalApi private[akka] def updated(node: UniqueAddress, key: A, initial: B, valueDeltas: Boolean = false)(modify: B ⇒ B): ORMap[A, B] = {
+ val (oldValue, hasOldValue) = values.get(key) match {
+ case Some(old) ⇒ (old, true)
+ case _ ⇒ (initial, false)
+ }
+ // Optimization: for some types - like GSet, GCounter, PNCounter and ORSet - that are delta based
+ // we can emit (and later merge) their deltas instead of full updates.
+ // However to avoid necessity of tombstones, the derived map type needs to support this
+ // with clearing the value (e.g. removing all elements if value is a set)
+ // before removing the key - like e.g. ORMultiMap does
+ oldValue match {
+ case _: DeltaReplicatedData if valueDeltas ⇒
+ val newValue = modify(oldValue.asInstanceOf[DeltaReplicatedData].resetDelta.asInstanceOf[B])
+ val newValueDelta = newValue.asInstanceOf[DeltaReplicatedData].delta
+ val deltaOp = newValueDelta match {
+ case Some(d) if hasOldValue ⇒ UpdateDeltaOp(keys.resetDelta.add(node, key).delta.get, Map(key → d), zeroTag)
+ case _ ⇒ PutDeltaOp(keys.resetDelta.add(node, key).delta.get, key → newValue, zeroTag)
+ }
+ new ORMap(keys.add(node, key), values.updated(key, newValue), zeroTag, Some(newDelta(deltaOp)))
+ case _ ⇒
+ val newValue = modify(oldValue)
+ val deltaOp = PutDeltaOp(keys.resetDelta.add(node, key).delta.get, key → newValue, zeroTag)
+ new ORMap(keys.add(node, key), values.updated(key, newValue), zeroTag, Some(newDelta(deltaOp)))
}
- new ORMap(keys.add(node, key), values.updated(key, newValue))
}
/**
@@ -150,13 +298,24 @@ final class ORMap[A, B <: ReplicatedData] private[akka] (
* INTERNAL API
*/
@InternalApi private[akka] def remove(node: UniqueAddress, key: A): ORMap[A, B] = {
- new ORMap(keys.remove(node, key), values - key)
+ // for removals the delta values map emitted will be empty
+ val removeDeltaOp = RemoveDeltaOp(keys.resetDelta.remove(node, key).delta.get, zeroTag)
+ new ORMap(keys.remove(node, key), values - key, zeroTag, Some(newDelta(removeDeltaOp)))
}
- override def merge(that: ORMap[A, B]): ORMap[A, B] = {
- val mergedKeys = keys.merge(that.keys)
+ /**
+ * INTERNAL API
+ * This function is only to be used by derived maps that avoid remove anomalies
+ * by keeping the vvector (in form of key -> value pair) for deleted keys
+ */
+ @InternalApi private[akka] def removeKey(node: UniqueAddress, key: A): ORMap[A, B] = {
+ val removeKeyDeltaOp = RemoveKeyDeltaOp(keys.resetDelta.remove(node, key).delta.get, key, zeroTag)
+ new ORMap(keys.remove(node, key), values, zeroTag, Some(newDelta(removeKeyDeltaOp)))
+ }
+
+ private def dryMerge(that: ORMap[A, B], mergedKeys: ORSet[A], valueKeysIterator: Iterator[A]): ORMap[A, B] = {
var mergedValues = Map.empty[A, B]
- mergedKeys.elementsMap.keysIterator.foreach { key ⇒
+ valueKeysIterator.foreach { key ⇒
(this.values.get(key), that.values.get(key)) match {
case (Some(thisValue), Some(thatValue)) ⇒
if (thisValue.getClass != thatValue.getClass) {
@@ -174,8 +333,110 @@ final class ORMap[A, B <: ReplicatedData] private[akka] (
case (None, None) ⇒ throw new IllegalStateException(s"missing value for $key")
}
}
+ new ORMap(mergedKeys, mergedValues, zeroTag = zeroTag)
+ }
- new ORMap(mergedKeys, mergedValues)
+ override def merge(that: ORMap[A, B]): ORMap[A, B] = {
+ val mergedKeys = keys.merge(that.keys)
+ dryMerge(that, mergedKeys, mergedKeys.elementsMap.keysIterator)
+ }
+
+ /**
+ * INTERNAL API
+ * This function is only to be used by derived maps that avoid remove anomalies
+ * by keeping the vvector (in form of key -> value pair) for deleted keys
+ */
+ @InternalApi private[akka] def mergeRetainingDeletedValues(that: ORMap[A, B]): ORMap[A, B] = {
+ val mergedKeys = keys.merge(that.keys)
+ dryMerge(that, mergedKeys, (this.values.keySet ++ that.values.keySet).iterator)
+ }
+
+ override def resetDelta: ORMap[A, B] =
+ if (delta.isEmpty) this
+ else new ORMap[A, B](keys, values, zeroTag = zeroTag)
+
+ override def mergeDelta(thatDelta: ORMap.DeltaOp): ORMap[A, B] = {
+ // helper function to simplify folds below
+ def foldValues(values: List[(A, ReplicatedData)], initial: B) =
+ values.foldLeft(initial) {
+ case (acc: DeltaReplicatedData, (_, value: ReplicatedDelta)) ⇒
+ acc.mergeDelta(value.asInstanceOf[acc.D]).asInstanceOf[B]
+ case (acc, (_, value)) ⇒
+ acc.merge(value.asInstanceOf[acc.T]).asInstanceOf[B]
+ }
+
+ val mergedKeys: ORSet[A] = thatDelta match {
+ case d: AtomicDeltaOp[A, B] ⇒ keys.mergeDelta(d.underlying)
+ case ORMap.DeltaGroup(ops) ⇒
+ ops.foldLeft(keys)((acc, op) ⇒ acc.mergeDelta(op.asInstanceOf[AtomicDeltaOp[A, B]].underlying))
+ }
+
+ var mergedValues = Map.empty[A, B]
+ var tombstonedVals = Set.empty[A]
+ var thatValueDeltas: Map[A, List[(A, ReplicatedData)]] = Map.empty
+
+ val processDelta: PartialFunction[ORMap.DeltaOp, Unit] = {
+ case putOp: PutDeltaOp[A, B] ⇒
+ val key = putOp.value._1
+ thatValueDeltas += (key → (putOp.value :: Nil)) // put is destructive!
+ case _: RemoveDeltaOp[A, B] ⇒
+ // remove delta is only for the side effect of key being removed
+ // please note that if it is not preceded by update clearing the value
+ // anomalies will result
+ case removeKeyOp: RemoveKeyDeltaOp[A, B] ⇒
+ tombstonedVals = tombstonedVals + removeKeyOp.removedKey
+ case updateOp: UpdateDeltaOp[A, _] ⇒
+ val key = updateOp.values.head._1
+ val value = (key, updateOp.values.head._2)
+ if (thatValueDeltas.contains(key))
+ thatValueDeltas = thatValueDeltas + (key → (thatValueDeltas(key) :+ value))
+ else
+ thatValueDeltas += (key → (value :: Nil))
+ }
+
+ val processNestedDelta: PartialFunction[ORMap.DeltaOp, Unit] = {
+ case ORMap.DeltaGroup(ops) ⇒
+ ops.foreach {
+ processDelta.orElse {
+ case ORMap.DeltaGroup(args) ⇒
+ throw new IllegalStateException("Cannot nest DeltaGroups")
+ }
+ }
+ }
+
+ (processDelta orElse processNestedDelta)(thatDelta)
+
+ val aggregateValuesForKey: (A ⇒ Unit) = { key ⇒
+ (this.values.get(key), thatValueDeltas.get(key)) match {
+ case (Some(thisValue), Some(thatValues)) ⇒
+ val mergedValue = foldValues(thatValues, thisValue)
+ mergedValues = mergedValues.updated(key, mergedValue)
+ case (Some(thisValue), None) ⇒
+ mergedValues = mergedValues.updated(key, thisValue)
+ case (None, Some(thatValues)) ⇒
+ val (_, initialValue) = thatValues.head
+ val mergedValue = initialValue match {
+ case _: ReplicatedDelta ⇒
+ foldValues(thatValues, initialValue.asInstanceOf[ReplicatedDelta].zero.asInstanceOf[B])
+ case _ ⇒
+ foldValues(thatValues.tail, initialValue.asInstanceOf[B])
+ }
+ mergedValues = mergedValues.updated(key, mergedValue)
+ case (None, None) ⇒ throw new IllegalStateException(s"missing value for $key")
+ }
+ }
+
+ mergedKeys.elementsMap.keysIterator.foreach { aggregateValuesForKey }
+ tombstonedVals.foreach { aggregateValuesForKey }
+
+ new ORMap[A, B](mergedKeys, mergedValues, zeroTag = zeroTag)
+ }
+
+ private def newDelta(deltaOp: ORMap.DeltaOp) = delta match {
+ case Some(d) ⇒
+ d.merge(deltaOp)
+ case None ⇒
+ deltaOp
}
override def modifiedByNodes: Set[UniqueAddress] = {
@@ -199,7 +460,7 @@ final class ORMap[A, B <: ReplicatedData] private[akka] (
acc.updated(key, data.prune(removedNode, collapseInto).asInstanceOf[B])
case (acc, _) ⇒ acc
}
- new ORMap(prunedKeys, prunedValues)
+ new ORMap(prunedKeys, prunedValues, zeroTag = zeroTag)
}
override def pruningCleanup(removedNode: UniqueAddress): ORMap[A, B] = {
@@ -209,7 +470,7 @@ final class ORMap[A, B <: ReplicatedData] private[akka] (
acc.updated(key, data.pruningCleanup(removedNode).asInstanceOf[B])
case (acc, _) ⇒ acc
}
- new ORMap(pruningCleanupedKeys, pruningCleanupedValues)
+ new ORMap(pruningCleanupedKeys, pruningCleanupedValues, zeroTag = zeroTag)
}
// this class cannot be a `case class` because we need different `unapply`
diff --git a/akka-distributed-data/src/main/scala/akka/cluster/ddata/ORMultiMap.scala b/akka-distributed-data/src/main/scala/akka/cluster/ddata/ORMultiMap.scala
index d95d04409b..5c7d00e907 100644
--- a/akka-distributed-data/src/main/scala/akka/cluster/ddata/ORMultiMap.scala
+++ b/akka-distributed-data/src/main/scala/akka/cluster/ddata/ORMultiMap.scala
@@ -3,22 +3,26 @@
*/
package akka.cluster.ddata
-import akka.cluster.{ UniqueAddress, Cluster }
+import akka.cluster.{ Cluster, UniqueAddress }
import akka.annotation.InternalApi
+import akka.cluster.ddata.ORMap._
object ORMultiMap {
- val _empty: ORMultiMap[Any, Any] = new ORMultiMap(ORMap.empty)
+ val _empty: ORMultiMap[Any, Any] = new ORMultiMap(ORMap.emptyWithORMultiMapTag, false)
+ val _emptyWithValueDeltas: ORMultiMap[Any, Any] = new ORMultiMap(ORMap.emptyWithORMultiMapTag, true)
/**
* Provides an empty multimap.
*/
def empty[A, B]: ORMultiMap[A, B] = _empty.asInstanceOf[ORMultiMap[A, B]]
+ def emptyWithValueDeltas[A, B]: ORMultiMap[A, B] = _emptyWithValueDeltas.asInstanceOf[ORMultiMap[A, B]]
def apply(): ORMultiMap[Any, Any] = _empty
/**
* Java API
*/
def create[A, B](): ORMultiMap[A, B] = empty[A, B]
+ def createWithDeltaDelta[A, B](): ORMultiMap[A, B] = emptyWithValueDeltas[A, B]
/**
* Extract the [[ORMultiMap#entries]].
@@ -41,18 +45,28 @@ object ORMultiMap {
* This class is immutable, i.e. "modifying" methods return a new instance.
*/
@SerialVersionUID(1L)
-final class ORMultiMap[A, B] private[akka] (private[akka] val underlying: ORMap[A, ORSet[B]])
- extends ReplicatedData with ReplicatedDataSerialization with RemovedNodePruning {
+final class ORMultiMap[A, B] private[akka] (
+ private[akka] val underlying: ORMap[A, ORSet[B]],
+ private[akka] val withValueDeltas: Boolean)
+ extends DeltaReplicatedData with ReplicatedDataSerialization with RemovedNodePruning {
override type T = ORMultiMap[A, B]
+ override type D = ORMap.DeltaOp
override def merge(that: T): T =
- new ORMultiMap(underlying.merge(that.underlying))
+ if (withValueDeltas == that.withValueDeltas) {
+ if (withValueDeltas)
+ new ORMultiMap(underlying.mergeRetainingDeletedValues(that.underlying), withValueDeltas)
+ else
+ new ORMultiMap(underlying.merge(that.underlying), withValueDeltas)
+ } else throw new IllegalArgumentException("Trying to merge two ORMultiMaps of different map sub-type")
/**
* Scala API: All entries of a multimap where keys are strings and values are sets.
*/
- def entries: Map[A, Set[B]] =
+ def entries: Map[A, Set[B]] = if (withValueDeltas)
+ underlying.entries.collect { case (k, v) if underlying.keys.elements.contains(k) ⇒ k → v.elements }
+ else
underlying.entries.map { case (k, v) ⇒ k → v.elements }
/**
@@ -61,9 +75,10 @@ final class ORMultiMap[A, B] private[akka] (private[akka] val underlying: ORMap[
def getEntries(): java.util.Map[A, java.util.Set[B]] = {
import scala.collection.JavaConverters._
val result = new java.util.HashMap[A, java.util.Set[B]]
- underlying.entries.foreach {
- case (k, v) ⇒ result.put(k, v.elements.asJava)
- }
+ if (withValueDeltas)
+ underlying.entries.foreach { case (k, v) ⇒ if (underlying.keys.elements.contains(k)) result.put(k, v.elements.asJava) }
+ else
+ underlying.entries.foreach { case (k, v) ⇒ result.put(k, v.elements.asJava) }
result
}
@@ -71,7 +86,10 @@ final class ORMultiMap[A, B] private[akka] (private[akka] val underlying: ORMap[
* Get the set associated with the key if there is one.
*/
def get(key: A): Option[Set[B]] =
- underlying.get(key).map(_.elements)
+ if (withValueDeltas && !underlying.keys.elements.contains(key))
+ None
+ else
+ underlying.get(key).map(_.elements)
/**
* Scala API: Get the set associated with the key if there is one,
@@ -80,11 +98,11 @@ final class ORMultiMap[A, B] private[akka] (private[akka] val underlying: ORMap[
def getOrElse(key: A, default: ⇒ Set[B]): Set[B] =
get(key).getOrElse(default)
- def contains(key: A): Boolean = underlying.contains(key)
+ def contains(key: A): Boolean = underlying.keys.elements.contains(key)
- def isEmpty: Boolean = underlying.isEmpty
+ def isEmpty: Boolean = underlying.keys.elements.isEmpty
- def size: Int = underlying.size
+ def size: Int = underlying.keys.elements.size
/**
* Convenience for put. Requires an implicit Cluster.
@@ -115,10 +133,10 @@ final class ORMultiMap[A, B] private[akka] (private[akka] val underlying: ORMap[
* INTERNAL API
*/
@InternalApi private[akka] def put(node: UniqueAddress, key: A, value: Set[B]): ORMultiMap[A, B] = {
- val newUnderlying = underlying.updated(node, key, ORSet.empty[B]) { existing ⇒
+ val newUnderlying = underlying.updated(node, key, ORSet.empty[B], valueDeltas = withValueDeltas) { existing ⇒
value.foldLeft(existing.clear(node)) { (s, element) ⇒ s.add(node, element) }
}
- new ORMultiMap(newUnderlying)
+ new ORMultiMap(newUnderlying, withValueDeltas)
}
/**
@@ -137,8 +155,14 @@ final class ORMultiMap[A, B] private[akka] (private[akka] val underlying: ORMap[
/**
* INTERNAL API
*/
- @InternalApi private[akka] def remove(node: UniqueAddress, key: A): ORMultiMap[A, B] =
- new ORMultiMap(underlying.remove(node, key))
+ @InternalApi private[akka] def remove(node: UniqueAddress, key: A): ORMultiMap[A, B] = {
+ if (withValueDeltas) {
+ val u = underlying.updated(node, key, ORSet.empty[B], valueDeltas = true) { existing ⇒ existing.clear(node) }
+ new ORMultiMap(u.removeKey(node, key), withValueDeltas)
+ } else {
+ new ORMultiMap(underlying.remove(node, key), withValueDeltas)
+ }
+ }
/**
* Scala API: Add an element to a set associated with a key. If there is no existing set then one will be initialised.
@@ -156,8 +180,8 @@ final class ORMultiMap[A, B] private[akka] (private[akka] val underlying: ORMap[
* INTERNAL API
*/
@InternalApi private[akka] def addBinding(node: UniqueAddress, key: A, element: B): ORMultiMap[A, B] = {
- val newUnderlying = underlying.updated(node, key, ORSet.empty[B])(_.add(node, element))
- new ORMultiMap(newUnderlying)
+ val newUnderlying = underlying.updated(node, key, ORSet.empty[B], valueDeltas = withValueDeltas)(_.add(node, element))
+ new ORMultiMap(newUnderlying, withValueDeltas)
}
/**
@@ -179,13 +203,17 @@ final class ORMultiMap[A, B] private[akka] (private[akka] val underlying: ORMap[
*/
@InternalApi private[akka] def removeBinding(node: UniqueAddress, key: A, element: B): ORMultiMap[A, B] = {
val newUnderlying = {
- val u = underlying.updated(node, key, ORSet.empty[B])(_.remove(node, element))
+ val u = underlying.updated(node, key, ORSet.empty[B], valueDeltas = withValueDeltas)(_.remove(node, element))
u.get(key) match {
- case Some(s) if s.isEmpty ⇒ u.remove(node, key)
- case _ ⇒ u
+ case Some(s) if s.isEmpty ⇒
+ if (withValueDeltas)
+ u.removeKey(node, key)
+ else
+ u.remove(node, key)
+ case _ ⇒ u
}
}
- new ORMultiMap(newUnderlying)
+ new ORMultiMap(newUnderlying, withValueDeltas)
}
/**
@@ -205,6 +233,14 @@ final class ORMultiMap[A, B] private[akka] (private[akka] val underlying: ORMap[
else
this
+ override def resetDelta: ORMultiMap[A, B] =
+ new ORMultiMap(underlying.resetDelta, withValueDeltas)
+
+ override def delta: Option[D] = underlying.delta
+
+ override def mergeDelta(thatDelta: D): ORMultiMap[A, B] =
+ new ORMultiMap(underlying.mergeDelta(thatDelta), withValueDeltas)
+
override def modifiedByNodes: Set[UniqueAddress] =
underlying.modifiedByNodes
@@ -212,10 +248,10 @@ final class ORMultiMap[A, B] private[akka] (private[akka] val underlying: ORMap[
underlying.needPruningFrom(removedNode)
override def pruningCleanup(removedNode: UniqueAddress): T =
- new ORMultiMap(underlying.pruningCleanup(removedNode))
+ new ORMultiMap(underlying.pruningCleanup(removedNode), withValueDeltas)
override def prune(removedNode: UniqueAddress, collapseInto: UniqueAddress): T =
- new ORMultiMap(underlying.prune(removedNode, collapseInto))
+ new ORMultiMap(underlying.prune(removedNode, collapseInto), withValueDeltas)
// this class cannot be a `case class` because we need different `unapply`
diff --git a/akka-distributed-data/src/main/scala/akka/cluster/ddata/ORSet.scala b/akka-distributed-data/src/main/scala/akka/cluster/ddata/ORSet.scala
index 2f1637dfe8..fa3eacd744 100644
--- a/akka-distributed-data/src/main/scala/akka/cluster/ddata/ORSet.scala
+++ b/akka-distributed-data/src/main/scala/akka/cluster/ddata/ORSet.scala
@@ -91,7 +91,10 @@ object ORSet {
}
}
- final case class DeltaGroup[A](ops: immutable.IndexedSeq[DeltaOp]) extends DeltaOp {
+ /**
+ * INTERNAL API
+ */
+ @InternalApi private[akka] final case class DeltaGroup[A](ops: immutable.IndexedSeq[DeltaOp]) extends DeltaOp {
override def merge(that: DeltaOp): DeltaOp = that match {
case thatAdd: AddDeltaOp[A] ⇒
// merge AddDeltaOp into last AddDeltaOp in the group, if possible
diff --git a/akka-distributed-data/src/main/scala/akka/cluster/ddata/PNCounterMap.scala b/akka-distributed-data/src/main/scala/akka/cluster/ddata/PNCounterMap.scala
index 6fed4cc47c..694616edb2 100644
--- a/akka-distributed-data/src/main/scala/akka/cluster/ddata/PNCounterMap.scala
+++ b/akka-distributed-data/src/main/scala/akka/cluster/ddata/PNCounterMap.scala
@@ -6,10 +6,12 @@ package akka.cluster.ddata
import akka.cluster.Cluster
import akka.cluster.UniqueAddress
import java.math.BigInteger
+
import akka.annotation.InternalApi
+import akka.cluster.ddata.ORMap._
object PNCounterMap {
- def empty[A]: PNCounterMap[A] = new PNCounterMap(ORMap.empty)
+ def empty[A]: PNCounterMap[A] = new PNCounterMap(ORMap.emptyWithPNCounterMapTag)
def apply[A](): PNCounterMap[A] = empty
/**
* Java API
@@ -30,9 +32,10 @@ object PNCounterMap {
@SerialVersionUID(1L)
final class PNCounterMap[A] private[akka] (
private[akka] val underlying: ORMap[A, PNCounter])
- extends ReplicatedData with ReplicatedDataSerialization with RemovedNodePruning {
+ extends DeltaReplicatedData with ReplicatedDataSerialization with RemovedNodePruning {
type T = PNCounterMap[A]
+ type D = ORMap.DeltaOp
/** Scala API */
def entries: Map[A, BigInt] = underlying.entries.map { case (k, c) ⇒ k → c.value }
@@ -124,6 +127,14 @@ final class PNCounterMap[A] private[akka] (
override def merge(that: PNCounterMap[A]): PNCounterMap[A] =
new PNCounterMap(underlying.merge(that.underlying))
+ override def resetDelta: PNCounterMap[A] =
+ new PNCounterMap(underlying.resetDelta)
+
+ override def delta: Option[D] = underlying.delta
+
+ override def mergeDelta(thatDelta: D): PNCounterMap[A] =
+ new PNCounterMap(underlying.mergeDelta(thatDelta))
+
override def modifiedByNodes: Set[UniqueAddress] =
underlying.modifiedByNodes
diff --git a/akka-distributed-data/src/main/scala/akka/cluster/ddata/protobuf/ReplicatedDataSerializer.scala b/akka-distributed-data/src/main/scala/akka/cluster/ddata/protobuf/ReplicatedDataSerializer.scala
index d65c372c26..cd9eff03b5 100644
--- a/akka-distributed-data/src/main/scala/akka/cluster/ddata/protobuf/ReplicatedDataSerializer.scala
+++ b/akka-distributed-data/src/main/scala/akka/cluster/ddata/protobuf/ReplicatedDataSerializer.scala
@@ -149,6 +149,22 @@ private object ReplicatedDataSerializer {
override def getValue(entry: rd.ORMultiMap.Entry): rd.ORSet = entry.getValue
}
+ implicit object ORMapDeltaGroupEntry extends ProtoMapEntryWriter[rd.ORMapDeltaGroup.MapEntry, rd.ORMapDeltaGroup.MapEntry.Builder, dm.OtherMessage] with ProtoMapEntryReader[rd.ORMapDeltaGroup.MapEntry, dm.OtherMessage] {
+ override def setStringKey(builder: rd.ORMapDeltaGroup.MapEntry.Builder, key: String, value: dm.OtherMessage): rd.ORMapDeltaGroup.MapEntry = builder.setStringKey(key).setValue(value).build()
+ override def setLongKey(builder: rd.ORMapDeltaGroup.MapEntry.Builder, key: Long, value: dm.OtherMessage): rd.ORMapDeltaGroup.MapEntry = builder.setLongKey(key).setValue(value).build()
+ override def setIntKey(builder: rd.ORMapDeltaGroup.MapEntry.Builder, key: Int, value: dm.OtherMessage): rd.ORMapDeltaGroup.MapEntry = builder.setIntKey(key).setValue(value).build()
+ override def setOtherKey(builder: rd.ORMapDeltaGroup.MapEntry.Builder, key: dm.OtherMessage, value: dm.OtherMessage): rd.ORMapDeltaGroup.MapEntry = builder.setOtherKey(key).setValue(value).build()
+ override def hasStringKey(entry: rd.ORMapDeltaGroup.MapEntry): Boolean = entry.hasStringKey
+ override def getStringKey(entry: rd.ORMapDeltaGroup.MapEntry): String = entry.getStringKey
+ override def hasIntKey(entry: rd.ORMapDeltaGroup.MapEntry): Boolean = entry.hasIntKey
+ override def getIntKey(entry: rd.ORMapDeltaGroup.MapEntry): Int = entry.getIntKey
+ override def hasLongKey(entry: rd.ORMapDeltaGroup.MapEntry): Boolean = entry.hasLongKey
+ override def getLongKey(entry: rd.ORMapDeltaGroup.MapEntry): Long = entry.getLongKey
+ override def hasOtherKey(entry: rd.ORMapDeltaGroup.MapEntry): Boolean = entry.hasOtherKey
+ override def getOtherKey(entry: rd.ORMapDeltaGroup.MapEntry): OtherMessage = entry.getOtherKey
+ override def getValue(entry: rd.ORMapDeltaGroup.MapEntry): dm.OtherMessage = entry.getValue
+ }
+
}
/**
@@ -178,6 +194,11 @@ class ReplicatedDataSerializer(val system: ExtendedActorSystem)
private val PNCounterKeyManifest = "g"
private val ORMapManifest = "H"
private val ORMapKeyManifest = "h"
+ private val ORMapPutManifest = "Ha"
+ private val ORMapRemoveManifest = "Hr"
+ private val ORMapRemoveKeyManifest = "Hk"
+ private val ORMapUpdateManifest = "Hu"
+ private val ORMapDeltaGroupManifest = "Hg"
private val LWWMapManifest = "I"
private val LWWMapKeyManifest = "i"
private val PNCounterMapManifest = "J"
@@ -198,6 +219,11 @@ class ReplicatedDataSerializer(val system: ExtendedActorSystem)
GCounterManifest → gcounterFromBinary,
PNCounterManifest → pncounterFromBinary,
ORMapManifest → ormapFromBinary,
+ ORMapPutManifest → ormapPutFromBinary,
+ ORMapRemoveManifest → ormapRemoveFromBinary,
+ ORMapRemoveKeyManifest → ormapRemoveKeyFromBinary,
+ ORMapUpdateManifest → ormapUpdateFromBinary,
+ ORMapDeltaGroupManifest → ormapDeltaGroupFromBinary,
LWWMapManifest → lwwmapFromBinary,
PNCounterMapManifest → pncountermapFromBinary,
ORMultiMapManifest → multimapFromBinary,
@@ -216,57 +242,67 @@ class ReplicatedDataSerializer(val system: ExtendedActorSystem)
ORMultiMapKeyManifest → (bytes ⇒ ORMultiMapKey(keyIdFromBinary(bytes))))
override def manifest(obj: AnyRef): String = obj match {
- case _: ORSet[_] ⇒ ORSetManifest
- case _: ORSet.AddDeltaOp[_] ⇒ ORSetAddManifest
- case _: ORSet.RemoveDeltaOp[_] ⇒ ORSetRemoveManifest
- case _: GSet[_] ⇒ GSetManifest
- case _: GCounter ⇒ GCounterManifest
- case _: PNCounter ⇒ PNCounterManifest
- case _: Flag ⇒ FlagManifest
- case _: LWWRegister[_] ⇒ LWWRegisterManifest
- case _: ORMap[_, _] ⇒ ORMapManifest
- case _: LWWMap[_, _] ⇒ LWWMapManifest
- case _: PNCounterMap[_] ⇒ PNCounterMapManifest
- case _: ORMultiMap[_, _] ⇒ ORMultiMapManifest
- case DeletedData ⇒ DeletedDataManifest
- case _: VersionVector ⇒ VersionVectorManifest
+ case _: ORSet[_] ⇒ ORSetManifest
+ case _: ORSet.AddDeltaOp[_] ⇒ ORSetAddManifest
+ case _: ORSet.RemoveDeltaOp[_] ⇒ ORSetRemoveManifest
+ case _: GSet[_] ⇒ GSetManifest
+ case _: GCounter ⇒ GCounterManifest
+ case _: PNCounter ⇒ PNCounterManifest
+ case _: Flag ⇒ FlagManifest
+ case _: LWWRegister[_] ⇒ LWWRegisterManifest
+ case _: ORMap[_, _] ⇒ ORMapManifest
+ case _: ORMap.PutDeltaOp[_, _] ⇒ ORMapPutManifest
+ case _: ORMap.RemoveDeltaOp[_, _] ⇒ ORMapRemoveManifest
+ case _: ORMap.RemoveKeyDeltaOp[_, _] ⇒ ORMapRemoveKeyManifest
+ case _: ORMap.UpdateDeltaOp[_, _] ⇒ ORMapUpdateManifest
+ case _: LWWMap[_, _] ⇒ LWWMapManifest
+ case _: PNCounterMap[_] ⇒ PNCounterMapManifest
+ case _: ORMultiMap[_, _] ⇒ ORMultiMapManifest
+ case DeletedData ⇒ DeletedDataManifest
+ case _: VersionVector ⇒ VersionVectorManifest
- case _: ORSetKey[_] ⇒ ORSetKeyManifest
- case _: GSetKey[_] ⇒ GSetKeyManifest
- case _: GCounterKey ⇒ GCounterKeyManifest
- case _: PNCounterKey ⇒ PNCounterKeyManifest
- case _: FlagKey ⇒ FlagKeyManifest
- case _: LWWRegisterKey[_] ⇒ LWWRegisterKeyManifest
- case _: ORMapKey[_, _] ⇒ ORMapKeyManifest
- case _: LWWMapKey[_, _] ⇒ LWWMapKeyManifest
- case _: PNCounterMapKey[_] ⇒ PNCounterMapKeyManifest
- case _: ORMultiMapKey[_, _] ⇒ ORMultiMapKeyManifest
+ case _: ORSetKey[_] ⇒ ORSetKeyManifest
+ case _: GSetKey[_] ⇒ GSetKeyManifest
+ case _: GCounterKey ⇒ GCounterKeyManifest
+ case _: PNCounterKey ⇒ PNCounterKeyManifest
+ case _: FlagKey ⇒ FlagKeyManifest
+ case _: LWWRegisterKey[_] ⇒ LWWRegisterKeyManifest
+ case _: ORMapKey[_, _] ⇒ ORMapKeyManifest
+ case _: LWWMapKey[_, _] ⇒ LWWMapKeyManifest
+ case _: PNCounterMapKey[_] ⇒ PNCounterMapKeyManifest
+ case _: ORMultiMapKey[_, _] ⇒ ORMultiMapKeyManifest
- case _: ORSet.DeltaGroup[_] ⇒ ORSetDeltaGroupManifest
- case _: ORSet.FullStateDeltaOp[_] ⇒ ORSetFullManifest
+ case _: ORSet.DeltaGroup[_] ⇒ ORSetDeltaGroupManifest
+ case _: ORMap.DeltaGroup[_, _] ⇒ ORMapDeltaGroupManifest
+ case _: ORSet.FullStateDeltaOp[_] ⇒ ORSetFullManifest
case _ ⇒
throw new IllegalArgumentException(s"Can't serialize object of type ${obj.getClass} in [${getClass.getName}]")
}
def toBinary(obj: AnyRef): Array[Byte] = obj match {
- case m: ORSet[_] ⇒ compress(orsetToProto(m))
- case m: ORSet.AddDeltaOp[_] ⇒ orsetToProto(m.underlying).toByteArray
- case m: ORSet.RemoveDeltaOp[_] ⇒ orsetToProto(m.underlying).toByteArray
- case m: GSet[_] ⇒ gsetToProto(m).toByteArray
- case m: GCounter ⇒ gcounterToProto(m).toByteArray
- case m: PNCounter ⇒ pncounterToProto(m).toByteArray
- case m: Flag ⇒ flagToProto(m).toByteArray
- case m: LWWRegister[_] ⇒ lwwRegisterToProto(m).toByteArray
- case m: ORMap[_, _] ⇒ compress(ormapToProto(m))
- case m: LWWMap[_, _] ⇒ compress(lwwmapToProto(m))
- case m: PNCounterMap[_] ⇒ compress(pncountermapToProto(m))
- case m: ORMultiMap[_, _] ⇒ compress(multimapToProto(m))
- case DeletedData ⇒ dm.Empty.getDefaultInstance.toByteArray
- case m: VersionVector ⇒ versionVectorToProto(m).toByteArray
- case Key(id) ⇒ keyIdToBinary(id)
- case m: ORSet.DeltaGroup[_] ⇒ orsetDeltaGroupToProto(m).toByteArray
- case m: ORSet.FullStateDeltaOp[_] ⇒ orsetToProto(m.underlying).toByteArray
+ case m: ORSet[_] ⇒ compress(orsetToProto(m))
+ case m: ORSet.AddDeltaOp[_] ⇒ orsetToProto(m.underlying).toByteArray
+ case m: ORSet.RemoveDeltaOp[_] ⇒ orsetToProto(m.underlying).toByteArray
+ case m: GSet[_] ⇒ gsetToProto(m).toByteArray
+ case m: GCounter ⇒ gcounterToProto(m).toByteArray
+ case m: PNCounter ⇒ pncounterToProto(m).toByteArray
+ case m: Flag ⇒ flagToProto(m).toByteArray
+ case m: LWWRegister[_] ⇒ lwwRegisterToProto(m).toByteArray
+ case m: ORMap[_, _] ⇒ compress(ormapToProto(m))
+ case m: ORMap.PutDeltaOp[_, _] ⇒ ormapPutToProto(m).toByteArray
+ case m: ORMap.RemoveDeltaOp[_, _] ⇒ ormapRemoveToProto(m).toByteArray
+ case m: ORMap.RemoveKeyDeltaOp[_, _] ⇒ ormapRemoveKeyToProto(m).toByteArray
+ case m: ORMap.UpdateDeltaOp[_, _] ⇒ ormapUpdateToProto(m).toByteArray
+ case m: LWWMap[_, _] ⇒ compress(lwwmapToProto(m))
+ case m: PNCounterMap[_] ⇒ compress(pncountermapToProto(m))
+ case m: ORMultiMap[_, _] ⇒ compress(multimapToProto(m))
+ case DeletedData ⇒ dm.Empty.getDefaultInstance.toByteArray
+ case m: VersionVector ⇒ versionVectorToProto(m).toByteArray
+ case Key(id) ⇒ keyIdToBinary(id)
+ case m: ORSet.DeltaGroup[_] ⇒ orsetDeltaGroupToProto(m).toByteArray
+ case m: ORMap.DeltaGroup[_, _] ⇒ ormapDeltaGroupToProto(m).toByteArray
+ case m: ORSet.FullStateDeltaOp[_] ⇒ orsetToProto(m.underlying).toByteArray
case _ ⇒
throw new IllegalArgumentException(s"Can't serialize object of type ${obj.getClass} in [${getClass.getName}]")
}
@@ -512,8 +548,9 @@ class ReplicatedDataSerializer(val system: ExtendedActorSystem)
}
def ormapToProto(ormap: ORMap[_, _]): rd.ORMap = {
+ val ormapBuilder = rd.ORMap.newBuilder()
val entries: jl.Iterable[rd.ORMap.Entry] = getEntries(ormap.values, rd.ORMap.Entry.newBuilder, otherMessageToProto)
- rd.ORMap.newBuilder().setKeys(orsetToProto(ormap.keys)).addAllEntries(entries).build()
+ ormapBuilder.setKeys(orsetToProto(ormap.keys)).addAllEntries(entries).build()
}
def ormapFromBinary(bytes: Array[Byte]): ORMap[Any, ReplicatedData] =
@@ -536,9 +573,144 @@ class ReplicatedDataSerializer(val system: ExtendedActorSystem)
entries)
}
+ def singleMapEntryFromProto[PEntry <: GeneratedMessage, A <: GeneratedMessage, B <: ReplicatedData](entry: PEntry, valueCreator: A ⇒ B)(implicit eh: ProtoMapEntryReader[PEntry, A]): Map[Any, B] = {
+ val elem = if (eh.hasStringKey(entry)) Some(eh.getStringKey(entry) → valueCreator(eh.getValue(entry)))
+ else if (eh.hasIntKey(entry)) Some(eh.getIntKey(entry) → valueCreator(eh.getValue(entry)))
+ else if (eh.hasLongKey(entry)) Some(eh.getLongKey(entry) → valueCreator(eh.getValue(entry)))
+ else if (eh.hasOtherKey(entry)) Some(otherMessageFromProto(eh.getOtherKey(entry)) → valueCreator(eh.getValue(entry)))
+ else None
+ elem match {
+ case Some(e) ⇒ Map(e)
+ case _ ⇒ Map.empty[Any, B]
+ }
+ }
+
+ // wire protocol is always DeltaGroup
+ private def ormapPutFromBinary(bytes: Array[Byte]): ORMap.PutDeltaOp[Any, ReplicatedData] = {
+ val group = ormapDeltaGroupFromBinary(bytes)
+ if (group.ops.size == 1 && group.ops.head.isInstanceOf[ORMap.PutDeltaOp[_, _]])
+ group.ops.head.asInstanceOf[ORMap.PutDeltaOp[Any, ReplicatedData]]
+ else
+ throw new NotSerializableException("Improper ORMap delta put operation size or kind")
+ }
+
+ // wire protocol is always delta group
+ private def ormapRemoveFromBinary(bytes: Array[Byte]): ORMap.RemoveDeltaOp[Any, ReplicatedData] = {
+ val group = ormapDeltaGroupFromBinary(bytes)
+ if (group.ops.size == 1 && group.ops.head.isInstanceOf[ORMap.RemoveDeltaOp[_, _]])
+ group.ops.head.asInstanceOf[ORMap.RemoveDeltaOp[Any, ReplicatedData]]
+ else
+ throw new NotSerializableException("Improper ORMap delta remove operation size or kind")
+ }
+
+ // wire protocol is always delta group
+ private def ormapRemoveKeyFromBinary(bytes: Array[Byte]): ORMap.RemoveKeyDeltaOp[Any, ReplicatedData] = {
+ val group = ormapDeltaGroupFromBinary(bytes)
+ if (group.ops.size == 1 && group.ops.head.isInstanceOf[ORMap.RemoveKeyDeltaOp[_, _]])
+ group.ops.head.asInstanceOf[ORMap.RemoveKeyDeltaOp[Any, ReplicatedData]]
+ else
+ throw new NotSerializableException("Improper ORMap delta remove key operation size or kind")
+ }
+
+ // wire protocol is always delta group
+ private def ormapUpdateFromBinary(bytes: Array[Byte]): ORMap.UpdateDeltaOp[Any, ReplicatedDelta] = {
+ val group = ormapDeltaGroupFromBinary(bytes)
+ if (group.ops.size == 1 && group.ops.head.isInstanceOf[ORMap.UpdateDeltaOp[_, _]])
+ group.ops.head.asInstanceOf[ORMap.UpdateDeltaOp[Any, ReplicatedDelta]]
+ else
+ throw new NotSerializableException("Improper ORMap delta update operation size or kind")
+ }
+
+ // this can be made client-extendable in the same way as Http codes in Spray are
+ private def zeroTagFromCode(code: Int) = code match {
+ case ORMap.VanillaORMapTag.value ⇒ ORMap.VanillaORMapTag
+ case ORMap.PNCounterMapTag.value ⇒ ORMap.PNCounterMapTag
+ case ORMap.ORMultiMapTag.value ⇒ ORMap.ORMultiMapTag
+ case ORMap.ORMultiMapWithValueDeltasTag.value ⇒ ORMap.ORMultiMapWithValueDeltasTag
+ case ORMap.LWWMapTag.value ⇒ ORMap.LWWMapTag
+ case _ ⇒ throw new IllegalArgumentException("Invalid ZeroTag code")
+ }
+
+ private def ormapDeltaGroupFromBinary(bytes: Array[Byte]): ORMap.DeltaGroup[Any, ReplicatedData] = {
+ val deltaGroup = rd.ORMapDeltaGroup.parseFrom(bytes)
+ val ops: Vector[ORMap.DeltaOp] =
+ deltaGroup.getEntriesList.asScala.map { entry ⇒
+ if (entry.getOperation == rd.ORMapDeltaOp.ORMapPut) {
+ val map = singleMapEntryFromProto(entry.getEntryData, (v: dm.OtherMessage) ⇒ otherMessageFromProto(v).asInstanceOf[ReplicatedData])
+ ORMap.PutDeltaOp(ORSet.AddDeltaOp(orsetFromProto(entry.getUnderlying)), map.head, zeroTagFromCode(entry.getZeroTag))
+ } else if (entry.getOperation == rd.ORMapDeltaOp.ORMapRemove) {
+ val map = singleMapEntryFromProto(entry.getEntryData, (v: dm.OtherMessage) ⇒ otherMessageFromProto(v).asInstanceOf[ReplicatedData])
+ ORMap.RemoveDeltaOp(ORSet.RemoveDeltaOp(orsetFromProto(entry.getUnderlying)), zeroTagFromCode(entry.getZeroTag))
+ } else if (entry.getOperation == rd.ORMapDeltaOp.ORMapRemoveKey) {
+ val map = singleMapEntryFromProto(entry.getEntryData, (v: dm.OtherMessage) ⇒ otherMessageFromProto(v).asInstanceOf[ReplicatedData])
+ ORMap.RemoveKeyDeltaOp(ORSet.RemoveDeltaOp(orsetFromProto(entry.getUnderlying)), map.keySet.head, zeroTagFromCode(entry.getZeroTag))
+ } else if (entry.getOperation == rd.ORMapDeltaOp.ORMapUpdate) {
+ val map = singleMapEntryFromProto(entry.getEntryData, (v: dm.OtherMessage) ⇒ otherMessageFromProto(v).asInstanceOf[ReplicatedDelta])
+ ORMap.UpdateDeltaOp(ORSet.AddDeltaOp(orsetFromProto(entry.getUnderlying)), map, zeroTagFromCode(entry.getZeroTag))
+ } else
+ throw new NotSerializableException(s"Unknown ORMap delta operation ${entry.getOperation}")
+ }(collection.breakOut)
+ ORMap.DeltaGroup(ops)
+ }
+
+ private def ormapPutToProto(addDelta: ORMap.PutDeltaOp[_, _]): rd.ORMapDeltaGroup = {
+ ormapDeltaGroupToProto(ORMap.DeltaGroup(scala.collection.immutable.IndexedSeq(addDelta.asInstanceOf[ORMap.DeltaOp])))
+ }
+
+ private def ormapRemoveToProto(addDelta: ORMap.RemoveDeltaOp[_, _]): rd.ORMapDeltaGroup = {
+ ormapDeltaGroupToProto(ORMap.DeltaGroup(scala.collection.immutable.IndexedSeq(addDelta.asInstanceOf[ORMap.DeltaOp])))
+ }
+
+ private def ormapRemoveKeyToProto(addDelta: ORMap.RemoveKeyDeltaOp[_, _]): rd.ORMapDeltaGroup = {
+ ormapDeltaGroupToProto(ORMap.DeltaGroup(scala.collection.immutable.IndexedSeq(addDelta.asInstanceOf[ORMap.DeltaOp])))
+ }
+
+ private def ormapUpdateToProto(addDelta: ORMap.UpdateDeltaOp[_, _]): rd.ORMapDeltaGroup = {
+ ormapDeltaGroupToProto(ORMap.DeltaGroup(scala.collection.immutable.IndexedSeq(addDelta.asInstanceOf[ORMap.DeltaOp])))
+ }
+
+ private def ormapDeltaGroupToProto(deltaGroup: ORMap.DeltaGroup[_, _]): rd.ORMapDeltaGroup = {
+ def createEntry(opType: rd.ORMapDeltaOp, u: ORSet[_], m: Map[_, _], zt: Int) = {
+ if (m.size > 1)
+ throw new IllegalArgumentException("Invalid size of ORMap delta map")
+ else {
+ val entryDataBuilder = rd.ORMapDeltaGroup.MapEntry.newBuilder()
+ m.headOption.map {
+ case (key: String, value) ⇒ entryDataBuilder.setStringKey(key).setValue(otherMessageToProto(value))
+ case (key: Int, value) ⇒ entryDataBuilder.setIntKey(key).setValue(otherMessageToProto(value))
+ case (key: Long, value) ⇒ entryDataBuilder.setLongKey(key).setValue(otherMessageToProto(value))
+ case (key, value) ⇒ entryDataBuilder.setOtherKey(otherMessageToProto(key)).setValue(otherMessageToProto(value))
+ }
+ val builder = rd.ORMapDeltaGroup.Entry.newBuilder()
+ .setOperation(opType)
+ .setUnderlying(orsetToProto(u))
+ .setZeroTag(zt)
+ if (m.size > 0)
+ builder.setEntryData(entryDataBuilder.build())
+ builder
+ }
+ }
+
+ val b = rd.ORMapDeltaGroup.newBuilder()
+ deltaGroup.ops.foreach {
+ case ORMap.PutDeltaOp(op, pair, zt) ⇒
+ b.addEntries(createEntry(rd.ORMapDeltaOp.ORMapPut, op.asInstanceOf[ORSet.AddDeltaOp[_]].underlying, Map(pair), zt.value))
+ case ORMap.RemoveDeltaOp(op, zt) ⇒
+ b.addEntries(createEntry(rd.ORMapDeltaOp.ORMapRemove, op.asInstanceOf[ORSet.RemoveDeltaOp[_]].underlying, Map.empty, zt.value))
+ case ORMap.RemoveKeyDeltaOp(op, k, zt) ⇒
+ b.addEntries(createEntry(rd.ORMapDeltaOp.ORMapRemove, op.asInstanceOf[ORSet.RemoveDeltaOp[_]].underlying, Map(k → k), zt.value))
+ case ORMap.UpdateDeltaOp(op, m, zt) ⇒
+ b.addEntries(createEntry(rd.ORMapDeltaOp.ORMapUpdate, op.asInstanceOf[ORSet.AddDeltaOp[_]].underlying, m, zt.value))
+ case ORMap.DeltaGroup(u) ⇒
+ throw new IllegalArgumentException("ORMap.DeltaGroup should not be nested")
+ }
+ b.build()
+ }
+
def lwwmapToProto(lwwmap: LWWMap[_, _]): rd.LWWMap = {
+ val lwwmapBuilder = rd.LWWMap.newBuilder()
val entries: jl.Iterable[rd.LWWMap.Entry] = getEntries(lwwmap.underlying.entries, rd.LWWMap.Entry.newBuilder, lwwRegisterToProto)
- rd.LWWMap.newBuilder().setKeys(orsetToProto(lwwmap.underlying.keys)).addAllEntries(entries).build()
+ lwwmapBuilder.setKeys(orsetToProto(lwwmap.underlying.keys)).addAllEntries(entries).build()
}
def lwwmapFromBinary(bytes: Array[Byte]): LWWMap[Any, Any] =
@@ -548,12 +720,13 @@ class ReplicatedDataSerializer(val system: ExtendedActorSystem)
val entries = mapTypeFromProto(lwwmap.getEntriesList, lwwRegisterFromProto)
new LWWMap(new ORMap(
keys = orsetFromProto(lwwmap.getKeys),
- entries))
+ entries, ORMap.LWWMapTag))
}
def pncountermapToProto(pncountermap: PNCounterMap[_]): rd.PNCounterMap = {
+ val pncountermapBuilder = rd.PNCounterMap.newBuilder()
val entries: jl.Iterable[rd.PNCounterMap.Entry] = getEntries(pncountermap.underlying.entries, rd.PNCounterMap.Entry.newBuilder, pncounterToProto)
- rd.PNCounterMap.newBuilder().setKeys(orsetToProto(pncountermap.underlying.keys)).addAllEntries(entries).build()
+ pncountermapBuilder.setKeys(orsetToProto(pncountermap.underlying.keys)).addAllEntries(entries).build()
}
def pncountermapFromBinary(bytes: Array[Byte]): PNCounterMap[_] =
@@ -563,12 +736,16 @@ class ReplicatedDataSerializer(val system: ExtendedActorSystem)
val entries = mapTypeFromProto(pncountermap.getEntriesList, pncounterFromProto)
new PNCounterMap(new ORMap(
keys = orsetFromProto(pncountermap.getKeys),
- entries))
+ entries, ORMap.PNCounterMapTag))
}
def multimapToProto(multimap: ORMultiMap[_, _]): rd.ORMultiMap = {
+ val ormultimapBuilder = rd.ORMultiMap.newBuilder()
val entries: jl.Iterable[rd.ORMultiMap.Entry] = getEntries(multimap.underlying.entries, rd.ORMultiMap.Entry.newBuilder, orsetToProto)
- rd.ORMultiMap.newBuilder().setKeys(orsetToProto(multimap.underlying.keys)).addAllEntries(entries).build()
+ ormultimapBuilder.setKeys(orsetToProto(multimap.underlying.keys)).addAllEntries(entries)
+ if (multimap.withValueDeltas)
+ ormultimapBuilder.setWithValueDeltas(true)
+ ormultimapBuilder.build()
}
def multimapFromBinary(bytes: Array[Byte]): ORMultiMap[Any, Any] =
@@ -576,9 +753,18 @@ class ReplicatedDataSerializer(val system: ExtendedActorSystem)
def multimapFromProto(multimap: rd.ORMultiMap): ORMultiMap[Any, Any] = {
val entries = mapTypeFromProto(multimap.getEntriesList, orsetFromProto)
- new ORMultiMap(new ORMap(
- keys = orsetFromProto(multimap.getKeys),
- entries))
+ val withValueDeltas = if (multimap.hasWithValueDeltas)
+ multimap.getWithValueDeltas
+ else false
+ new ORMultiMap(
+ new ORMap(
+ keys = orsetFromProto(multimap.getKeys),
+ entries,
+ if (withValueDeltas)
+ ORMap.ORMultiMapWithValueDeltasTag
+ else
+ ORMap.ORMultiMapTag),
+ withValueDeltas)
}
def keyIdToBinary(id: String): Array[Byte] =
diff --git a/akka-distributed-data/src/multi-jvm/scala/akka/cluster/ddata/ReplicatorMapDeltaSpec.scala b/akka-distributed-data/src/multi-jvm/scala/akka/cluster/ddata/ReplicatorMapDeltaSpec.scala
new file mode 100644
index 0000000000..f083fdbf30
--- /dev/null
+++ b/akka-distributed-data/src/multi-jvm/scala/akka/cluster/ddata/ReplicatorMapDeltaSpec.scala
@@ -0,0 +1,281 @@
+/**
+ * Copyright (C) 2009-2016 Lightbend Inc.
+ */
+package akka.cluster.ddata
+
+import java.util.concurrent.ThreadLocalRandom
+
+import scala.concurrent.duration._
+
+import akka.cluster.Cluster
+import akka.cluster.ddata.Replicator._
+import akka.remote.testconductor.RoleName
+import akka.remote.testkit.MultiNodeConfig
+import akka.remote.testkit.MultiNodeSpec
+import akka.testkit._
+import com.typesafe.config.ConfigFactory
+
+object ReplicatorMapDeltaSpec extends MultiNodeConfig {
+ val first = role("first")
+ val second = role("second")
+ val third = role("third")
+ val fourth = role("fourth")
+
+ commonConfig(ConfigFactory.parseString("""
+ akka.loglevel = DEBUG
+ akka.actor.provider = "cluster"
+ akka.log-dead-letters-during-shutdown = off
+ """))
+
+ testTransport(on = true)
+
+ sealed trait Op
+ final case class Delay(n: Int) extends Op
+ final case class Incr(ki: (PNCounterMapKey[String], String), n: Int, consistency: WriteConsistency) extends Op
+ final case class Decr(ki: (PNCounterMapKey[String], String), n: Int, consistency: WriteConsistency) extends Op
+ final case class Add(ki: (ORMultiMapKey[String, String], String), elem: String, consistency: WriteConsistency) extends Op
+ final case class Remove(ki: (ORMultiMapKey[String, String], String), elem: String, consistency: WriteConsistency) extends Op
+
+ val timeout = 5.seconds
+ val writeTwo = WriteTo(2, timeout)
+ val writeMajority = WriteMajority(timeout)
+
+ val KeyPN = PNCounterMapKey[String]("A")
+ val KeyMM = ORMultiMapKey[String, String]("D")
+ val KeyA: (PNCounterMapKey[String], String) = (KeyPN, "a")
+ val KeyB: (PNCounterMapKey[String], String) = (KeyPN, "b")
+ val KeyC: (PNCounterMapKey[String], String) = (KeyPN, "c")
+ val KeyD: (ORMultiMapKey[String, String], String) = (KeyMM, "d")
+ val KeyE: (ORMultiMapKey[String, String], String) = (KeyMM, "e")
+ val KeyF: (ORMultiMapKey[String, String], String) = (KeyMM, "f")
+
+ def generateOperations(onNode: RoleName): Vector[Op] = {
+ val rnd = ThreadLocalRandom.current()
+
+ def consistency(): WriteConsistency = {
+ rnd.nextInt(100) match {
+ case n if n < 90 ⇒ WriteLocal
+ case n if n < 95 ⇒ writeTwo
+ case n if n < 100 ⇒ writeMajority
+ }
+ }
+
+ def rndPnCounterkey(): (PNCounterMapKey[String], String) = {
+ rnd.nextInt(3) match {
+ case 0 ⇒ KeyA
+ case 1 ⇒ KeyB
+ case 2 ⇒ KeyC
+ }
+ }
+
+ def rndOrSetkey(): (ORMultiMapKey[String, String], String) = {
+ rnd.nextInt(3) match {
+ case 0 ⇒ KeyD
+ case 1 ⇒ KeyE
+ case 2 ⇒ KeyF
+ }
+ }
+
+ var availableForRemove = Set.empty[String]
+
+ def rndAddElement(): String = {
+ // lower case a - j
+ val s = (97 + rnd.nextInt(10)).toChar.toString
+ availableForRemove += s
+ s
+ }
+
+ def rndRemoveElement(): String = {
+ if (availableForRemove.isEmpty)
+ "a"
+ else
+ availableForRemove.toVector(rnd.nextInt(availableForRemove.size))
+ }
+
+ (0 to (30 + rnd.nextInt(10))).map { _ ⇒
+ rnd.nextInt(4) match {
+ case 0 ⇒ Delay(rnd.nextInt(500))
+ case 1 ⇒ Incr(rndPnCounterkey(), rnd.nextInt(100), consistency())
+ case 2 ⇒ Decr(rndPnCounterkey(), rnd.nextInt(10), consistency())
+ case 3 ⇒
+ // ORSet
+ val key = rndOrSetkey()
+ // only removals for KeyF on node first
+ if (key == KeyF && onNode == first && rnd.nextBoolean())
+ Remove(key, rndRemoveElement(), consistency())
+ else
+ Add(key, rndAddElement(), consistency())
+ }
+ }.toVector
+ }
+
+}
+
+class ReplicatorMapDeltaSpecMultiJvmNode1 extends ReplicatorMapDeltaSpec
+class ReplicatorMapDeltaSpecMultiJvmNode2 extends ReplicatorMapDeltaSpec
+class ReplicatorMapDeltaSpecMultiJvmNode3 extends ReplicatorMapDeltaSpec
+class ReplicatorMapDeltaSpecMultiJvmNode4 extends ReplicatorMapDeltaSpec
+
+class ReplicatorMapDeltaSpec extends MultiNodeSpec(ReplicatorMapDeltaSpec) with STMultiNodeSpec with ImplicitSender {
+ import Replicator._
+ import ReplicatorMapDeltaSpec._
+
+ override def initialParticipants = roles.size
+
+ implicit val cluster = Cluster(system)
+ val fullStateReplicator = system.actorOf(Replicator.props(
+ ReplicatorSettings(system).withGossipInterval(1.second).withDeltaCrdtEnabled(false)), "fullStateReplicator")
+ val deltaReplicator = {
+ val r = system.actorOf(Replicator.props(ReplicatorSettings(system)), "deltaReplicator")
+ r ! Replicator.Internal.TestFullStateGossip(enabled = false)
+ r
+ }
+
+ var afterCounter = 0
+ def enterBarrierAfterTestStep(): Unit = {
+ afterCounter += 1
+ enterBarrier("after-" + afterCounter)
+ }
+
+ def join(from: RoleName, to: RoleName): Unit = {
+ runOn(from) {
+ cluster join node(to).address
+ }
+ enterBarrier(from.name + "-joined")
+ }
+
+ "delta-CRDT" must {
+ "join cluster" in {
+ join(first, first)
+ join(second, first)
+ join(third, first)
+ join(fourth, first)
+
+ within(15.seconds) {
+ awaitAssert {
+ fullStateReplicator ! GetReplicaCount
+ expectMsg(ReplicaCount(4))
+ }
+ }
+
+ enterBarrierAfterTestStep()
+ }
+
+ "propagate delta" in {
+ join(first, first)
+ join(second, first)
+ join(third, first)
+ join(fourth, first)
+
+ within(15.seconds) {
+ awaitAssert {
+ fullStateReplicator ! GetReplicaCount
+ expectMsg(ReplicaCount(4))
+ }
+ }
+ enterBarrier("ready")
+
+ runOn(first) {
+ // by setting something for each key we don't have to worry about NotFound
+ List(KeyA, KeyB, KeyC).foreach { key ⇒
+ fullStateReplicator ! Update(key._1, PNCounterMap.empty[String], WriteLocal)(_ increment key._2)
+ deltaReplicator ! Update(key._1, PNCounterMap.empty[String], WriteLocal)(_ increment key._2)
+ }
+ List(KeyD, KeyE, KeyF).foreach { key ⇒
+ fullStateReplicator ! Update(key._1, ORMultiMap.emptyWithValueDeltas[String, String], WriteLocal)(_ + (key._2, Set("a")))
+ deltaReplicator ! Update(key._1, ORMultiMap.emptyWithValueDeltas[String, String], WriteLocal)(_ + (key._2, Set("a")))
+ }
+ }
+ enterBarrier("updated-1")
+
+ within(5.seconds) {
+ awaitAssert {
+ val p = TestProbe()
+ List(KeyA, KeyB, KeyC).foreach { key ⇒
+ fullStateReplicator.tell(Get(key._1, ReadLocal), p.ref)
+ p.expectMsgType[GetSuccess[PNCounterMap[String]]].dataValue.get(key._2).get.intValue should be(1)
+ }
+ }
+ awaitAssert {
+ val p = TestProbe()
+ List(KeyD, KeyE, KeyF).foreach { key ⇒
+ fullStateReplicator.tell(Get(key._1, ReadLocal), p.ref)
+ p.expectMsgType[GetSuccess[ORMultiMap[String, String]]].dataValue.get(key._2) should ===(Some(Set("a")))
+ }
+ }
+ }
+
+ enterBarrierAfterTestStep()
+ }
+
+ "be eventually consistent" in {
+ val operations = generateOperations(onNode = myself)
+ log.debug(s"random operations on [${myself.name}]: ${operations.mkString(", ")}")
+ try {
+ // perform random operations with both delta and full-state replicators
+ // and compare that the end result is the same
+
+ for (op ← operations) {
+ log.debug("operation: {}", op)
+ op match {
+ case Delay(d) ⇒ Thread.sleep(d)
+ case Incr(key, n, consistency) ⇒
+ fullStateReplicator ! Update(key._1, PNCounterMap.empty[String], WriteLocal)(_ increment (key._2, n))
+ deltaReplicator ! Update(key._1, PNCounterMap.empty[String], WriteLocal)(_ increment (key._2, n))
+ case Decr(key, n, consistency) ⇒
+ fullStateReplicator ! Update(key._1, PNCounterMap.empty[String], WriteLocal)(_ decrement (key._2, n))
+ deltaReplicator ! Update(key._1, PNCounterMap.empty[String], WriteLocal)(_ decrement (key._2, n))
+ case Add(key, elem, consistency) ⇒
+ // to have an deterministic result when mixing add/remove we can only perform
+ // the ORSet operations from one node
+ runOn((if (key == KeyF) List(first) else List(first, second, third)): _*) {
+ fullStateReplicator ! Update(key._1, ORMultiMap.emptyWithValueDeltas[String, String], WriteLocal)(_ addBinding (key._2, elem))
+ deltaReplicator ! Update(key._1, ORMultiMap.emptyWithValueDeltas[String, String], WriteLocal)(_ addBinding (key._2, elem))
+ }
+ case Remove(key, elem, consistency) ⇒
+ runOn(first) {
+ fullStateReplicator ! Update(key._1, ORMultiMap.emptyWithValueDeltas[String, String], WriteLocal)(_ removeBinding (key._2, elem))
+ deltaReplicator ! Update(key._1, ORMultiMap.emptyWithValueDeltas[String, String], WriteLocal)(_ removeBinding (key._2, elem))
+ }
+ }
+ }
+
+ enterBarrier("updated-2")
+
+ List(KeyA, KeyB, KeyC).foreach { key ⇒
+ within(5.seconds) {
+ awaitAssert {
+ val p = TestProbe()
+ fullStateReplicator.tell(Get(key._1, ReadLocal), p.ref)
+ val fullStateValue = p.expectMsgType[GetSuccess[PNCounterMap[String]]].dataValue.get(key._2).get.intValue
+ deltaReplicator.tell(Get(key._1, ReadLocal), p.ref)
+ val deltaValue = p.expectMsgType[GetSuccess[PNCounterMap[String]]].dataValue.get(key._2).get.intValue
+ deltaValue should ===(fullStateValue)
+ }
+ }
+ }
+
+ List(KeyD, KeyE, KeyF).foreach { key ⇒
+ within(5.seconds) {
+ awaitAssert {
+ val p = TestProbe()
+ fullStateReplicator.tell(Get(key._1, ReadLocal), p.ref)
+ val fullStateValue = p.expectMsgType[GetSuccess[ORMultiMap[String, String]]].dataValue.get(key._2)
+ deltaReplicator.tell(Get(key._1, ReadLocal), p.ref)
+ val deltaValue = p.expectMsgType[GetSuccess[ORMultiMap[String, String]]].dataValue.get(key._2)
+ deltaValue should ===(fullStateValue)
+ }
+ }
+ }
+
+ enterBarrierAfterTestStep()
+ } catch {
+ case e: Throwable ⇒
+ info(s"random operations on [${myself.name}]: ${operations.mkString(", ")}")
+ throw e
+ }
+ }
+ }
+
+}
+
diff --git a/akka-distributed-data/src/multi-jvm/scala/akka/cluster/ddata/ReplicatorPruningSpec.scala b/akka-distributed-data/src/multi-jvm/scala/akka/cluster/ddata/ReplicatorPruningSpec.scala
index 33154a59b0..da67a36434 100644
--- a/akka-distributed-data/src/multi-jvm/scala/akka/cluster/ddata/ReplicatorPruningSpec.scala
+++ b/akka-distributed-data/src/multi-jvm/scala/akka/cluster/ddata/ReplicatorPruningSpec.scala
@@ -47,6 +47,8 @@ class ReplicatorPruningSpec extends MultiNodeSpec(ReplicatorPruningSpec) with ST
val KeyA = GCounterKey("A")
val KeyB = ORSetKey[String]("B")
val KeyC = PNCounterMapKey[String]("C")
+ val KeyD = ORMultiMapKey[String, String]("D")
+ val KeyE = ORMapKey[String, GSet[String]]("E")
def join(from: RoleName, to: RoleName): Unit = {
runOn(from) {
@@ -89,6 +91,12 @@ class ReplicatorPruningSpec extends MultiNodeSpec(ReplicatorPruningSpec) with ST
replicator ! Update(KeyC, PNCounterMap.empty[String], WriteAll(timeout)) { _ increment "x" increment "y" }
expectMsg(UpdateSuccess(KeyC, None))
+ replicator ! Update(KeyD, ORMultiMap.empty[String, String], WriteAll(timeout)) { _ + ("a", Set("A")) }
+ expectMsg(UpdateSuccess(KeyD, None))
+
+ replicator ! Update(KeyE, ORMap.empty[String, GSet[String]], WriteAll(timeout)) { _ + ("a", GSet.empty[String].add("A")) }
+ expectMsg(UpdateSuccess(KeyE, None))
+
enterBarrier("updates-done")
replicator ! Get(KeyA, ReadLocal)
@@ -104,8 +112,24 @@ class ReplicatorPruningSpec extends MultiNodeSpec(ReplicatorPruningSpec) with ST
oldMap.get("x") should be(Some(3))
oldMap.get("y") should be(Some(3))
+ replicator ! Get(KeyD, ReadLocal)
+ val oldMultiMap = expectMsgType[GetSuccess[ORMultiMap[String, String]]].dataValue
+ oldMultiMap.get("a") should be(Some(Set("A")))
+
+ replicator ! Get(KeyE, ReadLocal)
+ val oldORMap = expectMsgType[GetSuccess[ORMap[String, GSet[String]]]].dataValue
+ val GSet(d) = oldORMap.entries("a")
+ d should be(Set("A"))
+
enterBarrier("get-old")
+ runOn(third) {
+ replicator ! Update(KeyE, ORMap.empty[String, GSet[String]], WriteLocal) { _ - "a" }
+ expectMsg(UpdateSuccess(KeyE, None))
+ }
+
+ enterBarrier("remove-element")
+
runOn(first) {
cluster.leave(node(third).address)
}
@@ -155,6 +179,25 @@ class ReplicatorPruningSpec extends MultiNodeSpec(ReplicatorPruningSpec) with ST
}
}
}
+ within(5.seconds) {
+ awaitAssert {
+ replicator ! Get(KeyD, ReadLocal)
+ expectMsgPF() {
+ case g @ GetSuccess(KeyD, _) ⇒
+ g.get(KeyD).entries("a") should be(Set("A"))
+ g.get(KeyD).needPruningFrom(thirdUniqueAddress) should be(false)
+ }
+ }
+ }
+ within(5.seconds) {
+ awaitAssert {
+ replicator ! Get(KeyE, ReadLocal)
+ expectMsgPF() {
+ case g @ GetSuccess(KeyE, _) ⇒
+ g.get(KeyE).needPruningFrom(thirdUniqueAddress) should be(false)
+ }
+ }
+ }
}
enterBarrier("pruning-done")
diff --git a/akka-distributed-data/src/test/scala/akka/cluster/ddata/LWWMapSpec.scala b/akka-distributed-data/src/test/scala/akka/cluster/ddata/LWWMapSpec.scala
index fd83e035af..37f364d393 100644
--- a/akka-distributed-data/src/test/scala/akka/cluster/ddata/LWWMapSpec.scala
+++ b/akka-distributed-data/src/test/scala/akka/cluster/ddata/LWWMapSpec.scala
@@ -47,6 +47,27 @@ class LWWMapSpec extends WordSpec with Matchers {
(m3 merge m4).entries should be(Map("a" → 1, "b" → 22, "c" → 3))
}
+ "be able to work with deltas" in {
+ val m1 = LWWMap.empty.put(node1, "a", 1, defaultClock[Int]).put(node1, "b", 2, defaultClock[Int])
+ val m2 = LWWMap.empty.put(node2, "c", 3, defaultClock[Int])
+
+ val expected = Map("a" → 1, "b" → 2, "c" → 3)
+ (m1 merge m2).entries should be(expected)
+ (m2 merge m1).entries should be(expected)
+
+ LWWMap.empty.mergeDelta(m1.delta.get).mergeDelta(m2.delta.get).entries should be(expected)
+ LWWMap.empty.mergeDelta(m2.delta.get).mergeDelta(m1.delta.get).entries should be(expected)
+
+ val merged1 = m1 merge m2
+
+ val m3 = merged1.resetDelta.remove(node1, "b")
+ (merged1 mergeDelta m3.delta.get).entries should be(Map("a" → 1, "c" → 3))
+
+ // but if there is a conflicting update the entry is not removed
+ val m4 = merged1.resetDelta.put(node2, "b", 22, defaultClock[Int])
+ (m3 mergeDelta m4.delta.get).entries should be(Map("a" → 1, "b" → 22, "c" → 3))
+ }
+
"have unapply extractor" in {
val m1 = LWWMap.empty.put(node1, "a", 1L, defaultClock[Long])
val LWWMap(entries1) = m1
diff --git a/akka-distributed-data/src/test/scala/akka/cluster/ddata/ORMapSpec.scala b/akka-distributed-data/src/test/scala/akka/cluster/ddata/ORMapSpec.scala
index 3b25721794..a9d245d1c4 100644
--- a/akka-distributed-data/src/test/scala/akka/cluster/ddata/ORMapSpec.scala
+++ b/akka-distributed-data/src/test/scala/akka/cluster/ddata/ORMapSpec.scala
@@ -30,12 +30,43 @@ class ORMapSpec extends WordSpec with Matchers {
}
+ "be able to add entries with deltas" in {
+ val m = ORMap().put(node1, "a", GSet() + "A").put(node1, "b", GSet() + "B")
+ val md = m.delta.get
+
+ val m1 = ORMap().mergeDelta(md)
+
+ val GSet(a) = m1.entries("a")
+ a should be(Set("A"))
+ val GSet(b) = m1.entries("b")
+ b should be(Set("B"))
+
+ val m2 = m1.put(node1, "a", GSet() + "C")
+ val GSet(a2) = m2.entries("a")
+ a2 should be(Set("C"))
+
+ }
+
"be able to remove entry" in {
val m = ORMap().put(node1, "a", GSet() + "A").put(node1, "b", GSet() + "B").remove(node1, "a")
m.entries.keySet should not contain ("a")
m.entries.keySet should contain("b")
}
+ "be able to remove entry using a delta" in {
+ val m = ORMap().put(node1, "a", GSet() + "A").put(node1, "b", GSet() + "B")
+ val addDelta = m.delta.get
+
+ val removeDelta = m.resetDelta.remove(node1, "a").delta.get
+
+ val m1 = ORMap().mergeDelta(addDelta)
+ m1.entries.keySet should contain("a")
+
+ val m2 = m1.mergeDelta(removeDelta)
+ m2.entries.keySet should not contain ("a")
+ m2.entries.keySet should contain("b")
+ }
+
"be able to add removed" in {
val m = ORMap().put(node1, "a", GSet() + "A").put(node1, "b", GSet() + "B").remove(node1, "a")
m.entries.keySet should not contain ("a")
@@ -110,6 +141,330 @@ class ORMapSpec extends WordSpec with Matchers {
merged2.entries("c").elements should be(Set("C"))
}
+ "not have anomalies for remove+updated scenario and deltas" in {
+ val m1 = ORMap.empty.put(node1, "a", GSet.empty + "A").put(node1, "b", GSet.empty + "B")
+ val m2 = ORMap.empty.put(node2, "c", GSet.empty + "C")
+
+ val merged1 = m1 merge m2
+
+ val m3 = merged1.resetDelta.remove(node1, "b")
+ val m4 = merged1.resetDelta.updated(node1, "b", GSet.empty[String])(_.add("B2"))
+
+ val merged2 = m3 merge m4
+
+ merged2.entries("a").elements should be(Set("A"))
+ // note that B is included, because GSet("B") is merged with GSet("B2")
+ merged2.entries("b").elements should be(Set("B", "B2"))
+ merged2.entries("c").elements should be(Set("C"))
+
+ val merged3 = m3 mergeDelta m4.delta.get
+
+ merged3.entries("a").elements should be(Set("A"))
+ // note that B is included, because GSet("B") is merged with GSet("B2")
+ merged3.entries("b").elements should be(Set("B", "B2"))
+ merged3.entries("c").elements should be(Set("C"))
+ }
+
+ "not have anomalies for remove+updated scenario and deltas 2" in {
+ val m1 = ORMap.empty.put(node1, "a", ORSet.empty.add(node1, "A")).put(node1, "b", ORSet.empty.add(node1, "B"))
+ val m2 = ORMap.empty.put(node2, "c", ORSet.empty.add(node2, "C"))
+
+ val merged1 = m1 merge m2
+
+ val m3 = merged1.resetDelta.remove(node1, "b")
+ val m4 = merged1.resetDelta.remove(node1, "b").updated(node1, "b", ORSet.empty[String])(_.add(node1, "B2"))
+
+ val merged2 = m3 merge m4
+
+ merged2.entries("a").elements should be(Set("A"))
+ // note that B is not included, because it was removed in both timelines
+ merged2.entries("b").elements should be(Set("B2"))
+ merged2.entries("c").elements should be(Set("C"))
+
+ val merged3 = m3 mergeDelta m4.delta.get
+
+ merged3.entries("a").elements should be(Set("A"))
+ // note that B is not included, because it was removed in both timelines
+ merged3.entries("b").elements should be(Set("B2"))
+ merged3.entries("c").elements should be(Set("C"))
+ }
+
+ "not have anomalies for remove+updated scenario and deltas 3" in {
+ val m1 = ORMap.empty.put(node1, "a", ORSet.empty.add(node1, "A")).put(node1, "b", ORSet.empty.add(node1, "B"))
+ val m2 = ORMap.empty.put(node2, "c", ORSet.empty.add(node2, "C"))
+
+ val merged1 = m1 merge m2
+
+ val m3 = merged1.resetDelta.remove(node1, "b")
+ val m4 = merged1.resetDelta.remove(node2, "b").updated(node2, "b", ORSet.empty[String])(_.add(node2, "B2"))
+
+ val merged2 = m3 merge m4
+
+ merged2.entries("a").elements should be(Set("A"))
+ // note that B is not included, because it was removed in both timelines
+ merged2.entries("b").elements should be(Set("B2"))
+ merged2.entries("c").elements should be(Set("C"))
+
+ val merged3 = m3 mergeDelta m4.delta.get
+
+ merged3.entries("a").elements should be(Set("A"))
+ // note that B is not included, because it was removed in both timelines
+ merged3.entries("b").elements should be(Set("B2"))
+ merged3.entries("c").elements should be(Set("C"))
+ }
+
+ "not have anomalies for remove+updated scenario and deltas 4" in {
+ val m1 = ORMap.empty.put(node1, "a", ORSet.empty.add(node1, "A")).put(node1, "b", ORSet.empty.add(node1, "B"))
+ val m2 = ORMap.empty.put(node2, "c", ORSet.empty.add(node2, "C"))
+
+ val merged1 = m1 merge m2
+
+ val m3 = merged1.resetDelta.remove(node1, "b")
+ val m4 = merged1.resetDelta.updated(node1, "b", ORSet.empty[String])(_.add(node1, "B2"))
+
+ val merged2 = m3 merge m4
+
+ merged2.entries("a").elements should be(Set("A"))
+ // note that B is included, because ORSet("B") is merged with ORSet("B2")
+ merged2.entries("b").elements should be(Set("B", "B2"))
+ merged2.entries("c").elements should be(Set("C"))
+
+ val merged3 = m3 mergeDelta m4.delta.get
+
+ merged3.entries("a").elements should be(Set("A"))
+ // note that B is included, because ORSet("B") is merged with ORSet("B2")
+ merged3.entries("b").elements should be(Set("B", "B2"))
+ merged3.entries("c").elements should be(Set("C"))
+ }
+
+ "not have anomalies for remove+updated scenario and deltas 5" in {
+ val m1 = ORMap.empty.put(node1, "a", GSet.empty + "A").put(node1, "b", GSet.empty + "B")
+ val m2 = ORMap.empty.put(node2, "c", GSet.empty + "C")
+
+ val merged1 = m1 merge m2
+
+ val m3 = merged1.resetDelta.remove(node1, "b")
+ val m4 = merged1.resetDelta.put(node2, "b", GSet.empty + "B2")
+
+ val merged2 = m3 merge m4
+
+ merged2.entries("a").elements should be(Set("A"))
+ // note that B is not included, because it was removed in both timelines
+ merged2.entries("b").elements should be(Set("B2"))
+ merged2.entries("c").elements should be(Set("C"))
+
+ val merged3 = m3 mergeDelta m4.delta.get
+
+ merged3.entries("a").elements should be(Set("A"))
+ // note that B is not included, because it was removed in both timelines
+ merged3.entries("b").elements should be(Set("B2"))
+ merged3.entries("c").elements should be(Set("C"))
+ }
+
+ "not have anomalies for remove+updated scenario and deltas 6" in {
+ val m1 = ORMap.empty.put(node1, "a", ORSet.empty.add(node1, "A")).put(node1, "b", ORSet.empty.add(node1, "B"))
+ val m2 = ORMap.empty.put(node2, "b", ORSet.empty.add(node2, "B3"))
+
+ val merged1 = m1 merge m2
+
+ val m3 = merged1.resetDelta.remove(node1, "b")
+ val m4 = merged1.resetDelta.remove(node2, "b").updated(node2, "b", ORSet.empty[String])(_.add(node2, "B1"))
+ .updated(node2, "b", ORSet.empty[String])(_.add(node2, "B2"))
+
+ val merged2 = m3 merge m4
+
+ merged2.entries("a").elements should be(Set("A"))
+ // note that B is not included, because it was removed in both timelines
+ merged2.entries("b").elements should be(Set("B1", "B2"))
+
+ val merged3 = m3 mergeDelta m4.delta.get
+
+ merged3.entries("a").elements should be(Set("A"))
+ // note that B is not included, because it was removed in both timelines
+ merged3.entries("b").elements should be(Set("B1", "B2"))
+ }
+
+ "not have anomalies for remove+updated scenario and deltas 7" in {
+ val m1 = ORMap.empty.put(node1, "a", ORSet.empty.add(node1, "A"))
+ .put(node1, "b", ORSet.empty.add(node1, "B1")).remove(node1, "b")
+ val m2 = ORMap.empty.put(node1, "a", ORSet.empty.add(node1, "A")).put(node1, "b", ORSet.empty.add(node1, "B2"))
+ val m2d = m2.resetDelta.remove(node1, "b")
+ val m2u = m2.resetDelta.updated(node1, "b", ORSet.empty[String])(_.add(node1, "B3"))
+ .updated(node2, "b", ORSet.empty[String])(_.add(node2, "B4"))
+
+ val merged1 = (m1 merge m2d) mergeDelta m2u.delta.get
+
+ merged1.entries("a").elements should be(Set("A"))
+ // note that B1 is lost as it was added and removed earlier in timeline than B2
+ merged1.entries("b").elements should be(Set("B2", "B3", "B4"))
+ }
+
+ "not have anomalies for remove+updated scenario and deltas 8" in {
+ val m1 = ORMap.empty.put(node1, "a", GSet.empty + "A")
+ .put(node1, "b", GSet.empty + "B").put(node2, "b", GSet.empty + "B")
+ val m2 = ORMap.empty.put(node2, "c", GSet.empty + "C")
+
+ val merged1 = m1 merge m2
+
+ val m3 = merged1.resetDelta.remove(node1, "b").remove(node2, "b")
+ val m4 = merged1.resetDelta.put(node2, "b", GSet.empty + "B2").put(node2, "b", GSet.empty + "B3")
+
+ val merged2 = m3 merge m4
+
+ merged2.entries("a").elements should be(Set("A"))
+ merged2.entries("b").elements should be(Set("B3"))
+ merged2.entries("c").elements should be(Set("C"))
+
+ val merged3 = (merged1 mergeDelta m3.delta.get) mergeDelta m4.delta.get
+
+ merged3.entries("a").elements should be(Set("A"))
+ merged3.entries("b").elements should be(Set("B3"))
+ merged3.entries("c").elements should be(Set("C"))
+ }
+
+ "not have anomalies for remove+updated scenario and deltas 9" in {
+ val m1 = ORMap.empty.put(node1, "a", GSet.empty + "A")
+ .put(node1, "b", GSet.empty + "B").put(node2, "b", GSet.empty + "B")
+ val m2 = ORMap.empty.put(node2, "c", GSet.empty + "C")
+
+ val merged1 = m1 merge m2
+
+ val m3 = merged1.resetDelta.remove(node1, "b").remove(node2, "b")
+ val m4 = merged1.resetDelta.updated(node2, "b", GSet.empty[String])(_.add("B2"))
+ .updated(node2, "b", GSet.empty[String])(_.add("B3"))
+
+ val merged2 = m3 merge m4
+
+ merged2.entries("a").elements should be(Set("A"))
+ merged2.entries("b").elements should be(Set("B2", "B3"))
+ merged2.entries("c").elements should be(Set("C"))
+
+ val merged3 = (merged1 mergeDelta m3.delta.get) mergeDelta m4.delta.get
+
+ merged3.entries("a").elements should be(Set("A"))
+ merged3.entries("b").elements should be(Set("B2", "B3"))
+ merged3.entries("c").elements should be(Set("C"))
+ }
+
+ "not have anomalies for remove+updated scenario and deltas 10" in {
+ val m1 = ORMap.empty.put(node2, "a", GSet.empty + "A")
+ .put(node2, "b", GSet.empty + "B")
+
+ val m3 = m1.resetDelta.remove(node2, "b")
+ val m4 = m3.resetDelta.put(node2, "b", GSet.empty + "B2").updated(node2, "b", GSet.empty[String])(_.add("B3"))
+
+ val merged2 = m3 merge m4
+
+ merged2.entries("a").elements should be(Set("A"))
+ merged2.entries("b").elements should be(Set("B2", "B3"))
+
+ val merged3 = m3 mergeDelta m4.delta.get
+
+ merged3.entries("a").elements should be(Set("A"))
+ merged3.entries("b").elements should be(Set("B2", "B3"))
+ }
+
+ "have the usual anomalies for remove+updated scenario" in {
+ // please note that the current ORMultiMap has the same anomaly
+ // because the condition of keeping global vvector is violated
+ // by removal of the whole entry for the removed key "b" which results in removal of it's value's vvector
+ val m1 = ORMap.empty.put(node1, "a", ORSet.empty.add(node1, "A")).put(node1, "b", ORSet.empty.add(node1, "B"))
+ val m2 = ORMap.empty.put(node2, "c", ORSet.empty.add(node2, "C"))
+
+ // m1 - node1 gets the update from m2
+ val merged1 = m1 merge m2
+ // m2 - node2 gets the update from m1
+ val merged2 = m2 merge m1
+
+ // RACE CONDITION ahead!
+ val m3 = merged1.resetDelta.remove(node1, "b")
+ // let's imagine that m3 (node1) update gets propagated here (full state or delta - doesn't matter)
+ // and is in flight, but in the meantime, an element is being added somewhere else (m4 - node2)
+ // and the update is propagated before the update from node1 is merged
+ val m4 = merged2.resetDelta.updated(node2, "b", ORSet.empty[String])(_.add(node2, "B2"))
+ // and later merged on node1
+ val merged3 = m3 merge m4
+ // and the other way round...
+ val merged4 = m4 merge m3
+
+ // result - the element "B" is kept on both sides...
+ merged3.entries("a").elements should be(Set("A"))
+ merged3.entries("b").elements should be(Set("B", "B2"))
+ merged3.entries("c").elements should be(Set("C"))
+
+ merged4.entries("a").elements should be(Set("A"))
+ merged4.entries("b").elements should be(Set("B", "B2"))
+ merged4.entries("c").elements should be(Set("C"))
+
+ // but if the timing was slightly different, so that the update from node1
+ // would get merged just before update on node2:
+ val merged5 = (m2 merge m3).resetDelta.updated(node2, "b", ORSet.empty[String])(_.add(node2, "B2"))
+ // the update propagated ... and merged on node1:
+ val merged6 = m3 merge merged5
+
+ // then the outcome is different... because the vvector of value("b") was lost...
+ merged5.entries("a").elements should be(Set("A"))
+ // this time it's different...
+ merged5.entries("b").elements should be(Set("B2"))
+ merged5.entries("c").elements should be(Set("C"))
+
+ merged6.entries("a").elements should be(Set("A"))
+ // this time it's different...
+ merged6.entries("b").elements should be(Set("B2"))
+ merged6.entries("c").elements should be(Set("C"))
+ }
+
+ "work with deltas and updated for GSet elements type" in {
+ val m1 = ORMap.empty.put(node1, "a", GSet.empty + "A")
+ val m2 = m1.resetDelta.updated(node1, "a", GSet.empty[String])(_.add("B"))
+ val m3 = ORMap().mergeDelta(m1.delta.get).mergeDelta(m2.delta.get)
+ val GSet(d3) = m3.entries("a")
+ d3 should be(Set("A", "B"))
+ }
+
+ "work with deltas and updated for ORSet elements type" in {
+ val m1 = ORMap.empty.put(node1, "a", ORSet.empty.add(node1, "A"))
+ val m2 = m1.resetDelta.updated(node1, "a", ORSet.empty[String])(_.add(node1, "B"))
+ val m3 = ORMap().mergeDelta(m1.delta.get).mergeDelta(m2.delta.get)
+
+ val ORSet(d3) = m3.entries("a")
+ d3 should be(Set("A", "B"))
+ }
+
+ "work with aggregated deltas and updated for GSet elements type" in {
+ val m1 = ORMap.empty.put(node1, "a", GSet.empty + "A")
+ val m2 = m1.resetDelta.updated(node1, "a", GSet.empty[String])(_.add("B")).updated(node1, "a", GSet.empty[String])(_.add("C"))
+ val m3 = ORMap().mergeDelta(m1.delta.get).mergeDelta(m2.delta.get)
+ val GSet(d3) = m3.entries("a")
+ d3 should be(Set("A", "B", "C"))
+ }
+
+ "work with deltas and updated for GCounter elements type" in {
+ val m1 = ORMap.empty.put(node1, "a", GCounter.empty)
+ val m2 = m1.resetDelta.updated(node1, "a", GCounter.empty)(_.increment(node1, 10))
+ val m3 = m2.resetDelta.updated(node2, "a", GCounter.empty)(_.increment(node2, 10))
+ val m4 = ORMap().mergeDelta(m1.delta.get).mergeDelta(m2.delta.get).mergeDelta(m3.delta.get)
+ val GCounter(num) = m4.entries("a")
+ num should ===(20)
+ }
+
+ "work with deltas and updated for PNCounter elements type" in {
+ val m1 = ORMap.empty.put(node1, "a", PNCounter.empty)
+ val m2 = m1.resetDelta.updated(node1, "a", PNCounter.empty)(_.increment(node1, 10))
+ val m3 = m2.resetDelta.updated(node2, "a", PNCounter.empty)(_.decrement(node2, 10))
+ val m4 = ORMap().mergeDelta(m1.delta.get).mergeDelta(m2.delta.get).mergeDelta(m3.delta.get)
+ val PNCounter(num) = m4.entries("a")
+ num should ===(0)
+ }
+
+ "work with deltas and updated for Flag elements type" in {
+ val m1 = ORMap.empty.put(node1, "a", Flag(false))
+ val m2 = m1.resetDelta.updated(node1, "a", Flag.empty)(_.switchOn)
+ val m3 = ORMap().mergeDelta(m1.delta.get).mergeDelta(m2.delta.get)
+ val Flag(d3) = m3.entries("a")
+ d3 should be(true)
+ }
+
"not allow put for ORSet elements type" in {
val m = ORMap().put(node1, "a", ORSet().add(node1, "A"))
diff --git a/akka-distributed-data/src/test/scala/akka/cluster/ddata/ORMultiMapSpec.scala b/akka-distributed-data/src/test/scala/akka/cluster/ddata/ORMultiMapSpec.scala
index c3bc3f49c0..f95af2c934 100644
--- a/akka-distributed-data/src/test/scala/akka/cluster/ddata/ORMultiMapSpec.scala
+++ b/akka-distributed-data/src/test/scala/akka/cluster/ddata/ORMultiMapSpec.scala
@@ -77,6 +77,12 @@ class ORMultiMapSpec extends WordSpec with Matchers {
val merged2 = m2 merge m1
merged2.entries should be(expectedMerged)
+
+ val merged3 = m1 mergeDelta m2.delta.get
+ merged3.entries should be(expectedMerged)
+
+ val merged4 = m2 mergeDelta m1.delta.get
+ merged4.entries should be(expectedMerged)
}
}
@@ -107,6 +113,74 @@ class ORMultiMapSpec extends WordSpec with Matchers {
m2.entries should be(Map("b" → Set("B1")))
}
+ "not have usual anomalies for remove+addBinding scenario and delta-deltas" in {
+ val m1 = ORMultiMap.emptyWithValueDeltas[String, String].put(node1, "a", Set("A")).put(node1, "b", Set("B"))
+ val m2 = ORMultiMap.emptyWithValueDeltas[String, String].put(node2, "c", Set("C"))
+
+ val merged1 = m1 merge m2
+
+ val m3 = merged1.resetDelta.remove(node1, "b")
+ val m4 = merged1.resetDelta.addBinding(node1, "b", "B2")
+
+ val merged2 = m3 merge m4
+
+ merged2.entries("a") should be(Set("A"))
+ merged2.entries("b") should be(Set("B2"))
+ merged2.entries("c") should be(Set("C"))
+
+ val merged3 = m3 mergeDelta m4.delta.get
+
+ merged3.entries("a") should be(Set("A"))
+ merged3.entries("b") should be(Set("B2"))
+ merged3.entries("c") should be(Set("C"))
+ }
+
+ "not have usual anomalies for remove+addBinding scenario and delta-deltas 2" in {
+ // the new delta-delta ORMultiMap is free from this anomaly
+ val m1 = ORMultiMap.emptyWithValueDeltas[String, String].put(node1, "a", Set("A")).put(node1, "b", Set("B"))
+ val m2 = ORMultiMap.emptyWithValueDeltas[String, String].put(node2, "c", Set("C"))
+
+ // m1 - node1 gets the update from m2
+ val merged1 = m1 merge m2
+ // m2 - node2 gets the update from m1
+ val merged2 = m2 merge m1
+
+ // no race condition
+ val m3 = merged1.resetDelta.remove(node1, "b")
+ // let's imagine that m3 (node1) update gets propagated here (full state or delta - doesn't matter)
+ // and is in flight, but in the meantime, an element is being added somewhere else (m4 - node2)
+ // and the update is propagated before the update from node1 is merged
+ val m4 = merged2.resetDelta.addBinding(node2, "b", "B2")
+ // and later merged on node1
+ val merged3 = m3 merge m4
+ // and the other way round...
+ val merged4 = m4 merge m3
+
+ // result - the element "B" is kept on both sides...
+ merged3.entries("a") should be(Set("A"))
+ merged3.entries("b") should be(Set("B2"))
+ merged3.entries("c") should be(Set("C"))
+
+ merged4.entries("a") should be(Set("A"))
+ merged4.entries("b") should be(Set("B2"))
+ merged4.entries("c") should be(Set("C"))
+
+ // but if the timing was slightly different, so that the update from node1
+ // would get merged just before update on node2:
+ val merged5 = (m2 merge m3).resetDelta.addBinding(node2, "b", "B2")
+ // the update propagated ... and merged on node1:
+ val merged6 = m3 merge merged5
+
+ // then the outcome would be the same...
+ merged5.entries("a") should be(Set("A"))
+ merged5.entries("b") should be(Set("B2"))
+ merged5.entries("c") should be(Set("C"))
+
+ merged6.entries("a") should be(Set("A"))
+ merged6.entries("b") should be(Set("B2"))
+ merged6.entries("c") should be(Set("C"))
+ }
+
"have unapply extractor" in {
val m1 = ORMultiMap.empty.put(node1, "a", Set(1L, 2L)).put(node2, "b", Set(3L))
val m2: ORMultiMap[String, Long] = m1
diff --git a/akka-distributed-data/src/test/scala/akka/cluster/ddata/PNCounterMapSpec.scala b/akka-distributed-data/src/test/scala/akka/cluster/ddata/PNCounterMapSpec.scala
index 3960c3fd99..5ac4915a33 100644
--- a/akka-distributed-data/src/test/scala/akka/cluster/ddata/PNCounterMapSpec.scala
+++ b/akka-distributed-data/src/test/scala/akka/cluster/ddata/PNCounterMapSpec.scala
@@ -46,6 +46,24 @@ class PNCounterMapSpec extends WordSpec with Matchers {
(m3 merge m4).entries should be(Map("a" → 1, "b" → 13, "c" → 7))
}
+ "be able to work with deltas" in {
+ val m1 = PNCounterMap().increment(node1, "a", 1).increment(node1, "b", 3).increment(node1, "c", 2)
+ val m2 = PNCounterMap().increment(node2, "c", 5)
+
+ val expected = Map("a" → 1, "b" → 3, "c" → 7)
+ (PNCounterMap() mergeDelta m1.delta.get mergeDelta m2.delta.get).entries should be(expected)
+ (PNCounterMap() mergeDelta m2.delta.get mergeDelta m1.delta.get).entries should be(expected)
+
+ val merged1 = m1 merge m2
+
+ val m3 = merged1.resetDelta.remove(node1, "b")
+ (merged1 mergeDelta m3.delta.get).entries should be(Map("a" → 1, "c" → 7))
+
+ // but if there is a conflicting update the entry is not removed
+ val m4 = merged1.resetDelta.increment(node2, "b", 10)
+ (m3 mergeDelta m4.delta.get).entries should be(Map("a" → 1, "b" → 13, "c" → 7))
+ }
+
"have unapply extractor" in {
val m1 = PNCounterMap.empty.increment(node1, "a", 1).increment(node2, "b", 2)
val PNCounterMap(entries1) = m1
diff --git a/akka-distributed-data/src/test/scala/akka/cluster/ddata/protobuf/ReplicatedDataSerializerSpec.scala b/akka-distributed-data/src/test/scala/akka/cluster/ddata/protobuf/ReplicatedDataSerializerSpec.scala
index 4e53e1045e..b77c363f2b 100644
--- a/akka-distributed-data/src/test/scala/akka/cluster/ddata/protobuf/ReplicatedDataSerializerSpec.scala
+++ b/akka-distributed-data/src/test/scala/akka/cluster/ddata/protobuf/ReplicatedDataSerializerSpec.scala
@@ -184,6 +184,23 @@ class ReplicatedDataSerializerSpec extends TestKit(ActorSystem(
checkSerialization(ORMap().put(address1, Flag(), GSet() + "A"))
}
+ "serialize ORMap delta" in {
+ checkSerialization(ORMap().put(address1, "a", GSet() + "A").put(address2, "b", GSet() + "B").delta.get)
+ checkSerialization(ORMap().put(address1, "a", GSet() + "A").resetDelta.remove(address2, "a").delta.get)
+ checkSerialization(ORMap().put(address1, "a", GSet() + "A").remove(address2, "a").delta.get)
+ checkSerialization(ORMap().put(address1, 1, GSet() + "A").delta.get)
+ checkSerialization(ORMap().put(address1, 1L, GSet() + "A").delta.get)
+ checkSerialization(ORMap.empty[String, ORSet[String]]
+ .put(address1, "a", ORSet.empty[String].add(address1, "A"))
+ .put(address2, "b", ORSet.empty[String].add(address2, "B"))
+ .updated(address1, "a", ORSet.empty[String])(_.add(address1, "C")).delta.get)
+ checkSerialization(ORMap.empty[String, ORSet[String]]
+ .resetDelta
+ .updated(address1, "a", ORSet.empty[String])(_.add(address1, "C")).delta.get)
+ // use Flag for this test as object key because it is serializable
+ checkSerialization(ORMap().put(address1, Flag(), GSet() + "A").delta.get)
+ }
+
"be compatible with old ORMap serialization" in {
// Below blob was created with previous version of the serializer
val oldBlobAsBase64 = "H4sIAAAAAAAAAOOax8jlyaXMJc8lzMWXX5KRWqSXkV9copdflC7wXEWUiYGBQRaIGQQkuJS45LiEuHiL83NTUdQwwtWIC6kQpUqVKAulGBOlGJOE+LkYE4W4uJi5GB0FuJUYnUACSRABJ7AAAOLO3C3DAAAA"
@@ -244,6 +261,22 @@ class ReplicatedDataSerializerSpec extends TestKit(ActorSystem(
checkCompatibility(oldBlobAsBase64, ORMultiMap())
}
+ "serialize ORMultiMap withValueDeltas" in {
+ checkSerialization(ORMultiMap._emptyWithValueDeltas)
+ checkSerialization(ORMultiMap._emptyWithValueDeltas.addBinding(address1, "a", "A"))
+ checkSerialization(ORMultiMap._emptyWithValueDeltas.addBinding(address1, 1, "A"))
+ checkSerialization(ORMultiMap._emptyWithValueDeltas.addBinding(address1, 1L, "A"))
+ checkSerialization(ORMultiMap._emptyWithValueDeltas.addBinding(address1, Flag(), "A"))
+ checkSerialization(ORMultiMap.emptyWithValueDeltas[String, String]
+ .addBinding(address1, "a", "A1")
+ .put(address2, "b", Set("B1", "B2", "B3"))
+ .addBinding(address2, "a", "A2"))
+
+ val m1 = ORMultiMap.emptyWithValueDeltas[String, String].addBinding(address1, "a", "A1").addBinding(address2, "a", "A2")
+ val m2 = ORMultiMap.emptyWithValueDeltas[String, String].put(address2, "b", Set("B1", "B2", "B3"))
+ checkSameContent(m1.merge(m2), m2.merge(m1))
+ }
+
"serialize DeletedData" in {
checkSerialization(DeletedData)
}