Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
f599dd8
Update LanguageExt and netcore sdk
Stephanvs Oct 29, 2018
ec0c97b
Make internals visible to test project
Stephanvs Oct 29, 2018
3705092
Properly implemented Record types
Stephanvs Oct 29, 2018
ddb46fb
Fix formatting
Stephanvs Oct 29, 2018
7418d2a
Added simple sanity checks
Stephanvs Oct 29, 2018
fec1712
Added Replica tests
Stephanvs Oct 29, 2018
c4a1669
Use Assert.Equal instead of Assert.True
Stephanvs Oct 29, 2018
a1ab41d
Minor reformatting
Stephanvs Oct 29, 2018
c5d187d
Minor formatting
Stephanvs Oct 29, 2018
babad34
Remove travis ci
Stephanvs Oct 30, 2018
43db229
Removed unused comment
Stephanvs Oct 31, 2018
184f2f3
Merge branch 'master' into dev
Stephanvs Oct 31, 2018
b6869e8
Update azure pipeline to properly publish test results
Stephanvs Oct 31, 2018
b312d2b
Scan for tests in correct location
Stephanvs Oct 31, 2018
e4fa76e
Update build status badges
Stephanvs Oct 31, 2018
e29b632
Added additional assertions to the spec
Stephanvs Nov 2, 2018
ebc47b4
Handle branch cases within the Cursor.View()
Stephanvs Nov 2, 2018
f0dc134
Added SyntaxSpecs
Stephanvs Nov 7, 2018
e37bf0d
Introduced ctor overloads and helper methods for simpler api surface
Stephanvs Nov 9, 2018
1946399
Proper IComparable for Node, Replica and ListRef
Stephanvs Nov 9, 2018
57b2d98
Add to end instead of at beginning of pipeline
Stephanvs Nov 9, 2018
e87b0bd
Resolve back to inserting in front of fs
Stephanvs Nov 9, 2018
a2e3500
Mark more classes as sealed, and minor refactoring
Stephanvs Nov 10, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions .travis.yml

This file was deleted.

20 changes: 18 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,20 @@
| branch | build status |
|---|---|
| `master` | [![Build Status](https://travis-ci.org/Stephanvs/Mingle.svg?branch=master)](https://travis-ci.org/Stephanvs/Mingle) |
| `dev` | [![Build Status](https://travis-ci.org/Stephanvs/Mingle.svg?branch=dev)](https://travis-ci.org/Stephanvs/Mingle) |
| `master` | [![Build Status](https://dev.azure.com/Stephanvs/Mingle/_apis/build/status/Stephanvs.Mingle?branchName=master)](https://dev.azure.com/Stephanvs/Mingle/_build/latest?definitionId=1) |
| `dev` | [![Build Status](https://dev.azure.com/Stephanvs/Mingle/_apis/build/status/Stephanvs.Mingle?branchName=dev)](https://dev.azure.com/Stephanvs/Mingle/_build/latest?definitionId=1) |

# What is a CRDT?

Conflict-free, Coordination-free, Commutative, or Convergent datatypes, CRDT's are usually formally described as "join semi-lattices". Mathematical jargon aside, CRDT's track causality for modifications to your data. Because of this, time becomes less relevant, and coordination becomes unnecessary to get accurate values for your data.

# Want to learn more?

Here are some resources that may help you understand further.

- Strong Eventual Consistency and Conflict-free Replicated Data Types
- A good introduction to the concept of CRDTs: http://research.microsoft.com/apps/video/default.aspx?id=153540&r=1
- A comprehensive study of Convergent and Commutative Replicated Data Types
- A survey with references for several popular CRDTs: http://hal.inria.fr/docs/00/55/55/88/PDF/techreport.pdf
- Efficient State-based CRDTs by Delta-Mutation
- Talk: https://www.youtube.com/watch?v=y_ewFP-lgyM
- Paper: http://arxiv.org/pdf/1410.2803v1.pdf
15 changes: 13 additions & 2 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,16 @@ variables:
steps:
- script: dotnet build --configuration $(buildConfiguration)
displayName: 'dotnet build $(buildConfiguration)'
- script: dotnet test
displayName: 'dotnet test'

- task: DotNetCoreCLI@2
displayName: 'run unit tests'
inputs:
command: test
projects: 'test/**/*.csproj'
arguments: '--configuration $(buildConfiguration) --collect "Code coverage"'

- script: dotnet publish --output $(Build.ArtifactStagingDirectory)
displayName: 'dotnet publish'

- task: PublishBuildArtifacts@1
displayName: 'publish build artifacts'
5 changes: 5 additions & 0 deletions src/Attributes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
using System;
using System.IO;
using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("Mingle.Tests")]
80 changes: 37 additions & 43 deletions src/Core/Cmd.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,106 +9,100 @@ public sealed class Before : BeforeAfter { }

public sealed class After : BeforeAfter { }

public interface Cmd
public interface Cmd : IComparable<Cmd>
{
}

public sealed class Let : Record<Let>, Cmd
{
private readonly Var _x;
private readonly Expr _expr;
public readonly Var X;
public readonly Expr Expr;

public Let(Var x, Expr expr)
{
_x = x;
_expr = expr;
X = x;
Expr = expr;
}

public Var X => _x;

public Expr Expr => _expr;
public int CompareTo(Cmd other)
=> RecordType<Let>.Compare(this, other as Let);
}

public sealed class Assign : Record<Assign>, Cmd
{
private readonly Expr _expr;
private readonly Val _value;
public readonly Expr Expr;
public readonly Val Value;

public Assign(Expr expr, Val value)
{
_expr = expr;
_value = value;
Expr = expr;
Value = value;
}

public Expr Expr => _expr;

public Val Value => _value;
public int CompareTo(Cmd other)
=> RecordType<Assign>.Compare(this, other as Assign);
}

public sealed class Insert : Record<Insert>, Cmd
{
private readonly Expr _expr;
private readonly Val _value;
public readonly Expr Expr;
public readonly Val Value;

public Insert(Expr expr, Val value)
{
_expr = expr;
_value = value;
Expr = expr;
Value = value;
}

public Expr Expr => _expr;

public Val Value => _value;
public int CompareTo(Cmd other)
=> RecordType<Insert>.Compare(this, other as Insert);
}

public sealed class Delete : Record<Delete>, Cmd
{
private readonly Expr _expr;
public readonly Expr Expr;

public Delete(Expr expr)
{
_expr = expr;
Expr = expr;
}

public Expr Expr => _expr;
public int CompareTo(Cmd other)
=> RecordType<Delete>.Compare(this, other as Delete);
}

public sealed class MoveVertical : Record<MoveVertical>, Cmd
{
private readonly Expr _moveExpr;
private readonly Expr _targetExpr;
private readonly BeforeAfter _beforeAfter;
public readonly Expr MoveExpr;
public readonly Expr TargetExpr;
public readonly BeforeAfter BeforeAfter;

public MoveVertical(
Expr moveExpr,
Expr targetExpr,
BeforeAfter beforeAfter)
{
_moveExpr = moveExpr;
_targetExpr = targetExpr;
_beforeAfter = beforeAfter;
MoveExpr = moveExpr;
TargetExpr = targetExpr;
BeforeAfter = beforeAfter;
}

public Expr MoveExpr => _moveExpr;

public Expr TargetExpr => _targetExpr;

public BeforeAfter BeforeAfter => _beforeAfter;
public int CompareTo(Cmd other)
=> RecordType<MoveVertical>.Compare(this, other as MoveVertical);
}

public sealed class Sequence : Record<Sequence>, Cmd
{
private readonly Cmd _cmd1;
private readonly Cmd _cmd2;
public readonly Cmd Cmd1;
public readonly Cmd Cmd2;

public Sequence(Cmd cmd1, Cmd cmd2)
{
_cmd1 = cmd1;
_cmd2 = cmd2;
Cmd1 = cmd1;
Cmd2 = cmd2;
}

public Cmd Cmd1 => _cmd1;

public Cmd Cmd2 => _cmd2;
public int CompareTo(Cmd other)
=> RecordType<Sequence>.Compare(this, other as Sequence);
}
}
49 changes: 22 additions & 27 deletions src/Core/Cursor.cs
Original file line number Diff line number Diff line change
@@ -1,67 +1,62 @@
using System;
using System.Collections.Generic;
using LanguageExt;
using static LanguageExt.Prelude;

namespace Mingle
{
public /* immutable */ class Cursor
public /* immutable */ sealed class Cursor : Record<Cursor>
{
private Cursor(Lst<BranchTag> keys, Key finalKey)
public readonly Lst<BranchTag> Keys;
public readonly Key FinalKey;

internal Cursor(Lst<BranchTag> keys, Key finalKey)
{
Keys = keys;
FinalKey = finalKey;
}

public Lst<BranchTag> Keys { get; }

public Key FinalKey { get; }

public Cursor Append(Func<Key, BranchTag> tag, Key newFinalKey)
{
var branchTag = tag(FinalKey);
return new Cursor(Keys.Add(branchTag), newFinalKey);
}
=> new Cursor(Keys.Add(tag(FinalKey)), newFinalKey);

public Cursor.IView View()
{
return new Leaf(FinalKey);
}
=> match<BranchTag, Cursor.IView>(Keys,
() => new Leaf(FinalKey),
(k1, kn) => new Branch(k1, new Cursor(kn.Freeze(), FinalKey)));

public static Cursor Doc()
=> WithFinalKey(new DocK());

public static Cursor WithFinalKey(Key finalKey)
=> new Cursor(Lst<BranchTag>.Empty, finalKey);

internal Cursor Copy(Lst<BranchTag>? keys = null, Key finalKey = null)
=> new Cursor(keys: keys ?? Keys, finalKey: finalKey ?? FinalKey);

public interface IView
{
}

public class Leaf : Record<Leaf>, IView
public sealed class Leaf : Record<Leaf>, IView
{
private readonly Key _finalKey;
public readonly Key FinalKey;

public Leaf(Key finalKey)
{
_finalKey = finalKey;
FinalKey = finalKey;
}

public Key FinalKey => _finalKey;
}

public class Branch : Record<Branch>, IView
public sealed class Branch : Record<Branch>, IView
{
private readonly BranchTag _head;
private readonly Cursor _tail;
public readonly BranchTag Head;
public readonly Cursor Tail;

public Branch(BranchTag head, Cursor tail)
{
_head = head;
_tail = tail;
Head = head;
Tail = tail;
}

public BranchTag Head => _head;

public Cursor Tail => _tail;
}
}
}
30 changes: 10 additions & 20 deletions src/Core/Expr.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,53 +13,43 @@ public sealed class Doc : Record<Doc>, Expr

public sealed class Var : Record<Var>, Expr
{
private readonly string _name;
public readonly string Name;

public Var(string name)
{
_name = name;
Name = name;
}

public string Name => _name;
}

public sealed class DownField : Record<DownField>, Expr
{
private readonly Expr _expr;
private readonly string _key;
public readonly Expr Expr;
public readonly string Key;

public DownField(Expr expr, string key)
{
_expr = expr;
_key = key;
Expr = expr;
Key = key;
}

public Expr Expr => _expr;

public string Key => _key;
}

public sealed class Iter : Record<Iter>, Expr
{
private readonly Expr _expr;
public readonly Expr Expr;

public Iter(Expr expr)
{
_expr = expr;
Expr = expr;
}

public Expr Expr => _expr;
}

public sealed class Next : Record<Next>, Expr
{
private readonly Expr _expr;
public readonly Expr Expr;

public Next(Expr expr)
{
_expr = expr;
Expr = expr;
}

public Expr Expr => _expr;
}
}
Loading