Skip to content

Commit 3179bec

Browse files
committed
Merge branch 'master' of github.com:apple/swift-distributed-actors
2 parents 12b7d87 + 810710c commit 3179bec

File tree

6 files changed

+130
-47
lines changed

6 files changed

+130
-47
lines changed

Protos/CRDT/CRDT.proto

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,15 @@ message CRDTORMap {
9898
message Delta {
9999
CRDTVersionedContainerDelta keys = 1;
100100
repeated CRDTORMapKeyValue values = 2;
101+
CRDTORMapValue defaultValue = 3;
101102
}
102103

103104
VersionReplicaID replicaID = 1;
104105
CRDTORSet keys = 2;
105106
repeated CRDTORMapKeyValue values = 3;
106107
// Delta is derived from `updatedValues`
107108
repeated CRDTORMapKeyValue updatedValues = 4;
109+
CRDTORMapValue defaultValue = 5;
108110
}
109111

110112
// ***** CRDT.ORMultiMap *****

Sources/DistributedActors/CRDT/Protobuf/CRDT+Serialization.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,7 @@ extension CRDT.ORMap: ProtobufRepresentable {
319319
proto.keys = try self._keys.toProto(context: context)
320320
proto.values = try ORMapSerializationUtils.valuesToProto(self._storage, context: context)
321321
proto.updatedValues = try ORMapSerializationUtils.valuesToProto(self.updatedValues, context: context)
322+
proto.defaultValue = try ORMapSerializationUtils.valueToProto(self.defaultValue, context: context)
322323
return proto
323324
}
324325

@@ -335,7 +336,7 @@ extension CRDT.ORMap: ProtobufRepresentable {
335336

336337
self._storage = try ORMapSerializationUtils.valuesFromProto(proto.values, context: context)
337338
self.updatedValues = try ORMapSerializationUtils.valuesFromProto(proto.updatedValues, context: context)
338-
self.defaultValue = nil // We don't need remote's default value for merge
339+
self.defaultValue = try ORMapSerializationUtils.valueFromProto(proto.defaultValue, context: context)
339340
}
340341
}
341342

@@ -346,6 +347,7 @@ extension CRDT.ORMapDelta: ProtobufRepresentable {
346347
var proto = ProtobufRepresentation()
347348
proto.keys = try self.keys.toProto(context: context)
348349
proto.values = try ORMapSerializationUtils.valuesToProto(self.values, context: context)
350+
proto.defaultValue = try ORMapSerializationUtils.valueToProto(self.defaultValue, context: context)
349351
return proto
350352
}
351353

@@ -356,7 +358,7 @@ extension CRDT.ORMapDelta: ProtobufRepresentable {
356358
self.keys = try CRDT.ORSet<Key>.Delta(fromProto: proto.keys, context: context)
357359

358360
self.values = try ORMapSerializationUtils.valuesFromProto(proto.values, context: context)
359-
self.defaultValue = nil // We don't need remote's default value for merge
361+
self.defaultValue = try ORMapSerializationUtils.valueFromProto(proto.defaultValue, context: context)
360362
}
361363
}
362364

Sources/DistributedActors/CRDT/Protobuf/CRDT.pb.swift

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,15 @@ public struct ProtoCRDTORMap {
362362
set {_uniqueStorage()._updatedValues = newValue}
363363
}
364364

365+
public var defaultValue: ProtoCRDTORMapValue {
366+
get {return _storage._defaultValue ?? ProtoCRDTORMapValue()}
367+
set {_uniqueStorage()._defaultValue = newValue}
368+
}
369+
/// Returns true if `defaultValue` has been explicitly set.
370+
public var hasDefaultValue: Bool {return _storage._defaultValue != nil}
371+
/// Clears the value of `defaultValue`. Subsequent reads from it will return its default value.
372+
public mutating func clearDefaultValue() {_uniqueStorage()._defaultValue = nil}
373+
365374
public var unknownFields = SwiftProtobuf.UnknownStorage()
366375

367376
public struct Delta {
@@ -383,6 +392,15 @@ public struct ProtoCRDTORMap {
383392
set {_uniqueStorage()._values = newValue}
384393
}
385394

395+
public var defaultValue: ProtoCRDTORMapValue {
396+
get {return _storage._defaultValue ?? ProtoCRDTORMapValue()}
397+
set {_uniqueStorage()._defaultValue = newValue}
398+
}
399+
/// Returns true if `defaultValue` has been explicitly set.
400+
public var hasDefaultValue: Bool {return _storage._defaultValue != nil}
401+
/// Clears the value of `defaultValue`. Subsequent reads from it will return its default value.
402+
public mutating func clearDefaultValue() {_uniqueStorage()._defaultValue = nil}
403+
386404
public var unknownFields = SwiftProtobuf.UnknownStorage()
387405

388406
public init() {}
@@ -1278,13 +1296,15 @@ extension ProtoCRDTORMap: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement
12781296
2: .same(proto: "keys"),
12791297
3: .same(proto: "values"),
12801298
4: .same(proto: "updatedValues"),
1299+
5: .same(proto: "defaultValue"),
12811300
]
12821301

12831302
fileprivate class _StorageClass {
12841303
var _replicaID: ProtoVersionReplicaID? = nil
12851304
var _keys: ProtoCRDTORSet? = nil
12861305
var _values: [ProtoCRDTORMapKeyValue] = []
12871306
var _updatedValues: [ProtoCRDTORMapKeyValue] = []
1307+
var _defaultValue: ProtoCRDTORMapValue? = nil
12881308

12891309
static let defaultInstance = _StorageClass()
12901310

@@ -1295,6 +1315,7 @@ extension ProtoCRDTORMap: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement
12951315
_keys = source._keys
12961316
_values = source._values
12971317
_updatedValues = source._updatedValues
1318+
_defaultValue = source._defaultValue
12981319
}
12991320
}
13001321

@@ -1314,6 +1335,7 @@ extension ProtoCRDTORMap: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement
13141335
case 2: try decoder.decodeSingularMessageField(value: &_storage._keys)
13151336
case 3: try decoder.decodeRepeatedMessageField(value: &_storage._values)
13161337
case 4: try decoder.decodeRepeatedMessageField(value: &_storage._updatedValues)
1338+
case 5: try decoder.decodeSingularMessageField(value: &_storage._defaultValue)
13171339
default: break
13181340
}
13191341
}
@@ -1334,6 +1356,9 @@ extension ProtoCRDTORMap: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement
13341356
if !_storage._updatedValues.isEmpty {
13351357
try visitor.visitRepeatedMessageField(value: _storage._updatedValues, fieldNumber: 4)
13361358
}
1359+
if let v = _storage._defaultValue {
1360+
try visitor.visitSingularMessageField(value: v, fieldNumber: 5)
1361+
}
13371362
}
13381363
try unknownFields.traverse(visitor: &visitor)
13391364
}
@@ -1347,6 +1372,7 @@ extension ProtoCRDTORMap: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement
13471372
if _storage._keys != rhs_storage._keys {return false}
13481373
if _storage._values != rhs_storage._values {return false}
13491374
if _storage._updatedValues != rhs_storage._updatedValues {return false}
1375+
if _storage._defaultValue != rhs_storage._defaultValue {return false}
13501376
return true
13511377
}
13521378
if !storagesAreEqual {return false}
@@ -1361,11 +1387,13 @@ extension ProtoCRDTORMap.Delta: SwiftProtobuf.Message, SwiftProtobuf._MessageImp
13611387
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
13621388
1: .same(proto: "keys"),
13631389
2: .same(proto: "values"),
1390+
3: .same(proto: "defaultValue"),
13641391
]
13651392

13661393
fileprivate class _StorageClass {
13671394
var _keys: ProtoCRDTVersionedContainerDelta? = nil
13681395
var _values: [ProtoCRDTORMapKeyValue] = []
1396+
var _defaultValue: ProtoCRDTORMapValue? = nil
13691397

13701398
static let defaultInstance = _StorageClass()
13711399

@@ -1374,6 +1402,7 @@ extension ProtoCRDTORMap.Delta: SwiftProtobuf.Message, SwiftProtobuf._MessageImp
13741402
init(copying source: _StorageClass) {
13751403
_keys = source._keys
13761404
_values = source._values
1405+
_defaultValue = source._defaultValue
13771406
}
13781407
}
13791408

@@ -1391,6 +1420,7 @@ extension ProtoCRDTORMap.Delta: SwiftProtobuf.Message, SwiftProtobuf._MessageImp
13911420
switch fieldNumber {
13921421
case 1: try decoder.decodeSingularMessageField(value: &_storage._keys)
13931422
case 2: try decoder.decodeRepeatedMessageField(value: &_storage._values)
1423+
case 3: try decoder.decodeSingularMessageField(value: &_storage._defaultValue)
13941424
default: break
13951425
}
13961426
}
@@ -1405,6 +1435,9 @@ extension ProtoCRDTORMap.Delta: SwiftProtobuf.Message, SwiftProtobuf._MessageImp
14051435
if !_storage._values.isEmpty {
14061436
try visitor.visitRepeatedMessageField(value: _storage._values, fieldNumber: 2)
14071437
}
1438+
if let v = _storage._defaultValue {
1439+
try visitor.visitSingularMessageField(value: v, fieldNumber: 3)
1440+
}
14081441
}
14091442
try unknownFields.traverse(visitor: &visitor)
14101443
}
@@ -1416,6 +1449,7 @@ extension ProtoCRDTORMap.Delta: SwiftProtobuf.Message, SwiftProtobuf._MessageImp
14161449
let rhs_storage = _args.1
14171450
if _storage._keys != rhs_storage._keys {return false}
14181451
if _storage._values != rhs_storage._values {return false}
1452+
if _storage._defaultValue != rhs_storage._defaultValue {return false}
14191453
return true
14201454
}
14211455
if !storagesAreEqual {return false}

Sources/DistributedActors/CRDT/Types/CRDT+ORMap.swift

Lines changed: 12 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,9 @@ extension CRDT {
5656

5757
public let replicaID: ReplicaID
5858

59-
/// We allow `defaultValue` to be `nil` when we reconstruct `ORMap` from a remote message,
60-
/// but it **is** required in the initializer to ensure that **local** `ORMap` has `defaultValue`
61-
/// for `merge`, `update`, etc. In those methods `defaultValue` is required in case **local**
59+
/// The default value for `merge`, `update`, etc. in case **local**
6260
/// `ORMap` does not have an existing value for the given `key`.
63-
let defaultValue: Value?
61+
let defaultValue: Value
6462

6563
/// ORSet to maintain causal history of the keys only; values keep their own causal history (if applicable).
6664
/// This is for tracking key additions and removals.
@@ -110,15 +108,11 @@ extension CRDT {
110108
}
111109

112110
public mutating func update(key: Key, mutator: (inout Value) -> Void) {
113-
guard let defaultValue = self.defaultValue else {
114-
preconditionFailure("'defaultValue' is not set. This is a bug. Please report.")
115-
}
116-
117111
// Always add `key` to `_keys` set to track its causal history
118112
self._keys.insert(key)
119113

120114
// Apply `mutator` to the value then save it to state. Create `Value` if needed.
121-
var value = self._storage[key] ?? defaultValue
115+
var value = self._storage[key] ?? self.defaultValue
122116
mutator(&value)
123117
self._storage[key] = value
124118

@@ -161,25 +155,17 @@ extension CRDT {
161155
}
162156

163157
public mutating func merge(other: ORMap<Key, Value>) {
164-
guard let defaultValue = self.defaultValue else {
165-
preconditionFailure("'defaultValue' is not set. This is a bug. Please report.")
166-
}
167-
168158
self._keys.merge(other: other._keys)
169159
// Use the updated `_keys` to merge `_values` dictionaries.
170160
// Keys that no longer exist will have their values deleted as well.
171-
self._storage.merge(keys: self._keys.elements, other: other._storage, defaultValue: defaultValue)
161+
self._storage.merge(keys: self._keys.elements, other: other._storage, defaultValue: self.defaultValue)
172162
}
173163

174164
public mutating func mergeDelta(_ delta: Delta) {
175-
guard let defaultValue = self.defaultValue else {
176-
preconditionFailure("'defaultValue' is not set. This is a bug. Please report.")
177-
}
178-
179165
self._keys.mergeDelta(delta.keys)
180166
// Use the updated `_keys` to merge `_values` dictionaries.
181167
// Keys that no longer exist will have their values deleted as well.
182-
self._storage.merge(keys: self._keys.elements, other: delta.values, defaultValue: defaultValue)
168+
self._storage.merge(keys: self._keys.elements, other: delta.values, defaultValue: self.defaultValue)
183169
}
184170

185171
public mutating func resetDelta() {
@@ -192,13 +178,8 @@ extension CRDT {
192178
return false
193179
}
194180

195-
switch (self.defaultValue, other.defaultValue) {
196-
case (nil, nil):
197-
() // continue checking
198-
case (.some(let lhs), .some(let rhs)) where lhs.equalState(to: rhs):
199-
() // continue checking
200-
default:
201-
return false // values not equal
181+
guard self.defaultValue.equalState(to: other.defaultValue) else {
182+
return false
202183
}
203184

204185
guard self._storage.count == other._storage.count else {
@@ -230,10 +211,9 @@ extension CRDT {
230211
// TODO: `merge` defined in the Dictionary extension below should use `mergeDelta` when Value is DeltaCRDT
231212
var values: [Key: Value]
232213

233-
// See comment in `ORMap` on why this is optional
234-
let defaultValue: Value?
214+
let defaultValue: Value
235215

236-
init(keys: ORSet<Key>.Delta, values: [Key: Value], defaultValue: Value?) {
216+
init(keys: ORSet<Key>.Delta, values: [Key: Value], defaultValue: Value) {
237217
self.keys = keys
238218
self.values = values
239219
self.defaultValue = defaultValue
@@ -250,29 +230,20 @@ extension CRDT {
250230
}
251231

252232
public mutating func merge(other: ORMapDelta<Key, Value>) {
253-
guard let defaultValue = self.defaultValue else {
254-
preconditionFailure("Unable to merge [\(self)] with [\(other)] as 'defaultValue' is not set. This is a bug. Please report.")
255-
}
256-
257233
// Merge `keys` first--keys that have been deleted will be gone
258234
self.keys.merge(other: other.keys)
259235
// Use the updated `keys` to merge `values` dictionaries.
260236
// Keys that no longer exist will have their values deleted as well.
261-
self.values.merge(keys: self.keys.elements, other: other.values, defaultValue: defaultValue)
237+
self.values.merge(keys: self.keys.elements, other: other.values, defaultValue: self.defaultValue)
262238
}
263239

264240
public func equalState(to other: StateBasedCRDT) -> Bool {
265241
guard let other = other as? Self else {
266242
return false
267243
}
268244

269-
switch (self.defaultValue, other.defaultValue) {
270-
case (nil, nil):
271-
() // continue checking
272-
case (.some(let lhs), .some(let rhs)) where lhs.equalState(to: rhs):
273-
() // continue checking
274-
default:
275-
return false // values not equal
245+
guard self.defaultValue.equalState(to: other.defaultValue) else {
246+
return false
276247
}
277248

278249
guard self.values.count == other.values.count else {

0 commit comments

Comments
 (0)