Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 48a63f6

Browse files
committed
Add LSEQ
1 parent 0306f96 commit 48a63f6

15 files changed

Lines changed: 5593 additions & 0 deletions

Package.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,5 +46,13 @@ let package = Package(
4646
name: "CRDTRegistersTests",
4747
dependencies: ["CRDTRegisters"]
4848
),
49+
.target(
50+
name: "LSEQ",
51+
dependencies: []
52+
),
53+
.testTarget(
54+
name: "LSEQTests",
55+
dependencies: ["LSEQ"]
56+
),
4957
]
5058
)

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,13 @@ See the tests for more examples.
6868

6969
## Related Links
7070

71+
### CRDT Papers
72+
73+
* [Convergent and Commutative Replicated Data Types][crdt]
74+
* [LSEQ, an Adaptive Structure for Sequences in Distributed Collaborative Editing][lseq]
75+
76+
### Other Projects
77+
7178
See other projects which have implementations for CRDTs:
7279

7380
* [rust-crdt][rust_crdt]
@@ -82,3 +89,4 @@ See other projects which have implementations for CRDTs:
8289
[crdt]: https://hal.inria.fr/file/index/docid/555588/filename/techreport.pdf
8390
[rust_crdt]: https://github.com/rust-crdt/rust-crdt
8491
[java_crdt]: https://github.com/ajantis/java-crdt
92+
[lseq]: https://hal.archives-ouvertes.fr/hal-00921633/document

Sources/LSEQ/LSEQ.swift

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// Copyright 2019 Bryant Luk
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
public protocol LSEQ: Collection {
16+
associatedtype PositionType
17+
18+
associatedtype Element
19+
20+
associatedtype Index
21+
22+
associatedtype ElementContainer where ElementContainer: LSEQElementContainer,
23+
ElementContainer.PositionType == PositionType, ElementContainer.Element == Element
24+
25+
associatedtype Operation where Operation: LSEQOperation,
26+
Operation.PositionType == PositionType, Operation.Element == Element
27+
28+
var boundary: PositionType.Segment.Identifier { get }
29+
var source: PositionType.Segment.Source { get }
30+
var startPosition: PositionType { get }
31+
var endPosition: PositionType { get }
32+
var clock: PositionType.Clock { get }
33+
var storage: [ElementContainer] { get }
34+
35+
mutating func reserveCapacity(_ minimumCapacity: Int)
36+
37+
mutating func insert(_ newElement: Element, at index: Index)
38+
39+
mutating func insertAndMakeOperation(_ newElement: Element, at index: Index) -> Operation
40+
41+
@discardableResult
42+
mutating func remove(at index: Index) -> Element
43+
44+
@discardableResult
45+
mutating func removeAndMakeOperation(at index: Index) -> (Element, Operation)
46+
47+
mutating func apply(_ operation: Operation)
48+
49+
func makeDifferenceOperations(from other: Self) -> [Operation]
50+
}
51+
52+
public protocol LSEQOperation {
53+
associatedtype Kind
54+
associatedtype PositionType where PositionType: Position
55+
associatedtype Element
56+
57+
var kind: Kind { get }
58+
var position: PositionType { get }
59+
var element: Element? { get }
60+
}
61+
62+
public protocol LSEQElementContainer {
63+
associatedtype PositionType where PositionType: Position
64+
associatedtype Element
65+
66+
var position: PositionType { get }
67+
var element: Element { get }
68+
}
69+
70+
internal extension RandomAccessCollection {
71+
func insertionIndex(for predicate: (Element) -> Bool) -> Index {
72+
var slice: SubSequence = self[...]
73+
74+
while !slice.isEmpty {
75+
let middle = slice.index(slice.startIndex, offsetBy: slice.count / 2)
76+
if predicate(slice[middle]) {
77+
slice = slice[index(after: middle)...]
78+
} else {
79+
slice = slice[..<middle]
80+
}
81+
}
82+
return slice.startIndex
83+
}
84+
}

0 commit comments

Comments
 (0)