Skip to content

Instantly share code, notes, and snippets.

@chefnobody
Last active March 12, 2018 14:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chefnobody/5f35ca9c3a36dc1664bcea97b6bdfdec to your computer and use it in GitHub Desktop.
Save chefnobody/5f35ca9c3a36dc1664bcea97b6bdfdec to your computer and use it in GitHub Desktop.
Notes from reading through Peer-to-Peer white boarding article from Black Pixel.
import Foundation
/*
Peer-to-Peer white boarding application:
https://medium.com/bpxl-craft/building-a-peer-to-peer-whiteboarding-app-for-ipad-2a4c7728863e
Conflict-Free Replicated Data Type
CRDT
https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type#cite_note-OsterUrso2006-4
*/
/*
Edits are “conflict free” in that Pixelboard’s Edit integration algorithm guarantees that any Edit can be applied to a Drawing in any order and will always produce a valid result.
From the article:
Networks can be slow and unreliable. EditRecords cannot be guaranteed to be received in the same order in which they were created, nor can we guarantee that a device won’t receive the same EditRecord twice. Thus, sets of EditRecords must exhibit the following properties:
Associativity: (A∪B)∪C=A∪(B∪C) The order of the union operations must not matter, so that multiple sets of EditRecords from other devices in a session can be integrated in whatever order the network conditions allow.
Commutativity: A∪B=B∪A The order of the arguments to a union operation of two EditRecord sets must not affect the resulting value.
Idempotence: A∪A=A Duplicate EditRecords must be able to be integrated more than once without leading to duplication of those records in the replicated set of all records, nor duplicated information in the computed Drawing.
*/
indirect enum Edit {
case addStroke(Stroke)
case undo(Edit)
case redo(Edit)
}
typealias LogicalTimestamp = Int64
typealias UnixTimestamp = Int64
typealias CollaboratorID = Int64
struct EditRecord: Hashable, Comparable, Codable {
let edit: Edit
let logicalTimestamp: LogicalTimestamp
let temporalTimestamp: UnixTimestamp
let collaboratorID: CollaboratorID
static func < (lhs: EditRecord, rhs: EditRecord) -> Bool {
if lhs.logicalTimestamp != rhs.logicalTimestamp {
return lhs.logicalTimestamp < rhs.logicalTimestamp
}
else if lhs.temporalTimestamp != rhs.temporalTimestamp {
// more helpful as a tie-breaker when a logical time stamp
// match is found.
return lhs.temporalTimestamp < rhs.temporalTimestamp
}
else {
return lhs.collaboratorId < rhs.collaboratorId
}
}
}
struct Stroke {
}
struct Drawing {
let strokes: [Stroke]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment