Change some types from class to struct to avoid data racing (#33)
* Change the type of ChangePack from class to struct * Change ``Change`` and types confirming ``Operation`` from class to struct
This commit is contained in:
parent
b91f55d056
commit
ab0d8c92e9
|
@ -19,11 +19,11 @@ import Foundation
|
|||
/**
|
||||
* `Change` represents a unit of modification in the document.
|
||||
*/
|
||||
class Change {
|
||||
struct Change {
|
||||
private var id: ChangeID
|
||||
|
||||
// `operations` represent a series of user edits.
|
||||
private let operations: [Operation]
|
||||
private var operations: [Operation]
|
||||
|
||||
// `message` is used to save a description of the change.
|
||||
private let message: String?
|
||||
|
@ -58,11 +58,14 @@ class Change {
|
|||
/**
|
||||
* `setActor` sets the given actor.
|
||||
*/
|
||||
func setActor(_ actorID: ActorID) {
|
||||
self.operations.forEach {
|
||||
$0.setActor(actorID)
|
||||
mutating func setActor(_ actorID: ActorID) {
|
||||
let operations = self.operations.map {
|
||||
var new = $0
|
||||
new.setActor(actorID)
|
||||
return new
|
||||
}
|
||||
|
||||
self.operations = operations
|
||||
self.id.setActor(actorID)
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ import Foundation
|
|||
/**
|
||||
* `ChangePack` is a unit for delivering changes in a document to the remote.
|
||||
*/
|
||||
class ChangePack {
|
||||
struct ChangePack {
|
||||
/**
|
||||
* `documentKey` is the key of the document.
|
||||
*/
|
||||
|
@ -41,7 +41,7 @@ class ChangePack {
|
|||
* `minSyncedTicket` is the minimum logical time taken by clients who attach
|
||||
* the document. It used to collect garbage on the replica on the client.
|
||||
*/
|
||||
private var minSyncedTicket: TimeTicket?
|
||||
private let minSyncedTicket: TimeTicket?
|
||||
|
||||
init(key: String, checkpoint: Checkpoint, changes: [Change], snapshot: Data? = nil, minSyncedTicket: TimeTicket? = nil) {
|
||||
self.documentKey = key
|
||||
|
|
|
@ -148,9 +148,14 @@ public actor Document {
|
|||
*
|
||||
*/
|
||||
func setActor(_ actorID: ActorID) {
|
||||
for change in self.localChanges {
|
||||
change.setActor(actorID)
|
||||
let changes = self.localChanges.map {
|
||||
var new = $0
|
||||
new.setActor(actorID)
|
||||
return new
|
||||
}
|
||||
|
||||
self.localChanges = changes
|
||||
|
||||
self.changeID.setActor(actorID)
|
||||
|
||||
// TODOs also apply into root.
|
||||
|
|
|
@ -19,7 +19,7 @@ import Foundation
|
|||
/**
|
||||
* `AddOperation` is an operation representing adding an element to an Array.
|
||||
*/
|
||||
class AddOperation: Operation {
|
||||
struct AddOperation: Operation {
|
||||
let parentCreatedAt: TimeTicket
|
||||
var executedAt: TimeTicket
|
||||
private var previousCreatedAt: TimeTicket
|
||||
|
|
|
@ -19,7 +19,7 @@ import Foundation
|
|||
/**
|
||||
* `MoveOperation` is an operation representing moving an element to an Array.
|
||||
*/
|
||||
class MoveOperation: Operation {
|
||||
struct MoveOperation: Operation {
|
||||
let parentCreatedAt: TimeTicket
|
||||
var executedAt: TimeTicket
|
||||
private var previousCreatedAt: TimeTicket
|
||||
|
|
|
@ -18,8 +18,9 @@ import Foundation
|
|||
|
||||
/**
|
||||
* `Operation` represents an operation to be executed on a document.
|
||||
* Types confiming ``Operation`` must be struct to avoid data racing.
|
||||
*/
|
||||
protocol Operation: AnyObject {
|
||||
protocol Operation {
|
||||
var parentCreatedAt: TimeTicket { get }
|
||||
var executedAt: TimeTicket { get set }
|
||||
|
||||
|
@ -58,7 +59,7 @@ extension Operation {
|
|||
/**
|
||||
* `setActor` sets the given actor to this operation.
|
||||
*/
|
||||
func setActor(_ actorID: ActorID) {
|
||||
mutating func setActor(_ actorID: ActorID) {
|
||||
self.executedAt.setActor(actorID)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ import Foundation
|
|||
/**
|
||||
* `RemoveOperation` is an operation representing removes an element from Container.
|
||||
*/
|
||||
class RemoveOperation: Operation {
|
||||
struct RemoveOperation: Operation {
|
||||
let parentCreatedAt: TimeTicket
|
||||
var executedAt: TimeTicket
|
||||
private var createdAt: TimeTicket
|
||||
|
|
|
@ -20,7 +20,7 @@ import Foundation
|
|||
* `SetOperation` represents an operation that stores the value corresponding to the
|
||||
* given key in the Object.
|
||||
*/
|
||||
class SetOperation: Operation {
|
||||
struct SetOperation: Operation {
|
||||
let parentCreatedAt: TimeTicket
|
||||
var executedAt: TimeTicket
|
||||
private let key: String
|
||||
|
|
|
@ -42,7 +42,7 @@ class ChangeTests: XCTestCase {
|
|||
|
||||
let changeID = ChangeID(clientSeq: 1, lamport: 2, actor: self.actorId)
|
||||
|
||||
let target = Change(id: changeID, operations: [setOperation])
|
||||
var target = Change(id: changeID, operations: [setOperation])
|
||||
|
||||
XCTAssertEqual(target.getOperations()[0].executedAt.getStructureAsString(), "8:actor-1:0")
|
||||
|
||||
|
|
Loading…
Reference in New Issue