experimenting with 'reserved uids'

This commit is contained in:
Kevin Jahns 2014-08-07 21:52:50 +02:00
parent efc4e502cf
commit 9e1d9e568f
77 changed files with 509 additions and 1482 deletions

View File

@ -73,7 +73,7 @@ module.exports = (grunt) ->
browserify: browserify:
dest: dest:
files: files:
'dest/browser/Yatta_test.js': ['test/**/*.coffee'] 'dest/browser/test/Yatta_test.js': ['test/**/*.coffee']
options: options:
transform: ['coffeeify'] transform: ['coffeeify']
debug: true debug: true
@ -128,7 +128,7 @@ module.exports = (grunt) ->
grunt.loadNpmTasks "grunt-coffeelint" grunt.loadNpmTasks "grunt-coffeelint"
grunt.loadNpmTasks "grunt-codo" grunt.loadNpmTasks "grunt-codo"
grunt.registerTask "build", ["coffeelint", "codo", "test"] grunt.registerTask "build", ["coffeelint", "codo", "browserify", "test"]
grunt.registerTask "production", ["test", "coffee","coffeelint", "literate", "browserify", "uglify", "codo"] grunt.registerTask "production", ["test", "coffee","coffeelint", "literate", "browserify", "uglify", "codo"]
grunt.registerTask "default", ["build", "watch"] grunt.registerTask "default", ["build", "watch"]
grunt.registerTask "production", ["coffee"] grunt.registerTask "production", ["coffee"]

View File

@ -3,7 +3,7 @@
A real-time web framework that manages concurrency control for arbitrary data structures and is _not_ based on Operational Transformation. A real-time web framework that manages concurrency control for arbitrary data structures and is _not_ based on Operational Transformation.
Yatta! provides similar functionality as [ShareJs](https://github.com/share/ShareJS) and [OpenCoweb](https://github.com/opencoweb/coweb) Yatta! provides similar functionality as [ShareJs](https://github.com/share/ShareJS) and [OpenCoweb](https://github.com/opencoweb/coweb)
but does not require you to understand how the internals work. The predefined data structures provide a simple API to access your shared data types. but does not require you to understand how the internals work. The predefined data structures provide a simple API to access your shared data structures.
Predefined data structures: Predefined data structures:
* Text * Text
@ -13,26 +13,27 @@ Predefined data structures:
Unlike other frameworks, Yatta! supports P2P message propagation and is not bound to a specific communication protocol. Unlike other frameworks, Yatta! supports P2P message propagation and is not bound to a specific communication protocol.
Currently supported communication protocols: Currently supported communication protocols:
* [IWC](dbis.rwth-aachen.de/gadgets/iwc/resources/iwc.manual.pdf) - Inter-widget Communication * [IWC](http://dbis.rwth-aachen.de/gadgets/iwc/resources/iwc.manual.pdf) - Inter-widget Communication
# About # About
Find out more about the concurrent editing problem here Find out more about the concurrent editing problem here
([Cooperation, Concurrency, Conflicts, and Convergence](http://opencoweb.org/ocwdocs/intro/openg.html)) and here [Cooperation, Concurrency, Conflicts, and Convergence](http://opencoweb.org/ocwdocs/intro/openg.html) and here
([Operational Transformation (OT)](http://en.wikipedia.org/wiki/Operational_transformation)) [Operational Transformation (OT)](http://en.wikipedia.org/wiki/Operational_transformation)
My Bachelor Thesis project aim was to develop a P2P OT Framework that enables collaboration on XML documents and supports My Bachelor Thesis project aim was to develop a P2P OT Framework that enables collaboration on XML documents and supports
[Intention Preservation](http://www3.ntu.edu.sg/home/czsun/projects/otfaq/#intentionPreservation). [Intention Preservation](http://www3.ntu.edu.sg/home/czsun/projects/otfaq/#intentionPreservation).
After some time I realized that OT has significant drawbacks in P2P environments. After some time I realized that OT has significant drawbacks in P2P environments.
With my gained experiences I came up with a new approach. I named it Yata - Yet Another Transformation Approach. With my gained experiences I came up with a new approach. I named it Yata - Yet Another Transformation Approach.
Very surprising is that my approach enables concurrent editing with the following space and time properties: It enables concurrent editing with the following space and time properties:
* Time complexity: O(S), whereby S is the number of operations that are inserted concurrently at the same position. This means that my approach does not transform against operations that happen on other positions. * Time complexity: O(S), whereby S is the number of operations that are inserted concurrently at the same position. This means that my approach does not transform against operations that happen on other positions.
* Space complexity = O(|Document|), whereby |Document| is the size of shared document. Depending on the used data structure, Yata may needs 4*|Document| of space. * Space complexity = O(|Document|), whereby |Document| is the size of the shared document. Depending on the used data structure, Yata may needs 4*|Document| of space.
This means that my approach beats all OT time complexities. Furthermore, it is possible to make a very strict definition of Intention Preservation, and I was able to This means that my approach beats all OT time complexities. Furthermore, it is possible to make a very strict definition of Intention Preservation, and I was able to
show that it is never violated. show that it is never violated.
Another advantage of my approach is that propagated messages are very small. Another advantage of my approach is that propagated messages are very small.
Background: In Real-Time P2P OT algorithms you have to send a state-vector with every message that defines the state of the History Buffer Background: In real-time P2P OT algorithms you have to send a state-vector with every message that defines the state of the History Buffer
on which the operation was created. This is not necessary in Yata. on which the operation was created. This is not necessary in Yata.
One downside is that the History Buffer holds at least as many operations as there are characters in the document. One downside is that the History Buffer holds at least as many operations as there are characters in the document.
@ -42,6 +43,7 @@ So, how did I come up with the name for the implementation (Yatta! is not Yata)?
![YATTA!](./extras/imgs/YATTA.png) ![YATTA!](./extras/imgs/YATTA.png)
Yatta! means "I did it!" in Japanese. You scream it when you accomplish something (for proper application I refer to the Yatta-man in [Heroes](http://heroeswiki.com/Yatta!)). Yatta! means "I did it!" in Japanese. You scream it when you accomplish something (for proper application I refer to the Yatta-man in [Heroes](http://heroeswiki.com/Yatta!)).
There is also this awesome video on the Internet that will change your life [Yatta](https://www.youtube.com/watch?v=kL5DDSglM_s). There is also this awesome video on the Internet that will change your life [Yatta](https://www.youtube.com/watch?v=kL5DDSglM_s).
# Status # Status
Yatta! is still in an early development phase. Yatta! is still in an early development phase.
@ -50,3 +52,8 @@ Please report any issues to the [Github issue page](https://github.com/DadaMonad
# License # License
Yatta! is licensed under the [MIT License](./LICENSE.txt). Yatta! is licensed under the [MIT License](./LICENSE.txt).

View File

@ -146,23 +146,25 @@ Engine = (function() {
}; };
Engine.prototype.applyOps = function(ops_json) { Engine.prototype.applyOps = function(ops_json) {
var o, ops, _i, _j, _k, _len, _len1, _len2; var o, _i, _len, _results;
ops = []; _results = [];
for (_i = 0, _len = ops_json.length; _i < _len; _i++) { for (_i = 0, _len = ops_json.length; _i < _len; _i++) {
o = ops_json[_i]; o = ops_json[_i];
ops.push(this.parseOperation(o)); _results.push(this.applyOp(o));
} }
for (_j = 0, _len1 = ops.length; _j < _len1; _j++) { return _results;
o = ops[_j];
this.HB.addOperation(o); /*
} ops = []
for (_k = 0, _len2 = ops.length; _k < _len2; _k++) { for o in ops_json
o = ops[_k]; ops.push @parseOperation o
if (!o.execute()) { for o in ops
this.unprocessed_ops.push(o); @HB.addOperation o
} for o in ops
} if not o.execute()
return this.tryUnprocessed(); @unprocessed_ops.push o
@tryUnprocessed()
*/
}; };
Engine.prototype.applyOp = function(op_json) { Engine.prototype.applyOp = function(op_json) {
@ -216,20 +218,14 @@ Engine = require("../Engine.coffee");
JsonYatta = (function() { JsonYatta = (function() {
function JsonYatta(user_id, Connector) { function JsonYatta(user_id, Connector) {
var first_word, json_types, root_elem; var first_word, json_types;
this.HB = new HistoryBuffer(user_id); this.HB = new HistoryBuffer(user_id);
json_types = json_types_uninitialized(this.HB); json_types = json_types_uninitialized(this.HB);
this.engine = new Engine(this.HB, json_types.parser); this.engine = new Engine(this.HB, json_types.parser);
this.connector = new Connector(this.engine, this.HB, json_types.execution_listener, this); this.connector = new Connector(this.engine, this.HB, json_types.execution_listener, this);
root_elem = this.connector.getRootElement(); first_word = new json_types.types.JsonType(this.HB.getReservedUniqueIdentifier());
if (root_elem == null) { this.HB.addOperation(first_word).execute();
first_word = new json_types.types.JsonType(this.HB.getNextOperationIdentifier());
this.HB.addOperation(first_word);
first_word.execute();
this.root_element = first_word; this.root_element = first_word;
} else {
this.root_element = this.HB.getOperation(root_elem);
}
} }
JsonYatta.prototype.getRootElement = function() { JsonYatta.prototype.getRootElement = function() {
@ -305,6 +301,13 @@ HistoryBuffer = (function() {
return this.user_id; return this.user_id;
}; };
HistoryBuffer.prototype.getReservedUniqueIdentifier = function() {
return {
creator: '_',
op_number: '_'
};
};
HistoryBuffer.prototype.getOperationCounter = function() { HistoryBuffer.prototype.getOperationCounter = function() {
var ctn, res, user, _ref; var ctn, res, user, _ref;
res = {}; res = {};
@ -608,7 +611,7 @@ module.exports = function(HB) {
__extends(ImmutableObject, _super); __extends(ImmutableObject, _super);
function ImmutableObject(uid, content, prev, next, origin) { function ImmutableObject(uid, content, prev, next, origin) {
this.content = content != null ? content : ""; this.content = content;
ImmutableObject.__super__.constructor.call(this, uid, prev, next, origin); ImmutableObject.__super__.constructor.call(this, uid, prev, next, origin);
} }
@ -810,10 +813,11 @@ module.exports = function(HB) {
return JsonType.__super__.val.call(this, name, obj); return JsonType.__super__.val.call(this, name, obj);
} else { } else {
if (typeof content === 'string') { if (typeof content === 'string') {
word = HB.addOperation(new types.Word(HB.getNextOperationIdentifier(), content)).execute(); word = HB.addOperation(new types.Word(void 0)).execute();
word.insertText(0, content);
return JsonType.__super__.val.call(this, name, word); return JsonType.__super__.val.call(this, name, word);
} else if (content.constructor === Object) { } else if (content.constructor === Object) {
json = HB.addOperation(new JsonType(HB.getNextOperationIdentifier(), content, mutable)).execute(); json = HB.addOperation(new JsonType(void 0, content, mutable)).execute();
return JsonType.__super__.val.call(this, name, json); return JsonType.__super__.val.call(this, name, json);
} else { } else {
throw new Error("You must not set " + (typeof content) + "-types in collaborative Json-objects!"); throw new Error("You must not set " + (typeof content) + "-types in collaborative Json-objects!");
@ -887,7 +891,7 @@ module.exports = function(HB) {
var o, obj, result, _ref, _ref1; var o, obj, result, _ref, _ref1;
if (content != null) { if (content != null) {
if (this.map[name] == null) { if (this.map[name] == null) {
HB.addOperation(new AddName(HB.getNextOperationIdentifier(), this, name)).execute(); HB.addOperation(new AddName(void 0, this, name)).execute();
} }
this.map[name].replace(content); this.map[name].replace(content);
return this; return this;
@ -971,8 +975,8 @@ module.exports = function(HB) {
this.saveOperation('beginning', beginning); this.saveOperation('beginning', beginning);
this.saveOperation('end', end); this.saveOperation('end', end);
} else { } else {
this.beginning = HB.addOperation(new types.Delimiter(HB.getNextOperationIdentifier(), void 0, void 0)); this.beginning = HB.addOperation(new types.Delimiter(void 0, void 0, void 0));
this.end = HB.addOperation(new types.Delimiter(HB.getNextOperationIdentifier(), this.beginning, void 0)); this.end = HB.addOperation(new types.Delimiter(void 0, this.beginning, void 0));
this.beginning.next_cl = this.end; this.beginning.next_cl = this.end;
this.beginning.execute(); this.beginning.execute();
this.end.execute(); this.end.execute();
@ -1035,7 +1039,7 @@ module.exports = function(HB) {
ReplaceManager.prototype.replace = function(content) { ReplaceManager.prototype.replace = function(content) {
var o, op; var o, op;
o = this.getLastOperation(); o = this.getLastOperation();
op = new Replaceable(content, this, HB.getNextOperationIdentifier(), o, o.next_cl); op = new Replaceable(content, this, void 0, o, o.next_cl);
return HB.addOperation(op).execute(); return HB.addOperation(op).execute();
}; };
@ -1215,11 +1219,8 @@ module.exports = function(HB) {
Word = (function(_super) { Word = (function(_super) {
__extends(Word, _super); __extends(Word, _super);
function Word(uid, initial_content, beginning, end, prev, next, origin) { function Word(uid, beginning, end, prev, next, origin) {
Word.__super__.constructor.call(this, uid, beginning, end, prev, next, origin); Word.__super__.constructor.call(this, uid, beginning, end, prev, next, origin);
if (initial_content != null) {
this.insertText(0, initial_content);
}
} }
Word.prototype.insertText = function(position, content) { Word.prototype.insertText = function(position, content) {
@ -1228,7 +1229,7 @@ module.exports = function(HB) {
_results = []; _results = [];
for (_i = 0, _len = content.length; _i < _len; _i++) { for (_i = 0, _len = content.length; _i < _len; _i++) {
c = content[_i]; c = content[_i];
op = new TextInsert(c, HB.getNextOperationIdentifier(), o.prev_cl, o); op = new TextInsert(c, void 0, o.prev_cl, o);
_results.push(HB.addOperation(op).execute()); _results.push(HB.addOperation(op).execute());
} }
return _results; return _results;
@ -1313,7 +1314,7 @@ module.exports = function(HB) {
parser['Word'] = function(json) { parser['Word'] = function(json) {
var beginning, end, next, origin, prev, uid; var beginning, end, next, origin, prev, uid;
uid = json['uid'], beginning = json['beginning'], end = json['end'], prev = json['prev'], next = json['next'], origin = json['origin']; uid = json['uid'], beginning = json['beginning'], end = json['end'], prev = json['prev'], next = json['next'], origin = json['origin'];
return new Word(uid, void 0, beginning, end, prev, next, origin); return new Word(uid, beginning, end, prev, next, origin);
}; };
types['TextInsert'] = TextInsert; types['TextInsert'] = TextInsert;
types['TextDelete'] = TextDelete; types['TextDelete'] = TextDelete;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -2,11 +2,11 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Test GOTOjs</title> <title>Test GOTOjs</title>
<link rel="stylesheet" href="../../node_modules/mocha/mocha.css" /> <link rel="stylesheet" href="../../../node_modules/mocha/mocha.css" />
</head> </head>
<body> <body>
<div id="mocha"></div> <div id="mocha"></div>
<script src="../../node_modules/mocha/mocha.js"></script> <script src="../../../node_modules/mocha/mocha.js"></script>
<script>mocha.setup('bdd')</script> <script>mocha.setup('bdd')</script>
<script src="Yatta_test.js"></script> <script src="Yatta_test.js"></script>
<script> <script>

View File

@ -57,10 +57,10 @@ module.exports = function(user_list) {
TestConnector.prototype.receive = function(o) { TestConnector.prototype.receive = function(o) {
var _base, _name; var _base, _name;
if ((_base = this.unexecuted)[_name = o.creator] == null) { if ((_base = this.unexecuted)[_name = o.uid.creator] == null) {
_base[_name] = []; _base[_name] = [];
} }
return this.unexecuted[o.creator].push(o); return this.unexecuted[o.uid.creator].push(o);
}; };
TestConnector.prototype.flushOne = function(user) { TestConnector.prototype.flushOne = function(user) {

View File

@ -6,5 +6,5 @@
"TestConnector.coffee" "TestConnector.coffee"
], ],
"names": [], "names": [],
"mappings": "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" "mappings": "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"
} }

View File

@ -18,23 +18,25 @@ Engine = (function() {
}; };
Engine.prototype.applyOps = function(ops_json) { Engine.prototype.applyOps = function(ops_json) {
var o, ops, _i, _j, _k, _len, _len1, _len2; var o, _i, _len, _results;
ops = []; _results = [];
for (_i = 0, _len = ops_json.length; _i < _len; _i++) { for (_i = 0, _len = ops_json.length; _i < _len; _i++) {
o = ops_json[_i]; o = ops_json[_i];
ops.push(this.parseOperation(o)); _results.push(this.applyOp(o));
} }
for (_j = 0, _len1 = ops.length; _j < _len1; _j++) { return _results;
o = ops[_j];
this.HB.addOperation(o); /*
} ops = []
for (_k = 0, _len2 = ops.length; _k < _len2; _k++) { for o in ops_json
o = ops[_k]; ops.push @parseOperation o
if (!o.execute()) { for o in ops
this.unprocessed_ops.push(o); @HB.addOperation o
} for o in ops
} if not o.execute()
return this.tryUnprocessed(); @unprocessed_ops.push o
@tryUnprocessed()
*/
}; };
Engine.prototype.applyOp = function(op_json) { Engine.prototype.applyOp = function(op_json) {

View File

@ -6,5 +6,5 @@
"Engine.coffee" "Engine.coffee"
], ],
"names": [], "names": [],
"mappings": "AAIA,IAAA,MAAA;;AAAA;AACe,EAAA,gBAAE,EAAF,EAAO,MAAP,GAAA;AACX,IADY,IAAC,CAAA,KAAA,EACb,CAAA;AAAA,IADiB,IAAC,CAAA,SAAA,MAClB,CAAA;AAAA,IAAA,IAAC,CAAA,eAAD,GAAmB,EAAnB,CADW;EAAA,CAAb;;AAAA,mBAGA,cAAA,GAAgB,SAAC,IAAD,GAAA;AACd,QAAA,UAAA;AAAA,IAAA,UAAA,GAAa,IAAC,CAAA,MAAO,CAAA,IAAI,CAAC,IAAL,CAArB,CAAA;AACA,IAAA,IAAG,kBAAH;aACE,UAAA,CAAW,IAAX,EADF;KAAA,MAAA;AAGE,YAAU,IAAA,KAAA,CAAO,0CAAA,GAAyC,IAAI,CAAC,IAA9C,GAAoD,mBAApD,GAAsE,CAAA,IAAI,CAAC,SAAL,CAAe,IAAf,CAAA,CAAtE,GAA2F,GAAlG,CAAV,CAHF;KAFc;EAAA,CAHhB,CAAA;;AAAA,mBAUA,QAAA,GAAU,SAAC,QAAD,GAAA;AACR,QAAA,sCAAA;AAAA,IAAA,GAAA,GAAM,EAAN,CAAA;AACA,SAAA,+CAAA;uBAAA;AACE,MAAA,GAAG,CAAC,IAAJ,CAAS,IAAC,CAAA,cAAD,CAAgB,CAAhB,CAAT,CAAA,CADF;AAAA,KADA;AAGA,SAAA,4CAAA;kBAAA;AACE,MAAA,IAAC,CAAA,EAAE,CAAC,YAAJ,CAAiB,CAAjB,CAAA,CADF;AAAA,KAHA;AAKA,SAAA,4CAAA;kBAAA;AACE,MAAA,IAAG,CAAA,CAAK,CAAC,OAAF,CAAA,CAAP;AACE,QAAA,IAAC,CAAA,eAAe,CAAC,IAAjB,CAAsB,CAAtB,CAAA,CADF;OADF;AAAA,KALA;WAQA,IAAC,CAAA,cAAD,CAAA,EATQ;EAAA,CAVV,CAAA;;AAAA,mBAqBA,OAAA,GAAS,SAAC,OAAD,GAAA;AAEP,QAAA,CAAA;AAAA,IAAA,CAAA,GAAI,IAAC,CAAA,cAAD,CAAgB,OAAhB,CAAJ,CAAA;AAAA,IACA,IAAC,CAAA,EAAE,CAAC,YAAJ,CAAiB,CAAjB,CADA,CAAA;AAEA,IAAA,IAAG,CAAA,CAAK,CAAC,OAAF,CAAA,CAAP;AACE,MAAA,IAAC,CAAA,eAAe,CAAC,IAAjB,CAAsB,CAAtB,CAAA,CADF;KAFA;WAIA,IAAC,CAAA,cAAD,CAAA,EANO;EAAA,CArBT,CAAA;;AAAA,mBA6BA,cAAA,GAAgB,SAAA,GAAA;AACd,QAAA,qDAAA;AAAA;WAAM,IAAN,GAAA;AACE,MAAA,UAAA,GAAa,IAAC,CAAA,eAAe,CAAC,MAA9B,CAAA;AAAA,MACA,WAAA,GAAc,EADd,CAAA;AAEA;AAAA,WAAA,2CAAA;sBAAA;AACE,QAAA,IAAG,CAAA,EAAM,CAAC,OAAH,CAAA,CAAP;AACE,UAAA,WAAW,CAAC,IAAZ,CAAiB,EAAjB,CAAA,CADF;SADF;AAAA,OAFA;AAAA,MAKA,IAAC,CAAA,eAAD,GAAmB,WALnB,CAAA;AAMA,MAAA,IAAG,IAAC,CAAA,eAAe,CAAC,MAAjB,KAA2B,UAA9B;AACE,cADF;OAAA,MAAA;8BAAA;OAPF;IAAA,CAAA;oBADc;EAAA,CA7BhB,CAAA;;gBAAA;;IADF,CAAA;;AAAA,MA4CM,CAAC,OAAP,GAAiB,MA5CjB,CAAA" "mappings": "AAIA,IAAA,MAAA;;AAAA;AACe,EAAA,gBAAE,EAAF,EAAO,MAAP,GAAA;AACX,IADY,IAAC,CAAA,KAAA,EACb,CAAA;AAAA,IADiB,IAAC,CAAA,SAAA,MAClB,CAAA;AAAA,IAAA,IAAC,CAAA,eAAD,GAAmB,EAAnB,CADW;EAAA,CAAb;;AAAA,mBAGA,cAAA,GAAgB,SAAC,IAAD,GAAA;AACd,QAAA,UAAA;AAAA,IAAA,UAAA,GAAa,IAAC,CAAA,MAAO,CAAA,IAAI,CAAC,IAAL,CAArB,CAAA;AACA,IAAA,IAAG,kBAAH;aACE,UAAA,CAAW,IAAX,EADF;KAAA,MAAA;AAGE,YAAU,IAAA,KAAA,CAAO,0CAAA,GAAyC,IAAI,CAAC,IAA9C,GAAoD,mBAApD,GAAsE,CAAA,IAAI,CAAC,SAAL,CAAe,IAAf,CAAA,CAAtE,GAA2F,GAAlG,CAAV,CAHF;KAFc;EAAA,CAHhB,CAAA;;AAAA,mBAUA,QAAA,GAAU,SAAC,QAAD,GAAA;AACR,QAAA,qBAAA;AAAA;SAAA,+CAAA;uBAAA;AACE,oBAAA,IAAC,CAAA,OAAD,CAAS,CAAT,EAAA,CADF;AAAA;oBAAA;AAEA;AAAA;;;;;;;;;;OAHQ;EAAA,CAVV,CAAA;;AAAA,mBAwBA,OAAA,GAAS,SAAC,OAAD,GAAA;AAEP,QAAA,CAAA;AAAA,IAAA,CAAA,GAAI,IAAC,CAAA,cAAD,CAAgB,OAAhB,CAAJ,CAAA;AAAA,IACA,IAAC,CAAA,EAAE,CAAC,YAAJ,CAAiB,CAAjB,CADA,CAAA;AAEA,IAAA,IAAG,CAAA,CAAK,CAAC,OAAF,CAAA,CAAP;AACE,MAAA,IAAC,CAAA,eAAe,CAAC,IAAjB,CAAsB,CAAtB,CAAA,CADF;KAFA;WAIA,IAAC,CAAA,cAAD,CAAA,EANO;EAAA,CAxBT,CAAA;;AAAA,mBAgCA,cAAA,GAAgB,SAAA,GAAA;AACd,QAAA,qDAAA;AAAA;WAAM,IAAN,GAAA;AACE,MAAA,UAAA,GAAa,IAAC,CAAA,eAAe,CAAC,MAA9B,CAAA;AAAA,MACA,WAAA,GAAc,EADd,CAAA;AAEA;AAAA,WAAA,2CAAA;sBAAA;AACE,QAAA,IAAG,CAAA,EAAM,CAAC,OAAH,CAAA,CAAP;AACE,UAAA,WAAW,CAAC,IAAZ,CAAiB,EAAjB,CAAA,CADF;SADF;AAAA,OAFA;AAAA,MAKA,IAAC,CAAA,eAAD,GAAmB,WALnB,CAAA;AAMA,MAAA,IAAG,IAAC,CAAA,eAAe,CAAC,MAAjB,KAA2B,UAA9B;AACE,cADF;OAAA,MAAA;8BAAA;OAPF;IAAA,CAAA;oBADc;EAAA,CAhChB,CAAA;;gBAAA;;IADF,CAAA;;AAAA,MA+CM,CAAC,OAAP,GAAiB,MA/CjB,CAAA"
} }

View File

@ -8,20 +8,14 @@ Engine = require("../Engine.coffee");
JsonYatta = (function() { JsonYatta = (function() {
function JsonYatta(user_id, Connector) { function JsonYatta(user_id, Connector) {
var first_word, json_types, root_elem; var first_word, json_types;
this.HB = new HistoryBuffer(user_id); this.HB = new HistoryBuffer(user_id);
json_types = json_types_uninitialized(this.HB); json_types = json_types_uninitialized(this.HB);
this.engine = new Engine(this.HB, json_types.parser); this.engine = new Engine(this.HB, json_types.parser);
this.connector = new Connector(this.engine, this.HB, json_types.execution_listener, this); this.connector = new Connector(this.engine, this.HB, json_types.execution_listener, this);
root_elem = this.connector.getRootElement(); first_word = new json_types.types.JsonType(this.HB.getReservedUniqueIdentifier());
if (root_elem == null) { this.HB.addOperation(first_word).execute();
first_word = new json_types.types.JsonType(this.HB.getNextOperationIdentifier());
this.HB.addOperation(first_word);
first_word.execute();
this.root_element = first_word; this.root_element = first_word;
} else {
this.root_element = this.HB.getOperation(root_elem);
}
} }
JsonYatta.prototype.getRootElement = function() { JsonYatta.prototype.getRootElement = function() {

View File

@ -6,5 +6,5 @@
"JsonYatta.coffee" "JsonYatta.coffee"
], ],
"names": [], "names": [],
"mappings": "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" "mappings": "AACA,IAAA,0DAAA;;AAAA,wBAAA,GAA2B,OAAA,CAAQ,2BAAR,CAA3B,CAAA;;AAAA,aACA,GAAgB,OAAA,CAAQ,yBAAR,CADhB,CAAA;;AAAA,MAEA,GAAS,OAAA,CAAQ,kBAAR,CAFT,CAAA;;AAAA;AAYe,EAAA,mBAAC,OAAD,EAAU,SAAV,GAAA;AACX,QAAA,sBAAA;AAAA,IAAA,IAAC,CAAA,EAAD,GAAU,IAAA,aAAA,CAAc,OAAd,CAAV,CAAA;AAAA,IACA,UAAA,GAAa,wBAAA,CAAyB,IAAC,CAAA,EAA1B,CADb,CAAA;AAAA,IAEA,IAAC,CAAA,MAAD,GAAc,IAAA,MAAA,CAAO,IAAC,CAAA,EAAR,EAAY,UAAU,CAAC,MAAvB,CAFd,CAAA;AAAA,IAGA,IAAC,CAAA,SAAD,GAAiB,IAAA,SAAA,CAAU,IAAC,CAAA,MAAX,EAAmB,IAAC,CAAA,EAApB,EAAwB,UAAU,CAAC,kBAAnC,EAAuD,IAAvD,CAHjB,CAAA;AAAA,IAKA,UAAA,GAAiB,IAAA,UAAU,CAAC,KAAK,CAAC,QAAjB,CAA0B,IAAC,CAAA,EAAE,CAAC,2BAAJ,CAAA,CAA1B,CALjB,CAAA;AAAA,IAMA,IAAC,CAAA,EAAE,CAAC,YAAJ,CAAiB,UAAjB,CAA4B,CAAC,OAA7B,CAAA,CANA,CAAA;AAAA,IAOA,IAAC,CAAA,YAAD,GAAgB,UAPhB,CADW;EAAA,CAAb;;AAAA,sBAcA,cAAA,GAAgB,SAAA,GAAA;WACd,IAAC,CAAA,aADa;EAAA,CAdhB,CAAA;;AAAA,sBAoBA,SAAA,GAAW,SAAA,GAAA;WACT,IAAC,CAAA,OADQ;EAAA,CApBX,CAAA;;AAAA,sBA0BA,YAAA,GAAc,SAAA,GAAA;WACZ,IAAC,CAAA,UADW;EAAA,CA1Bd,CAAA;;AAAA,sBAgCA,gBAAA,GAAkB,SAAA,GAAA;WAChB,IAAC,CAAA,GADe;EAAA,CAhClB,CAAA;;AAAA,sBAsCA,iBAAA,GAAmB,SAAC,OAAD,GAAA;WAChB,IAAC,CAAA,YAAY,CAAC,iBAAd,CAAgC,OAAhC,EADgB;EAAA,CAtCnB,CAAA;;AAAA,sBA8CA,SAAA,GAAW,SAAA,GAAA;WACT,IAAC,CAAA,EAAE,CAAC,SAAJ,CAAA,EADS;EAAA,CA9CX,CAAA;;AAAA,sBAoDA,GAAA,GAAM,SAAC,IAAD,EAAO,OAAP,EAAgB,OAAhB,GAAA;WACJ,IAAC,CAAA,YAAY,CAAC,GAAd,CAAkB,IAAlB,EAAwB,OAAxB,EAAiC,OAAjC,EADI;EAAA,CApDN,CAAA;;AAAA,EA0DA,MAAM,CAAC,cAAP,CAAsB,SAAS,CAAC,SAAhC,EAA2C,OAA3C,EACE;AAAA,IAAA,GAAA,EAAM,SAAA,GAAA;aAAG,IAAC,CAAA,YAAY,CAAC,MAAjB;IAAA,CAAN;AAAA,IACA,GAAA,EAAM,SAAC,CAAD,GAAA;AACJ,UAAA,uBAAA;AAAA,MAAA,IAAG,CAAC,CAAC,WAAF,KAAiB,EAAE,CAAC,WAAvB;AACE;aAAA,WAAA;4BAAA;AACE,wBAAA,IAAC,CAAA,GAAD,CAAK,MAAL,EAAa,KAAb,EAAoB,WAApB,EAAA,CADF;AAAA;wBADF;OAAA,MAAA;AAIE,cAAU,IAAA,KAAA,CAAM,kCAAN,CAAV,CAJF;OADI;IAAA,CADN;GADF,CA1DA,CAAA;;mBAAA;;IAZF,CAAA;;;EA8EA,MAAM,CAAE,SAAR,GAAoB;CA9EpB;;AAAA,MA+EM,CAAC,OAAP,GAAiB,SA/EjB,CAAA"
} }

View File

@ -12,6 +12,13 @@ HistoryBuffer = (function() {
return this.user_id; return this.user_id;
}; };
HistoryBuffer.prototype.getReservedUniqueIdentifier = function() {
return {
creator: '_',
op_number: '_'
};
};
HistoryBuffer.prototype.getOperationCounter = function() { HistoryBuffer.prototype.getOperationCounter = function() {
var ctn, res, user, _ref; var ctn, res, user, _ref;
res = {}; res = {};

View File

@ -6,5 +6,5 @@
"HistoryBuffer.coffee" "HistoryBuffer.coffee"
], ],
"names": [], "names": [],
"mappings": "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" "mappings": "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"
} }

View File

@ -222,7 +222,7 @@ module.exports = function(HB) {
__extends(ImmutableObject, _super); __extends(ImmutableObject, _super);
function ImmutableObject(uid, content, prev, next, origin) { function ImmutableObject(uid, content, prev, next, origin) {
this.content = content != null ? content : ""; this.content = content;
ImmutableObject.__super__.constructor.call(this, uid, prev, next, origin); ImmutableObject.__super__.constructor.call(this, uid, prev, next, origin);
} }

File diff suppressed because one or more lines are too long

View File

@ -112,10 +112,11 @@ module.exports = function(HB) {
return JsonType.__super__.val.call(this, name, obj); return JsonType.__super__.val.call(this, name, obj);
} else { } else {
if (typeof content === 'string') { if (typeof content === 'string') {
word = HB.addOperation(new types.Word(HB.getNextOperationIdentifier(), content)).execute(); word = HB.addOperation(new types.Word(void 0)).execute();
word.insertText(0, content);
return JsonType.__super__.val.call(this, name, word); return JsonType.__super__.val.call(this, name, word);
} else if (content.constructor === Object) { } else if (content.constructor === Object) {
json = HB.addOperation(new JsonType(HB.getNextOperationIdentifier(), content, mutable)).execute(); json = HB.addOperation(new JsonType(void 0, content, mutable)).execute();
return JsonType.__super__.val.call(this, name, json); return JsonType.__super__.val.call(this, name, json);
} else { } else {
throw new Error("You must not set " + (typeof content) + "-types in collaborative Json-objects!"); throw new Error("You must not set " + (typeof content) + "-types in collaborative Json-objects!");

View File

@ -6,5 +6,5 @@
"JsonTypes.coffee" "JsonTypes.coffee"
], ],
"names": [], "names": [],
"mappings": "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" "mappings": "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"
} }

View File

@ -21,7 +21,7 @@ module.exports = function(HB) {
var o, obj, result, _ref, _ref1; var o, obj, result, _ref, _ref1;
if (content != null) { if (content != null) {
if (this.map[name] == null) { if (this.map[name] == null) {
HB.addOperation(new AddName(HB.getNextOperationIdentifier(), this, name)).execute(); HB.addOperation(new AddName(void 0, this, name)).execute();
} }
this.map[name].replace(content); this.map[name].replace(content);
return this; return this;
@ -105,8 +105,8 @@ module.exports = function(HB) {
this.saveOperation('beginning', beginning); this.saveOperation('beginning', beginning);
this.saveOperation('end', end); this.saveOperation('end', end);
} else { } else {
this.beginning = HB.addOperation(new types.Delimiter(HB.getNextOperationIdentifier(), void 0, void 0)); this.beginning = HB.addOperation(new types.Delimiter(void 0, void 0, void 0));
this.end = HB.addOperation(new types.Delimiter(HB.getNextOperationIdentifier(), this.beginning, void 0)); this.end = HB.addOperation(new types.Delimiter(void 0, this.beginning, void 0));
this.beginning.next_cl = this.end; this.beginning.next_cl = this.end;
this.beginning.execute(); this.beginning.execute();
this.end.execute(); this.end.execute();
@ -169,7 +169,7 @@ module.exports = function(HB) {
ReplaceManager.prototype.replace = function(content) { ReplaceManager.prototype.replace = function(content) {
var o, op; var o, op;
o = this.getLastOperation(); o = this.getLastOperation();
op = new Replaceable(content, this, HB.getNextOperationIdentifier(), o, o.next_cl); op = new Replaceable(content, this, void 0, o, o.next_cl);
return HB.addOperation(op).execute(); return HB.addOperation(op).execute();
}; };

File diff suppressed because one or more lines are too long

View File

@ -73,11 +73,8 @@ module.exports = function(HB) {
Word = (function(_super) { Word = (function(_super) {
__extends(Word, _super); __extends(Word, _super);
function Word(uid, initial_content, beginning, end, prev, next, origin) { function Word(uid, beginning, end, prev, next, origin) {
Word.__super__.constructor.call(this, uid, beginning, end, prev, next, origin); Word.__super__.constructor.call(this, uid, beginning, end, prev, next, origin);
if (initial_content != null) {
this.insertText(0, initial_content);
}
} }
Word.prototype.insertText = function(position, content) { Word.prototype.insertText = function(position, content) {
@ -86,7 +83,7 @@ module.exports = function(HB) {
_results = []; _results = [];
for (_i = 0, _len = content.length; _i < _len; _i++) { for (_i = 0, _len = content.length; _i < _len; _i++) {
c = content[_i]; c = content[_i];
op = new TextInsert(c, HB.getNextOperationIdentifier(), o.prev_cl, o); op = new TextInsert(c, void 0, o.prev_cl, o);
_results.push(HB.addOperation(op).execute()); _results.push(HB.addOperation(op).execute());
} }
return _results; return _results;
@ -171,7 +168,7 @@ module.exports = function(HB) {
parser['Word'] = function(json) { parser['Word'] = function(json) {
var beginning, end, next, origin, prev, uid; var beginning, end, next, origin, prev, uid;
uid = json['uid'], beginning = json['beginning'], end = json['end'], prev = json['prev'], next = json['next'], origin = json['origin']; uid = json['uid'], beginning = json['beginning'], end = json['end'], prev = json['prev'], next = json['next'], origin = json['origin'];
return new Word(uid, void 0, beginning, end, prev, next, origin); return new Word(uid, beginning, end, prev, next, origin);
}; };
types['TextInsert'] = TextInsert; types['TextInsert'] = TextInsert;
types['TextDelete'] = TextDelete; types['TextDelete'] = TextDelete;

View File

@ -6,5 +6,5 @@
"TextTypes.coffee" "TextTypes.coffee"
], ],
"names": [], "names": [],
"mappings": "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" "mappings": "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"
} }

View File

@ -6,5 +6,5 @@
"XmlTypes.coffee" "XmlTypes.coffee"
], ],
"names": [], "names": [],
"mappings": "AA6KkB" "mappings": "AA2KkB"
} }

View File

@ -1,159 +0,0 @@
(function() {
var Connector_uninitialized, Yatta, chai, expect, should, sinon, sinonChai, _;
chai = require('chai');
expect = chai.expect;
should = chai.should();
sinon = require('sinon');
sinonChai = require('sinon-chai');
_ = require("underscore");
chai.use(sinonChai);
Yatta = require("../lib/Frameworks/JsonYatta.coffee");
Connector_uninitialized = require("../lib/Connectors/TestConnector.coffee");
/*
describe "JsonYatta", ->
beforeEach (done)->
@last_user = 10
@users = []
@Connector = Connector_uninitialized @users
for i in [0..(@last_user+1)]
@users.push(new Yatta i, @Connector)
done()
it "can handle many engines, many operations, concurrently (random)", ->
number_of_test_cases_multiplier = 1
repeat_this = 100 * number_of_test_cases_multiplier
doSomething_amount = 200 * number_of_test_cases_multiplier
number_of_engines = 12 + number_of_test_cases_multiplier - 1
@time = 0
@ops = 0
users = []
generateInsertOp = (user_num)->
chars = "1234567890"
pos = _.random 0, (users[user_num].val('name').length-1)
length = 1 #_.random 0, 10
nextchar = chars[(_.random 0, (chars.length-1))]
text = ""
_(length).times ()-> text += nextchar
users[user_num].val('name').insertText pos, text
null
generateReplaceOp = (user_num)->
chars = "abcdefghijklmnopqrstuvwxyz"
length = _.random 0, 10
nextchar = chars[(_.random 0, (chars.length-1))]
text = ""
_(length).times ()-> text += nextchar
users[user_num].val('name').replaceText text
generateDeleteOp = (user_num)->
if users[user_num].val('name').val().length > 0
pos = _.random 0, (users[user_num].val('name').val().length-1)
length = 1 # _.random 0, ot.val('name').length - pos
ops1 = users[user_num].val('name').deleteText pos, length
undefined
generateRandomOp = (user_num)->
op_gen = [generateDeleteOp, generateInsertOp, generateReplaceOp]
i = _.random (op_gen.length - 1)
op = op_gen[i](user_num)
applyRandomOp = (user_num)->
user = users[user_num]
user.getConnector().flushOneRandom()
doSomething = do ()->
()->
user_num = _.random (number_of_engines-1)
choices = [applyRandomOp, generateRandomOp]
*if (users[user_num].buffer[user_num].length < maximum_ops_per_engine)
* choices = choices.concat generateRandomOp
choice = _.random (choices.length-1)
choices[choice](user_num)
console.log ""
for times in [1..repeat_this]
*console.log "repeated_this x #{times} times"
users = []
Connector = Connector_uninitialized users
users.push(new Yatta 0, Connector)
users[0].val('name',"initial")
for i in [1...number_of_engines]
users.push(new Yatta i, Connector)
found_error = false
*try
time_now = (new Date).getTime()
for i in [1..doSomething_amount]
doSomething()
for user,user_number in users
user.getConnector().flushAll()
@time += (new Date()).getTime() - time_now
number_of_created_operations = 0
for i in [0...(users.length)]
number_of_created_operations += users[i].getConnector().getOpsInExecutionOrder().length
@ops += number_of_created_operations*users.length
ops_per_msek = Math.floor(@ops/@time)
console.log "#{times}/#{repeat_this}: Every collaborator (#{users.length}) applied #{number_of_created_operations} ops in a different order." + " Over all we consumed #{@ops} operations in #{@time/1000} seconds (#{ops_per_msek} ops/msek)."
console.log users[0].val('name').val()
for i in [0...(users.length-1)]
if ((users[i].val('name').val() isnt users[i+1].val('name').val()) )# and (number_of_created_operations <= 6 or true)) or found_error
printOpsInExecutionOrder = (otnumber, otherotnumber)->
ops = users[otnumber].getConnector().getOpsInExecutionOrder()
for s in ops
console.log JSON.stringify s
console.log ""
s = "ops = ["
for o,j in ops
if j isnt 0
s += ", "
s += "op#{j}"
s += "]"
console.log s
console.log "@users[@last_user].ot.applyOps ops"
console.log "expect(@users[@last_user].ot.val('name')).to.equal(\"#{users[otherotnumber].val('name')}\")"
ops
console.log ""
console.log "Found an OT Puzzle!"
console.log "OT states:"
for u,j in users
console.log "OT#{j}: "+u.val('name')
console.log "\nOT execution order (#{i},#{i+1}):"
printOpsInExecutionOrder i, i+1
console.log ""
ops = printOpsInExecutionOrder i+1, i
console.log ""
*/
}).call(this);

View File

@ -1,163 +0,0 @@
(function() {
var Connector_uninitialized, Yatta, chai, expect, should, sinon, sinonChai, _;
chai = require('chai');
expect = chai.expect;
should = chai.should();
sinon = require('sinon');
sinonChai = require('sinon-chai');
_ = require("underscore");
chai.use(sinonChai);
Yatta = require("../lib/Frameworks/TextYatta.coffee");
Connector_uninitialized = require("../lib/Connectors/TestConnector.coffee");
/*
describe "TextYatta", ->
beforeEach (done)->
@last_user = 10
@users = []
@Connector = Connector_uninitialized @users
for i in [0..(@last_user+1)]
@users.push(new Yatta i, @Connector)
done()
it "handles inserts correctly", ->
it "can handle many engines, many operations, concurrently (random)", ->
number_of_test_cases_multiplier = 1
repeat_this = 1 * number_of_test_cases_multiplier
doSomething_amount = 500 * number_of_test_cases_multiplier
number_of_engines = 12 + number_of_test_cases_multiplier - 1
*maximum_ops_per_engine = 20 * number_of_test_cases_multiplier
@time = 0
@ops = 0
users = []
generateInsertOp = (user_num)->
chars = "1234567890"
pos = _.random 0, (users[user_num].val().length-1)
length = 1 #_.random 0, 10
nextchar = chars[(_.random 0, (chars.length-1))]
text = ""
_(length).times ()-> text += nextchar
users[user_num].insertText pos, text
null
generateReplaceOp = (user_num)->
chars = "abcdefghijklmnopqrstuvwxyz"
length = _.random 0, 10
nextchar = chars[(_.random 0, (chars.length-1))]
text = ""
_(length).times ()-> text += nextchar
users[user_num].replaceText text
generateDeleteOp = (user_num)->
if users[user_num].val().length > 0
pos = _.random 0, (users[user_num].val().length-1)
length = 1 # _.random 0, ot.val().length - pos
ops1 = users[user_num].deleteText pos, length
undefined
generateRandomOp = (user_num)->
op_gen = [generateDeleteOp, generateInsertOp, generateReplaceOp]
i = _.random (op_gen.length - 1)
op = op_gen[i](user_num)
applyRandomOp = (user_num)->
user = users[user_num]
user.getConnector().flushOneRandom()
doSomething = do ()->
()->
user_num = _.random (number_of_engines-1)
choices = [applyRandomOp, generateRandomOp]
*if (users[user_num].buffer[user_num].length < maximum_ops_per_engine)
* choices = choices.concat generateRandomOp
choice = _.random (choices.length-1)
choices[choice](user_num)
console.log ""
for times in [1..repeat_this]
*console.log "repeated_this x #{times} times"
users = []
Connector = Connector_uninitialized users
for i in [0..number_of_engines]
users.push(new Yatta i, Connector)
found_error = false
*try
time_now = (new Date).getTime()
for i in [1..doSomething_amount]
doSomething()
for user,user_number in users
user.getConnector().flushAll()
@time += (new Date()).getTime() - time_now
number_of_created_operations = 0
for i in [0...(users.length)]
number_of_created_operations += users[i].getConnector().getOpsInExecutionOrder().length
@ops += number_of_created_operations*users.length
ops_per_msek = Math.floor(@ops/@time)
console.log "#{times}/#{repeat_this}: Every collaborator (#{users.length}) applied #{number_of_created_operations} ops in a different order." + " Over all we consumed #{@ops} operations in #{@time/1000} seconds (#{ops_per_msek} ops/msek)."
console.log users[0].val()
found_inconsistency = false
for i in [0...(users.length-1)]
if ((users[i].val() isnt users[i+1].val()) )# and (number_of_created_operations <= 6 or true)) or found_error
found_inconsistency =true
printOpsInExecutionOrder = (otnumber, otherotnumber)->
ops = users[otnumber].getConnector().getOpsInExecutionOrder()
for s,j in ops
console.log "op#{j} = #{JSON.stringify s}"
console.log ""
s = "ops = ["
for o,j in ops
if j isnt 0
s += ", "
s += "op#{j}"
s += "]"
console.log s
console.log "@users[@last_user].ot.applyOps ops"
console.log "expect(@users[@last_user].val()).to.equal(\"#{users[otherotnumber].val()}\")"
ops
console.log ""
console.log "Found an OT Puzzle!"
console.log "OT states:"
for u,j in users
console.log "OT#{j}: "+u.val()
console.log "\nOT execution order (#{i},#{i+1}):"
printOpsInExecutionOrder i, i+1
console.log ""
ops = printOpsInExecutionOrder i+1, i
console.log ""
if found_inconsistency
throw new Error "dtrn"
* expect(users[i].ot.val()).to.equal(users[i+1].ot.val())
*/
}).call(this);

View File

@ -34,6 +34,7 @@
this.time = 0; this.time = 0;
this.ops = 0; this.ops = 0;
this.time_now = 0; this.time_now = 0;
this.debug = false;
this.reinitialize(); this.reinitialize();
} }
@ -123,7 +124,7 @@
}; };
Test.prototype.compareAll = function(test_number) { Test.prototype.compareAll = function(test_number) {
var i, j, number_of_created_operations, ops, ops_per_msek, printOpsInExecutionOrder, u, _i, _j, _k, _len, _ref, _ref1, _results; var i, j, number_of_created_operations, ops, ops_per_msek, printOpsInExecutionOrder, u, _i, _j, _k, _len, _ref, _ref1, _ref2, _results;
this.flushAll(); this.flushAll();
this.time += (new Date()).getTime() - this.time_now; this.time += (new Date()).getTime() - this.time_now;
number_of_created_operations = 0; number_of_created_operations = 0;
@ -135,12 +136,17 @@
if (test_number != null) { if (test_number != null) {
console.log(("" + test_number + "/" + this.repeat_this + ": Every collaborator (" + this.users.length + ") applied " + number_of_created_operations + " ops in a different order.") + (" Over all we consumed " + this.ops + " operations in " + (this.time / 1000) + " seconds (" + ops_per_msek + " ops/msek).")); console.log(("" + test_number + "/" + this.repeat_this + ": Every collaborator (" + this.users.length + ") applied " + number_of_created_operations + " ops in a different order.") + (" Over all we consumed " + this.ops + " operations in " + (this.time / 1000) + " seconds (" + ops_per_msek + " ops/msek)."));
} }
console.log(this.users.length);
_results = []; _results = [];
for (i = _j = 0, _ref1 = this.users.length - 1; 0 <= _ref1 ? _j < _ref1 : _j > _ref1; i = 0 <= _ref1 ? ++_j : --_j) { for (i = _j = 0, _ref1 = this.users.length - 1; 0 <= _ref1 ? _j < _ref1 : _j > _ref1; i = 0 <= _ref1 ? ++_j : --_j) {
if (!this.debug) {
_results.push(expect(this.users[i].val('name').val()).to.equal(this.users[i + 1].val('name').val()));
} else {
if (this.users[i].val('name').val() !== this.users[i + 1].val('name').val()) { if (this.users[i].val('name').val() !== this.users[i + 1].val('name').val()) {
printOpsInExecutionOrder = function(otnumber, otherotnumber) { printOpsInExecutionOrder = (function(_this) {
return function(otnumber, otherotnumber) {
var j, o, ops, s, _k, _l, _len, _len1; var j, o, ops, s, _k, _l, _len, _len1;
ops = this.users[otnumber].getConnector().getOpsInExecutionOrder(); ops = _this.users[otnumber].getConnector().getOpsInExecutionOrder();
for (_k = 0, _len = ops.length; _k < _len; _k++) { for (_k = 0, _len = ops.length; _k < _len; _k++) {
s = ops[_k]; s = ops[_k];
console.log(JSON.stringify(s)); console.log(JSON.stringify(s));
@ -157,14 +163,16 @@
s += "]"; s += "]";
console.log(s); console.log(s);
console.log("@users[@last_user].ot.applyOps ops"); console.log("@users[@last_user].ot.applyOps ops");
console.log("expect(@users[@last_user].ot.val('name')).to.equal(\"" + (users[otherotnumber].val('name')) + "\")"); console.log("expect(@users[@last_user].ot.val('name')).to.equal(\"" + (_this.users[otherotnumber].val('name')) + "\")");
return ops; return ops;
}; };
})(this);
console.log(""); console.log("");
console.log("Found an OT Puzzle!"); console.log("Found an OT Puzzle!");
console.log("OT states:"); console.log("OT states:");
for (j = _k = 0, _len = users.length; _k < _len; j = ++_k) { _ref2 = this.users;
u = users[j]; for (j = _k = 0, _len = _ref2.length; _k < _len; j = ++_k) {
u = _ref2[j];
console.log(("OT" + j + ": ") + u.val('name')); console.log(("OT" + j + ": ") + u.val('name'));
} }
console.log("\nOT execution order (" + i + "," + (i + 1) + "):"); console.log("\nOT execution order (" + i + "," + (i + 1) + "):");
@ -176,6 +184,7 @@
_results.push(void 0); _results.push(void 0);
} }
} }
}
return _results; return _results;
}; };

View File

@ -342,7 +342,7 @@
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
August 05, 14 20:37:47 by August 07, 14 21:48:38 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -142,7 +142,7 @@ only one will AddName operation will be executed.</p>
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
August 05, 14 20:37:47 by August 07, 14 21:48:38 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -157,7 +157,7 @@ This result can be sent to other clients.</p>
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
August 05, 14 20:37:47 by August 07, 14 21:48:38 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -118,7 +118,7 @@ of the Engine is empty.</p>
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
August 05, 14 20:37:47 by August 07, 14 21:48:38 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -72,6 +72,11 @@
</a> </a>
</span> </span>
<span class='desc'> <span class='desc'>
<p>ops = [] for o in ops_json ops.push @parseOperation o
for o in ops @HB.addOperation o
for o in ops if not o.execute()
@unprocessed_ops.push o
@tryUnprocessed()</p>
</span> </span>
</li> </li>
<li> <li>
@ -125,7 +130,16 @@
<b>applyOp</b><span>(op_json)</span> <b>applyOp</b><span>(op_json)</span>
<br> <br>
</p> </p>
<div class='docstring'>
<p>ops = []
for o in ops_json ops.push @parseOperation o
for o in ops @HB.addOperation o
for o in ops if not o.execute()
@unprocessed_ops.push o
@tryUnprocessed()</p>
</div>
<div class='tags'>
</div>
</div> </div>
<div class='method_details'> <div class='method_details'>
<p class='signature' id='tryUnprocessed-dynamic'> <p class='signature' id='tryUnprocessed-dynamic'>
@ -139,7 +153,7 @@
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
August 05, 14 20:37:47 by August 07, 14 21:48:38 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -57,6 +57,18 @@
Get the user id with wich the History Buffer was initialized. Get the user id with wich the History Buffer was initialized.
</span> </span>
</li> </li>
<li>
<span class='signature'>
<a href='#getReservedUniqueIdentifier-dynamic'>
#
(void)
<b>getReservedUniqueIdentifier</b><span>()</span>
</a>
</span>
<span class='desc'>
There is only one reserved unique identifier (uid), so use it wisely.
</span>
</li>
<li> <li>
<span class='signature'> <span class='signature'>
<a href='#getOperationCounter-dynamic'> <a href='#getOperationCounter-dynamic'>
@ -159,6 +171,22 @@
<p>Get the user id with wich the History Buffer was initialized.</p> <p>Get the user id with wich the History Buffer was initialized.</p>
</div> </div>
<div class='tags'> <div class='tags'>
</div>
</div>
<div class='method_details'>
<p class='signature' id='getReservedUniqueIdentifier-dynamic'>
#
(void)
<b>getReservedUniqueIdentifier</b><span>()</span>
<br>
</p>
<div class='docstring'>
<p>There is only one reserved unique identifier (uid), so use it wisely.
I propose to use it in your Framework, to create something like a root element.
An operation with this identifier is not propagated to other clients.
This is why everybode must create the same operation with this uid.</p>
</div>
<div class='tags'>
</div> </div>
</div> </div>
<div class='method_details'> <div class='method_details'>
@ -228,7 +256,7 @@ other operations (it wont executed)</p>
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
August 05, 14 20:37:47 by August 07, 14 21:48:38 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -93,7 +93,7 @@
<p class='signature' id='constructor-dynamic'> <p class='signature' id='constructor-dynamic'>
# #
(void) (void)
<b>constructor</b><span>(uid, content = &quot;&quot;, prev, next, origin)</span> <b>constructor</b><span>(uid, content, prev, next, origin)</span>
<br> <br>
</p> </p>
<div class='tags'> <div class='tags'>
@ -156,7 +156,7 @@
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
August 05, 14 20:37:47 by August 07, 14 21:48:38 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -256,7 +256,7 @@ TODO (Unused)</p>
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
August 05, 14 20:37:47 by August 07, 14 21:48:38 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -168,7 +168,7 @@
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
August 05, 14 20:37:47 by August 07, 14 21:48:38 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -286,7 +286,7 @@
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
August 05, 14 20:37:47 by August 07, 14 21:48:38 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -121,7 +121,7 @@ console.log(w.newProperty == &quot;Awesome&quot;) # true!</code></pre>
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
August 05, 14 20:37:47 by August 07, 14 21:48:38 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -250,7 +250,7 @@ JsonYatta was initialized (Depending on the HistoryBuffer implementation).</p>
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
August 05, 14 20:37:47 by August 07, 14 21:48:38 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -208,7 +208,7 @@ Doesn&#39;t return left-right delimiter.</p>
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
August 05, 14 20:37:47 by August 07, 14 21:48:38 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -99,7 +99,7 @@
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
August 05, 14 20:37:47 by August 07, 14 21:48:38 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -284,7 +284,7 @@ an easy way to refer to these operations via an uid or object reference.</p><p>F
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
August 05, 14 20:37:47 by August 07, 14 21:48:38 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -189,7 +189,7 @@ Each Replaceable holds a value that is now replaceable.</p><p>The Word-type has
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
August 05, 14 20:37:47 by August 07, 14 21:48:38 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -191,7 +191,7 @@ This result can be send to other clients.</p>
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
August 05, 14 20:37:47 by August 07, 14 21:48:38 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -219,7 +219,7 @@
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
August 05, 14 20:37:47 by August 07, 14 21:48:38 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -53,7 +53,7 @@
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
August 05, 14 20:37:47 by August 07, 14 21:48:38 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -173,7 +173,7 @@ This result can be send to other clients.</p>
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
August 05, 14 20:37:47 by August 07, 14 21:48:38 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -239,7 +239,7 @@
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
August 05, 14 20:37:47 by August 07, 14 21:48:38 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -126,7 +126,7 @@
<p class='signature' id='constructor-dynamic'> <p class='signature' id='constructor-dynamic'>
# #
(void) (void)
<b>constructor</b><span>(uid, initial_content, beginning, end, prev, next, origin)</span> <b>constructor</b><span>(uid, beginning, end, prev, next, origin)</span>
<br> <br>
</p> </p>
<div class='tags'> <div class='tags'>
@ -142,14 +142,6 @@
&mdash; &mdash;
<span class='desc'>A unique identifier. If uid is undefined, a new uid will be created. </span> <span class='desc'>A unique identifier. If uid is undefined, a new uid will be created. </span>
</li> </li>
<li>
<span class='name'>initial_content</span>
<span class='type'>
(
<tt>String</tt>
)
</span>
</li>
</ul> </ul>
</div> </div>
</div> </div>
@ -241,7 +233,7 @@ to provide replace functionality.</p>
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
August 05, 14 20:37:47 by August 07, 14 21:48:38 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -38,7 +38,7 @@
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
August 05, 14 20:37:47 by August 07, 14 21:48:38 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -34,11 +34,35 @@
</p> </p>
</nav> </nav>
<div id='filecontents'> <div id='filecontents'>
<h1 id="-yatta-yatta-svg-raw-true-"><a href="./Yatta.svg?raw=true">Yatta!</a></h1><p>A Collaboration Framework for arbitrary data structures that is <em>not</em> based on Operational Transformation.</p><h1 id="license">License</h1><p>Yatta! is licensed under the <a href="./LICENSE.txt">MIT license</a>.</p> <h1 id="-yatta-extras-imgs-yatta_logo-png-raw-true-"><img src="./extras/imgs/Yatta_logo.png?raw=true" alt="Yatta!"></h1><p>A real-time web framework that manages concurrency control for arbitrary data structures and is <em>not</em> based on Operational Transformation.
Yatta! provides similar functionality as <a href="https://github.com/share/ShareJS">ShareJs</a> and <a href="https://github.com/opencoweb/coweb">OpenCoweb</a>
but does not require you to understand how the internals work. The predefined data structures provide a simple API to access your shared data structures.</p><p>Predefined data structures:</p><ul>
<li>Text</li>
<li>Json - <a href="./examples/IwcJson.md">example</a></li>
<li>XML (coming soon)</li>
</ul><p>Unlike other frameworks, Yatta! supports P2P message propagation and is not bound to a specific communication protocol.</p><p>Currently supported communication protocols:</p><ul>
<li><a href="http://dbis.rwth-aachen.de/gadgets/iwc/resources/iwc.manual.pdf">IWC</a> - Inter-widget Communication</li>
</ul>
<h1 id="about">About</h1><p>Find out more about the concurrent editing problem here
<a href="http://opencoweb.org/ocwdocs/intro/openg.html">Cooperation, Concurrency, Conflicts, and Convergence</a> and here
<a href="http://en.wikipedia.org/wiki/Operational_transformation">Operational Transformation (OT)</a></p><p>My Bachelor Thesis project aim was to develop a P2P OT Framework that enables collaboration on XML documents and supports
<a href="http://www3.ntu.edu.sg/home/czsun/projects/otfaq/#intentionPreservation">Intention Preservation</a>.
After some time I realized that OT has significant drawbacks in P2P environments.</p><p>With my gained experiences I came up with a new approach. I named it Yata - Yet Another Transformation Approach.
It enables concurrent editing with the following space and time properties:</p><ul>
<li>Time complexity: O(S), whereby S is the number of operations that are inserted concurrently at the same position. This means that my approach does not transform against operations that happen on other positions.</li>
<li>Space complexity = O(|Document|), whereby |Document| is the size of the shared document. Depending on the used data structure, Yata may needs 4*|Document| of space.</li>
</ul><p>This means that my approach beats all OT time complexities. Furthermore, it is possible to make a very strict definition of Intention Preservation, and I was able to
show that it is never violated.</p><p>Another advantage of my approach is that propagated messages are very small.
Background: In real-time P2P OT algorithms you have to send a state-vector with every message that defines the state of the History Buffer
on which the operation was created. This is not necessary in Yata.</p><p>One downside is that the History Buffer holds at least as many operations as there are characters in the document.
In contrast, an OT algorithm can have an empty History Buffer while the document size is very big.</p><p>So, how did I come up with the name for the implementation (Yatta! is not Yata)?
<img src="./extras/imgs/YATTA.png" alt="YATTA!">
Yatta! means &quot;I did it!&quot; in Japanese. You scream it when you accomplish something (for proper application I refer to the Yatta-man in <a href="http://heroeswiki.com/Yatta!">Heroes</a>).
There is also this awesome video on the Internet that will change your life <a href="https://www.youtube.com/watch?v=kL5DDSglM_s">Yatta</a>.</p><h1 id="status">Status</h1><p>Yatta! is still in an early development phase.</p><h1 id="support">Support</h1><p>Please report any issues to the <a href="https://github.com/DadaMonad/Yatta/issues">Github issue page</a>!</p><h1 id="license">License</h1><p>Yatta! is licensed under the <a href="./LICENSE.txt">MIT License</a>.</p>
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
August 05, 14 20:37:47 by August 07, 14 21:48:38 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -103,7 +103,7 @@ window.onload = init
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
August 05, 14 20:37:47 by August 07, 14 21:48:38 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -43,7 +43,7 @@
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
August 05, 14 20:37:47 by August 07, 14 21:48:38 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -84,7 +84,7 @@
</div> </div>
</div> </div>
<div id='footer'> <div id='footer'>
August 05, 14 20:37:47 by August 07, 14 21:48:38 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -39,7 +39,7 @@
</table> </table>
</div> </div>
<div id='footer'> <div id='footer'>
August 05, 14 20:37:47 by August 07, 14 21:48:38 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -58,7 +58,7 @@
</dl> </dl>
</div> </div>
<div id='footer'> <div id='footer'>
August 05, 14 20:37:47 by August 07, 14 21:48:38 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -68,7 +68,7 @@
</dl> </dl>
</div> </div>
<div id='footer'> <div id='footer'>
August 05, 14 20:37:47 by August 07, 14 21:48:38 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -60,7 +60,7 @@
</dl> </dl>
</div> </div>
<div id='footer'> <div id='footer'>
August 05, 14 20:37:47 by August 07, 14 21:48:38 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -58,7 +58,7 @@
</dl> </dl>
</div> </div>
<div id='footer'> <div id='footer'>
August 05, 14 20:37:47 by August 07, 14 21:48:38 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -39,7 +39,7 @@
</table> </table>
</div> </div>
<div id='footer'> <div id='footer'>
August 05, 14 20:37:47 by August 07, 14 21:48:38 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -39,7 +39,7 @@
</table> </table>
</div> </div>
<div id='footer'> <div id='footer'>
August 05, 14 20:37:47 by August 07, 14 21:48:38 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -39,7 +39,7 @@
</table> </table>
</div> </div>
<div id='footer'> <div id='footer'>
August 05, 14 20:37:47 by August 07, 14 21:48:38 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -39,7 +39,7 @@
</table> </table>
</div> </div>
<div id='footer'> <div id='footer'>
August 05, 14 20:37:47 by August 07, 14 21:48:38 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

View File

@ -39,7 +39,7 @@
</table> </table>
</div> </div>
<div id='footer'> <div id='footer'>
August 05, 14 20:37:47 by August 07, 14 21:48:38 by
<a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'> <a href='https://github.com/coffeedoc/codo' title='CoffeeScript API documentation generator'>
Codo Codo
</a> </a>

File diff suppressed because one or more lines are too long

View File

@ -301,14 +301,6 @@
(lib&#47;Connectors&#47;IwcConnector.coffee) (lib&#47;Connectors&#47;IwcConnector.coffee)
</small> </small>
</li> </li>
<li>
<a href='class/Word.html#deleteText-dynamic' target='main' title='deleteText'>
#deleteText
</a>
<small>
(Word)
</small>
</li>
<li> <li>
<a href='class/TextYatta.html#deleteText-dynamic' target='main' title='deleteText'> <a href='class/TextYatta.html#deleteText-dynamic' target='main' title='deleteText'>
#deleteText #deleteText
@ -317,6 +309,14 @@
(TextYatta) (TextYatta)
</small> </small>
</li> </li>
<li>
<a href='class/Word.html#deleteText-dynamic' target='main' title='deleteText'>
#deleteText
</a>
<small>
(Word)
</small>
</li>
<li> <li>
<a href='class/Operation.html#execute-dynamic' target='main' title='execute'> <a href='class/Operation.html#execute-dynamic' target='main' title='execute'>
#execute #execute
@ -326,11 +326,11 @@
</small> </small>
</li> </li>
<li> <li>
<a href='class/Delimiter.html#execute-dynamic' target='main' title='execute'> <a href='class/AddName.html#execute-dynamic' target='main' title='execute'>
#execute #execute
</a> </a>
<small> <small>
(Delimiter) (AddName)
</small> </small>
</li> </li>
<li> <li>
@ -350,11 +350,11 @@
</small> </small>
</li> </li>
<li> <li>
<a href='class/AddName.html#execute-dynamic' target='main' title='execute'> <a href='class/Delimiter.html#execute-dynamic' target='main' title='execute'>
#execute #execute
</a> </a>
<small> <small>
(AddName) (Delimiter)
</small> </small>
</li> </li>
<li> <li>
@ -510,11 +510,11 @@
</small> </small>
</li> </li>
<li> <li>
<a href='class/JsonYatta.html#getRootElement-dynamic' target='main' title='getRootElement'> <a href='class/HistoryBuffer.html#getReservedUniqueIdentifier-dynamic' target='main' title='getReservedUniqueIdentifier'>
#getRootElement #getReservedUniqueIdentifier
</a> </a>
<small> <small>
(JsonYatta) (HistoryBuffer)
</small> </small>
</li> </li>
<li> <li>
@ -525,6 +525,14 @@
(IwcConnector) (IwcConnector)
</small> </small>
</li> </li>
<li>
<a href='class/JsonYatta.html#getRootElement-dynamic' target='main' title='getRootElement'>
#getRootElement
</a>
<small>
(JsonYatta)
</small>
</li>
<li> <li>
<a href='class/TestConnector.html#getRootElement-dynamic' target='main' title='getRootElement'> <a href='class/TestConnector.html#getRootElement-dynamic' target='main' title='getRootElement'>
#getRootElement #getRootElement
@ -550,11 +558,11 @@
</small> </small>
</li> </li>
<li> <li>
<a href='class/TextYatta.html#getUserId-dynamic' target='main' title='getUserId'> <a href='class/JsonYatta.html#getUserId-dynamic' target='main' title='getUserId'>
#getUserId #getUserId
</a> </a>
<small> <small>
(TextYatta) (JsonYatta)
</small> </small>
</li> </li>
<li> <li>
@ -566,11 +574,11 @@
</small> </small>
</li> </li>
<li> <li>
<a href='class/JsonYatta.html#getUserId-dynamic' target='main' title='getUserId'> <a href='class/TextYatta.html#getUserId-dynamic' target='main' title='getUserId'>
#getUserId #getUserId
</a> </a>
<small> <small>
(JsonYatta) (TextYatta)
</small> </small>
</li> </li>
<li> <li>
@ -661,14 +669,6 @@
(Operation) (Operation)
</small> </small>
</li> </li>
<li>
<a href='class/TestConnector.html#send-dynamic' target='main' title='send'>
#send
</a>
<small>
(TestConnector)
</small>
</li>
<li> <li>
<a href='class/IwcConnector.html#send-dynamic' target='main' title='send'> <a href='class/IwcConnector.html#send-dynamic' target='main' title='send'>
#send #send
@ -677,6 +677,14 @@
(IwcConnector) (IwcConnector)
</small> </small>
</li> </li>
<li>
<a href='class/TestConnector.html#send-dynamic' target='main' title='send'>
#send
</a>
<small>
(TestConnector)
</small>
</li>
<li> <li>
<a href='class/IwcConnector.html#sendIwcIntent-dynamic' target='main' title='sendIwcIntent'> <a href='class/IwcConnector.html#sendIwcIntent-dynamic' target='main' title='sendIwcIntent'>
#sendIwcIntent #sendIwcIntent
@ -765,6 +773,22 @@
(TextInsert) (TextInsert)
</small> </small>
</li> </li>
<li>
<a href='class/JsonType.html#val-dynamic' target='main' title='val'>
#val
</a>
<small>
(JsonType)
</small>
</li>
<li>
<a href='class/TextYatta.html#val-dynamic' target='main' title='val'>
#val
</a>
<small>
(TextYatta)
</small>
</li>
<li> <li>
<a href='class/Replaceable.html#val-dynamic' target='main' title='val'> <a href='class/Replaceable.html#val-dynamic' target='main' title='val'>
#val #val
@ -781,22 +805,6 @@
(MapManager) (MapManager)
</small> </small>
</li> </li>
<li>
<a href='class/TextYatta.html#val-dynamic' target='main' title='val'>
#val
</a>
<small>
(TextYatta)
</small>
</li>
<li>
<a href='class/JsonType.html#val-dynamic' target='main' title='val'>
#val
</a>
<small>
(JsonType)
</small>
</li>
<li> <li>
<a href='class/JsonYatta.html#val-dynamic' target='main' title='val'> <a href='class/JsonYatta.html#val-dynamic' target='main' title='val'>
#val #val

View File

@ -35,8 +35,8 @@ module.exports = (user_list)->
user.getConnector().receive(o) user.getConnector().receive(o)
receive: (o)-> receive: (o)->
@unexecuted[o.creator] ?= [] @unexecuted[o.uid.creator] ?= []
@unexecuted[o.creator].push o @unexecuted[o.uid.creator].push o
flushOne: (user)-> flushOne: (user)->
if @unexecuted[user]?.length > 0 if @unexecuted[user]?.length > 0

View File

@ -14,6 +14,9 @@ class Engine
throw new Error "You forgot to specify a parser for type #{json.type}. The message is #{JSON.stringify json}." throw new Error "You forgot to specify a parser for type #{json.type}. The message is #{JSON.stringify json}."
applyOps: (ops_json)-> applyOps: (ops_json)->
for o in ops_json
@applyOp o
###
ops = [] ops = []
for o in ops_json for o in ops_json
ops.push @parseOperation o ops.push @parseOperation o
@ -23,7 +26,7 @@ class Engine
if not o.execute() if not o.execute()
@unprocessed_ops.push o @unprocessed_ops.push o
@tryUnprocessed() @tryUnprocessed()
###
applyOp: (op_json)-> applyOp: (op_json)->
# $parse_and_execute will return false if $o_json was parsed and executed, otherwise the parsed operadion # $parse_and_execute will return false if $o_json was parsed and executed, otherwise the parsed operadion
o = @parseOperation op_json o = @parseOperation op_json

View File

@ -16,14 +16,11 @@ class JsonYatta
json_types = json_types_uninitialized @HB json_types = json_types_uninitialized @HB
@engine = new Engine @HB, json_types.parser @engine = new Engine @HB, json_types.parser
@connector = new Connector @engine, @HB, json_types.execution_listener, @ @connector = new Connector @engine, @HB, json_types.execution_listener, @
root_elem = @connector.getRootElement()
if not root_elem? first_word = new json_types.types.JsonType @HB.getReservedUniqueIdentifier()
first_word = new json_types.types.JsonType @HB.getNextOperationIdentifier() @HB.addOperation(first_word).execute()
@HB.addOperation(first_word)
first_word.execute()
@root_element = first_word @root_element = first_word
else
@root_element = @HB.getOperation(root_elem)
# #
# @result JsonType # @result JsonType

View File

@ -21,6 +21,18 @@ class HistoryBuffer
getUserId: ()-> getUserId: ()->
@user_id @user_id
#
# There is only one reserved unique identifier (uid), so use it wisely.
# I propose to use it in your Framework, to create something like a root element.
# An operation with this identifier is not propagated to other clients.
# This is why everybode must create the same operation with this uid.
#
getReservedUniqueIdentifier: ()->
{
creator : '_'
op_number : '_'
}
# #
# Get the operation counter that describes the current state of the document. # Get the operation counter that describes the current state of the document.
# #

View File

@ -294,7 +294,7 @@ module.exports = (HB)->
# @param {Object} uid A unique identifier. If uid is undefined, a new uid will be created. # @param {Object} uid A unique identifier. If uid is undefined, a new uid will be created.
# @param {Object} content # @param {Object} content
# #
constructor: (uid, @content="", prev, next, origin)-> constructor: (uid, @content, prev, next, origin)->
super uid, prev, next, origin super uid, prev, next, origin
# #

View File

@ -155,10 +155,11 @@ module.exports = (HB)->
super name, obj super name, obj
else else
if typeof content is 'string' if typeof content is 'string'
word = HB.addOperation(new types.Word HB.getNextOperationIdentifier(), content).execute() word = HB.addOperation(new types.Word undefined).execute()
word.insertText 0, content
super name, word super name, word
else if content.constructor is Object else if content.constructor is Object
json = HB.addOperation(new JsonType HB.getNextOperationIdentifier(), content, mutable).execute() json = HB.addOperation(new JsonType undefined, content, mutable).execute()
super name, json super name, json
else else
throw new Error "You must not set #{typeof content}-types in collaborative Json-objects!" throw new Error "You must not set #{typeof content}-types in collaborative Json-objects!"

View File

@ -20,7 +20,7 @@ module.exports = (HB)->
val: (name, content)-> val: (name, content)->
if content? if content?
if not @map[name]? if not @map[name]?
HB.addOperation(new AddName HB.getNextOperationIdentifier(), @, name).execute() HB.addOperation(new AddName undefined, @, name).execute()
@map[name].replace content @map[name].replace content
@ @
else if name? else if name?
@ -103,14 +103,14 @@ module.exports = (HB)->
@saveOperation 'beginning', beginning @saveOperation 'beginning', beginning
@saveOperation 'end', end @saveOperation 'end', end
else else
@beginning = HB.addOperation new types.Delimiter HB.getNextOperationIdentifier(), undefined, undefined @beginning = HB.addOperation new types.Delimiter undefined, undefined, undefined
@end = HB.addOperation new types.Delimiter HB.getNextOperationIdentifier(), @beginning, undefined @end = HB.addOperation new types.Delimiter undefined, @beginning, undefined
@beginning.next_cl = @end @beginning.next_cl = @end
@beginning.execute() @beginning.execute()
@end.execute() @end.execute()
super uid, prev, next, origin super uid, prev, next, origin
# Get the element previous to the delemiter at the end # Get the element previous to the delemiter at the end
getLastOperation: ()-> getLastOperation: ()->
@end.prev_cl @end.prev_cl
@ -165,7 +165,7 @@ module.exports = (HB)->
replace: (content)-> replace: (content)->
o = @getLastOperation() o = @getLastOperation()
op = new Replaceable content, @, HB.getNextOperationIdentifier(), o, o.next_cl op = new Replaceable content, @, undefined, o, o.next_cl
HB.addOperation(op).execute() HB.addOperation(op).execute()
val: ()-> val: ()->

View File

@ -78,19 +78,17 @@ module.exports = (HB)->
# #
# @param {Object} uid A unique identifier. If uid is undefined, a new uid will be created. # @param {Object} uid A unique identifier. If uid is undefined, a new uid will be created.
# @param {String} initial_content
# #
constructor: (uid, initial_content, beginning, end, prev, next, origin)-> constructor: (uid, beginning, end, prev, next, origin)->
super uid, beginning, end, prev, next, origin super uid, beginning, end, prev, next, origin
if initial_content?
@insertText 0, initial_content
# #
# Inserts a string into the word # Inserts a string into the word
# #
insertText: (position, content)-> insertText: (position, content)->
o = @getOperationByPosition position o = @getOperationByPosition position
for c in content for c in content
op = new TextInsert c, HB.getNextOperationIdentifier(), o.prev_cl, o op = new TextInsert c, undefined, o.prev_cl, o
HB.addOperation(op).execute() HB.addOperation(op).execute()
# #
@ -166,7 +164,7 @@ module.exports = (HB)->
'next': next 'next': next
'origin' : origin 'origin' : origin
} = json } = json
new Word uid, undefined, beginning, end, prev, next, origin new Word uid, beginning, end, prev, next, origin
types['TextInsert'] = TextInsert types['TextInsert'] = TextInsert
types['TextDelete'] = TextDelete types['TextDelete'] = TextDelete

View File

@ -25,6 +25,7 @@
"homepage": "https://github.com/DadaMonad/Yatta", "homepage": "https://github.com/DadaMonad/Yatta",
"dependencies": {}, "dependencies": {},
"devDependencies": { "devDependencies": {
"chai": "^1.9.1",
"coffeeify": "^0.6.0", "coffeeify": "^0.6.0",
"grunt": "^0.4.5", "grunt": "^0.4.5",
"grunt-browserify": "^2.1.3", "grunt-browserify": "^2.1.3",
@ -36,9 +37,9 @@
"grunt-contrib-watch": "^0.6.1", "grunt-contrib-watch": "^0.6.1",
"grunt-literate": "^0.2.0", "grunt-literate": "^0.2.0",
"grunt-simple-mocha": "^0.4.0", "grunt-simple-mocha": "^0.4.0",
"mocha": "^1.21.4",
"sinon": "^1.10.2", "sinon": "^1.10.2",
"sinon-chai": "^2.5.0", "sinon-chai": "^2.5.0",
"chai": "^1.9.1",
"underscore": "^1.6.0" "underscore": "^1.6.0"
} }
} }

View File

@ -1,146 +0,0 @@
chai = require('chai')
expect = chai.expect
should = chai.should()
sinon = require('sinon')
sinonChai = require('sinon-chai')
_ = require "underscore"
chai.use(sinonChai)
Yatta = require "../lib/Frameworks/JsonYatta.coffee"
Connector_uninitialized = require "../lib/Connectors/TestConnector.coffee"
###
describe "JsonYatta", ->
beforeEach (done)->
@last_user = 10
@users = []
@Connector = Connector_uninitialized @users
for i in [0..(@last_user+1)]
@users.push(new Yatta i, @Connector)
done()
it "can handle many engines, many operations, concurrently (random)", ->
number_of_test_cases_multiplier = 1
repeat_this = 100 * number_of_test_cases_multiplier
doSomething_amount = 200 * number_of_test_cases_multiplier
number_of_engines = 12 + number_of_test_cases_multiplier - 1
@time = 0
@ops = 0
users = []
generateInsertOp = (user_num)->
chars = "1234567890"
pos = _.random 0, (users[user_num].val('name').length-1)
length = 1 #_.random 0, 10
nextchar = chars[(_.random 0, (chars.length-1))]
text = ""
_(length).times ()-> text += nextchar
users[user_num].val('name').insertText pos, text
null
generateReplaceOp = (user_num)->
chars = "abcdefghijklmnopqrstuvwxyz"
length = _.random 0, 10
nextchar = chars[(_.random 0, (chars.length-1))]
text = ""
_(length).times ()-> text += nextchar
users[user_num].val('name').replaceText text
generateDeleteOp = (user_num)->
if users[user_num].val('name').val().length > 0
pos = _.random 0, (users[user_num].val('name').val().length-1)
length = 1 # _.random 0, ot.val('name').length - pos
ops1 = users[user_num].val('name').deleteText pos, length
undefined
generateRandomOp = (user_num)->
op_gen = [generateDeleteOp, generateInsertOp, generateReplaceOp]
i = _.random (op_gen.length - 1)
op = op_gen[i](user_num)
applyRandomOp = (user_num)->
user = users[user_num]
user.getConnector().flushOneRandom()
doSomething = do ()->
()->
user_num = _.random (number_of_engines-1)
choices = [applyRandomOp, generateRandomOp]
#if (users[user_num].buffer[user_num].length < maximum_ops_per_engine)
# choices = choices.concat generateRandomOp
choice = _.random (choices.length-1)
choices[choice](user_num)
console.log ""
for times in [1..repeat_this]
#console.log "repeated_this x #{times} times"
users = []
Connector = Connector_uninitialized users
users.push(new Yatta 0, Connector)
users[0].val('name',"initial")
for i in [1...number_of_engines]
users.push(new Yatta i, Connector)
found_error = false
#try
time_now = (new Date).getTime()
for i in [1..doSomething_amount]
doSomething()
for user,user_number in users
user.getConnector().flushAll()
@time += (new Date()).getTime() - time_now
number_of_created_operations = 0
for i in [0...(users.length)]
number_of_created_operations += users[i].getConnector().getOpsInExecutionOrder().length
@ops += number_of_created_operations*users.length
ops_per_msek = Math.floor(@ops/@time)
console.log "#{times}/#{repeat_this}: Every collaborator (#{users.length}) applied #{number_of_created_operations} ops in a different order." + " Over all we consumed #{@ops} operations in #{@time/1000} seconds (#{ops_per_msek} ops/msek)."
console.log users[0].val('name').val()
for i in [0...(users.length-1)]
if ((users[i].val('name').val() isnt users[i+1].val('name').val()) )# and (number_of_created_operations <= 6 or true)) or found_error
printOpsInExecutionOrder = (otnumber, otherotnumber)->
ops = users[otnumber].getConnector().getOpsInExecutionOrder()
for s in ops
console.log JSON.stringify s
console.log ""
s = "ops = ["
for o,j in ops
if j isnt 0
s += ", "
s += "op#{j}"
s += "]"
console.log s
console.log "@users[@last_user].ot.applyOps ops"
console.log "expect(@users[@last_user].ot.val('name')).to.equal(\"#{users[otherotnumber].val('name')}\")"
ops
console.log ""
console.log "Found an OT Puzzle!"
console.log "OT states:"
for u,j in users
console.log "OT#{j}: "+u.val('name')
console.log "\nOT execution order (#{i},#{i+1}):"
printOpsInExecutionOrder i, i+1
console.log ""
ops = printOpsInExecutionOrder i+1, i
console.log ""
###

View File

@ -1,152 +0,0 @@
chai = require('chai')
expect = chai.expect
should = chai.should()
sinon = require('sinon')
sinonChai = require('sinon-chai')
_ = require "underscore"
chai.use(sinonChai)
Yatta = require "../lib/Frameworks/TextYatta.coffee"
Connector_uninitialized = require "../lib/Connectors/TestConnector.coffee"
###
describe "TextYatta", ->
beforeEach (done)->
@last_user = 10
@users = []
@Connector = Connector_uninitialized @users
for i in [0..(@last_user+1)]
@users.push(new Yatta i, @Connector)
done()
it "handles inserts correctly", ->
it "can handle many engines, many operations, concurrently (random)", ->
number_of_test_cases_multiplier = 1
repeat_this = 1 * number_of_test_cases_multiplier
doSomething_amount = 500 * number_of_test_cases_multiplier
number_of_engines = 12 + number_of_test_cases_multiplier - 1
#maximum_ops_per_engine = 20 * number_of_test_cases_multiplier
@time = 0
@ops = 0
users = []
generateInsertOp = (user_num)->
chars = "1234567890"
pos = _.random 0, (users[user_num].val().length-1)
length = 1 #_.random 0, 10
nextchar = chars[(_.random 0, (chars.length-1))]
text = ""
_(length).times ()-> text += nextchar
users[user_num].insertText pos, text
null
generateReplaceOp = (user_num)->
chars = "abcdefghijklmnopqrstuvwxyz"
length = _.random 0, 10
nextchar = chars[(_.random 0, (chars.length-1))]
text = ""
_(length).times ()-> text += nextchar
users[user_num].replaceText text
generateDeleteOp = (user_num)->
if users[user_num].val().length > 0
pos = _.random 0, (users[user_num].val().length-1)
length = 1 # _.random 0, ot.val().length - pos
ops1 = users[user_num].deleteText pos, length
undefined
generateRandomOp = (user_num)->
op_gen = [generateDeleteOp, generateInsertOp, generateReplaceOp]
i = _.random (op_gen.length - 1)
op = op_gen[i](user_num)
applyRandomOp = (user_num)->
user = users[user_num]
user.getConnector().flushOneRandom()
doSomething = do ()->
()->
user_num = _.random (number_of_engines-1)
choices = [applyRandomOp, generateRandomOp]
#if (users[user_num].buffer[user_num].length < maximum_ops_per_engine)
# choices = choices.concat generateRandomOp
choice = _.random (choices.length-1)
choices[choice](user_num)
console.log ""
for times in [1..repeat_this]
#console.log "repeated_this x #{times} times"
users = []
Connector = Connector_uninitialized users
for i in [0..number_of_engines]
users.push(new Yatta i, Connector)
found_error = false
#try
time_now = (new Date).getTime()
for i in [1..doSomething_amount]
doSomething()
for user,user_number in users
user.getConnector().flushAll()
@time += (new Date()).getTime() - time_now
number_of_created_operations = 0
for i in [0...(users.length)]
number_of_created_operations += users[i].getConnector().getOpsInExecutionOrder().length
@ops += number_of_created_operations*users.length
ops_per_msek = Math.floor(@ops/@time)
console.log "#{times}/#{repeat_this}: Every collaborator (#{users.length}) applied #{number_of_created_operations} ops in a different order." + " Over all we consumed #{@ops} operations in #{@time/1000} seconds (#{ops_per_msek} ops/msek)."
console.log users[0].val()
found_inconsistency = false
for i in [0...(users.length-1)]
if ((users[i].val() isnt users[i+1].val()) )# and (number_of_created_operations <= 6 or true)) or found_error
found_inconsistency =true
printOpsInExecutionOrder = (otnumber, otherotnumber)->
ops = users[otnumber].getConnector().getOpsInExecutionOrder()
for s,j in ops
console.log "op#{j} = #{JSON.stringify s}"
console.log ""
s = "ops = ["
for o,j in ops
if j isnt 0
s += ", "
s += "op#{j}"
s += "]"
console.log s
console.log "@users[@last_user].ot.applyOps ops"
console.log "expect(@users[@last_user].val()).to.equal(\"#{users[otherotnumber].val()}\")"
ops
console.log ""
console.log "Found an OT Puzzle!"
console.log "OT states:"
for u,j in users
console.log "OT#{j}: "+u.val()
console.log "\nOT execution order (#{i},#{i+1}):"
printOpsInExecutionOrder i, i+1
console.log ""
ops = printOpsInExecutionOrder i+1, i
console.log ""
if found_inconsistency
throw new Error "dtrn"
# expect(users[i].ot.val()).to.equal(users[i+1].ot.val())
###

View File

@ -13,7 +13,7 @@ Connector_uninitialized = require "../lib/Connectors/TestConnector.coffee"
class Test class Test
constructor: ()-> constructor: ()->
@number_of_test_cases_multiplier = 1 @number_of_test_cases_multiplier = 1
@repeat_this = 1 * @number_of_test_cases_multiplier @repeat_this = 1000 * @number_of_test_cases_multiplier
@doSomething_amount = 5000 * @number_of_test_cases_multiplier @doSomething_amount = 5000 * @number_of_test_cases_multiplier
@number_of_engines = 10 + @number_of_test_cases_multiplier - 1 @number_of_engines = 10 + @number_of_test_cases_multiplier - 1
@ -21,16 +21,18 @@ class Test
@ops = 0 @ops = 0
@time_now = 0 @time_now = 0
@debug = false
@reinitialize() @reinitialize()
reinitialize: ()-> reinitialize: ()->
@users = [] @users = []
@Connector = Connector_uninitialized @users @Connector = Connector_uninitialized @users
@users.push(new Yatta 0, @Connector) for i in [0...@number_of_engines]
@users[0].val('name',"initial")
for i in [1...@number_of_engines]
@users.push(new Yatta i, @Connector) @users.push(new Yatta i, @Connector)
@users[0].val('name',"initial")
@flushAll()
getSomeUser: ()-> getSomeUser: ()->
i = _.random 0, (@users.length-1) i = _.random 0, (@users.length-1)
@ -61,7 +63,7 @@ class Test
undefined undefined
generateRandomOp: (user_num)=> generateRandomOp: (user_num)=>
op_gen = [@generateDeleteOp, @generateInsertOp, @generateReplaceOp] op_gen = [@generateDeleteOp, @generateInsertOp]#, @generateReplaceOp]
i = _.random (op_gen.length - 1) i = _.random (op_gen.length - 1)
op = op_gen[i](user_num) op = op_gen[i](user_num)
@ -92,12 +94,16 @@ class Test
ops_per_msek = Math.floor(@ops/@time) ops_per_msek = Math.floor(@ops/@time)
if test_number? if test_number?
console.log "#{test_number}/#{@repeat_this}: Every collaborator (#{@users.length}) applied #{number_of_created_operations} ops in a different order." + " Over all we consumed #{@ops} operations in #{@time/1000} seconds (#{ops_per_msek} ops/msek)." console.log "#{test_number}/#{@repeat_this}: Every collaborator (#{@users.length}) applied #{number_of_created_operations} ops in a different order." + " Over all we consumed #{@ops} operations in #{@time/1000} seconds (#{ops_per_msek} ops/msek)."
console.log @users.length
#console.log users[0].val('name').val() #console.log users[0].val('name').val()
for i in [0...(@users.length-1)] for i in [0...(@users.length-1)]
if not @debug
if (@users[i].val('name').val() isnt @users[i+1].val('name').val())
console.log "found error"
expect(@users[i].val('name').val()).to.equal(@users[i+1].val('name').val())
else
if ((@users[i].val('name').val() isnt @users[i+1].val('name').val()) )# and (number_of_created_operations <= 6 or true)) or found_error if ((@users[i].val('name').val() isnt @users[i+1].val('name').val()) )# and (number_of_created_operations <= 6 or true)) or found_error
printOpsInExecutionOrder = (otnumber, otherotnumber)=>
printOpsInExecutionOrder = (otnumber, otherotnumber)->
ops = @users[otnumber].getConnector().getOpsInExecutionOrder() ops = @users[otnumber].getConnector().getOpsInExecutionOrder()
for s in ops for s in ops
console.log JSON.stringify s console.log JSON.stringify s
@ -110,12 +116,12 @@ class Test
s += "]" s += "]"
console.log s console.log s
console.log "@users[@last_user].ot.applyOps ops" console.log "@users[@last_user].ot.applyOps ops"
console.log "expect(@users[@last_user].ot.val('name')).to.equal(\"#{users[otherotnumber].val('name')}\")" console.log "expect(@users[@last_user].ot.val('name')).to.equal(\"#{@users[otherotnumber].val('name')}\")"
ops ops
console.log "" console.log ""
console.log "Found an OT Puzzle!" console.log "Found an OT Puzzle!"
console.log "OT states:" console.log "OT states:"
for u,j in users for u,j in @users
console.log "OT#{j}: "+u.val('name') console.log "OT#{j}: "+u.val('name')
console.log "\nOT execution order (#{i},#{i+1}):" console.log "\nOT execution order (#{i},#{i+1}):"
printOpsInExecutionOrder i, i+1 printOpsInExecutionOrder i, i+1
@ -136,6 +142,7 @@ class Test
describe "JsonYatta", -> describe "JsonYatta", ->
beforeEach (done)-> beforeEach (done)->
@timeout 50000
@yTest = new Test() @yTest = new Test()
done() done()