yorkie-ios-sdk/Sources/Document/Change/ChangeID.swift

122 lines
3.4 KiB
Swift

/*
* Copyright 2022 The Yorkie Authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import Foundation
/**
* `ChangeID` is for identifying the Change. This is immutable.
*/
struct ChangeID {
/**
* `initial` represents the initial state ID. Usually this is used to
* represent a state where nothing has been edited.
*/
static let initial = ChangeID(clientSeq: 0, lamport: 0, actor: ActorIDs.initial)
// `serverSeq` is optional and only present for changes stored on the server.
private var serverSeq: Int64?
private let clientSeq: UInt32
private var lamport: Int64
private var actor: ActorID?
init(clientSeq: UInt32, lamport: Int64, actor: ActorID? = nil, serverSeq: Int64? = nil) {
self.clientSeq = clientSeq
self.lamport = lamport
self.actor = actor
self.serverSeq = serverSeq
}
/**
* `next` creates a next ID of this ID.
*/
func next() -> ChangeID {
return ChangeID(clientSeq: self.clientSeq + 1, lamport: self.lamport + 1, actor: self.actor, serverSeq: self.serverSeq)
}
/**
* `syncLamport` syncs lamport timestamp with the given ID.
*
* {@link https://en.wikipedia.org/wiki/Lamport_timestamps#Algorithm}
*/
mutating func syncLamport(with otherLamport: Int64) {
let lamport = otherLamport > self.lamport ? otherLamport : self.lamport + 1
self.lamport = lamport
}
/**
* `createTimeTicket` creates a ticket of the given delimiter.
*/
func createTimeTicket(delimiter: UInt32) -> TimeTicket {
return TimeTicket(lamport: self.lamport, delimiter: delimiter, actorID: self.actor)
}
/**
* `setActor` sets the given actor.
*/
mutating func setActor(_ actorID: ActorID) {
self.actor = actorID
}
/**
* `getServerSeq` returns the server sequence of this ID.
*/
func getServerSeq() -> Int64? {
return self.serverSeq
}
/**
* `getClientSeq` returns the client sequence of this ID.
*/
func getClientSeq() -> UInt32 {
return self.clientSeq
}
/**
* `getLamport` returns the lamport clock of this ID.
*/
func getLamport() -> Int64 {
return self.lamport
}
/**
* `getLamportAsString` returns the lamport clock of this ID as a string.
*/
func getLamportAsString() -> String {
return "\(self.lamport)"
}
/**
* `getActorID` returns the actor of this ID.
*/
func getActorID() -> String? {
return self.actor
}
/**
* `structureAsString` returns a string containing the meta data of this ID.
*/
var structureAsString: String {
var actor: String
if let value = self.actor {
actor = String(value.suffix(2))
} else {
actor = "nil"
}
return "\(self.lamport):\(actor):\(self.clientSeq)"
}
}