diffusion
Advanced tools
Comparing version 5.7.3 to 5.7.4
{ | ||
"name": "diffusion", | ||
"version": "5.7.3", | ||
"version": "5.7.4", | ||
"description": "Diffusion Javascript UCI client", | ||
@@ -5,0 +5,0 @@ "keywords" : ["diffusion", "reappt", "websockets", "data"], |
@@ -29,5 +29,5 @@ var SessionImpl = require('session/session-impl'); | ||
*/ | ||
version : '5.7.3', | ||
version : '5.7.4', | ||
build : '3_dev#internal', | ||
build : '4_dev#internal', | ||
@@ -34,0 +34,0 @@ /** |
@@ -0,1 +1,11 @@ | ||
var approximateSquareRoot = require('util/math').approximateSquareRoot; | ||
/** | ||
* Controls when to give up. Larger values reduce the number of operations | ||
* that will be aborted, potentially decreasing bytes on the wire, but | ||
* increase CPU cost. The CPU cose for rejected values increases | ||
* quadratically with this factor. | ||
*/ | ||
var BAIL_OUT_FACTOR = 10; | ||
// Constant result codes | ||
@@ -74,123 +84,151 @@ var SUCCESS = 0, | ||
function diff(a, aOffset, aLength, b, bOffset, bLength, script) { | ||
checkBounds(a, aOffset, aLength); | ||
checkBounds(b, bOffset, bLength); | ||
/** | ||
* Bail-out is necessary because in the worst case the algorithm is O(N^2) | ||
* in time, where N is the total input length. The cost also depends on the | ||
* number and distribution of differences between the two values. | ||
* <p> | ||
* See the Java MyersBinaryDiff#calculateBailOutLimit implementation for more | ||
* in-depth documentation regarding the choice of strategy. | ||
*/ | ||
function calculateBailOutLimit(l1, l2, bailOutFactor) { | ||
return bailOutFactor * approximateSquareRoot(l1 + l2); | ||
} | ||
var x = 0; | ||
var y = 0; | ||
while (x < aLength && y < bLength && a[aOffset + x] === b[bOffset + y]) { | ||
++x; | ||
++y; | ||
function checkBounds(buffer, offset, length) { | ||
if (offset < 0) { | ||
throw new Error("offset " + offset + " < 0"); | ||
} | ||
var u = aLength; | ||
var v = bLength; | ||
while (u > x && v > y && a[aOffset + u - 1] === b[bOffset + v - 1]) { | ||
--u; | ||
--v; | ||
if (length < 0) { | ||
throw new Error("length " + length + " < 0"); | ||
} | ||
var r1 = script.match(aOffset, x); // Prefix | ||
if (r1 !== SUCCESS) { | ||
return r1; | ||
if (offset + length > buffer.length || offset + length < 0) { | ||
throw new Error("offset " + offset + " + " + length + " > " + buffer.length); | ||
} | ||
} | ||
var r2; | ||
function Execution(a, b, script, bailOutLimit) { | ||
var self = this; | ||
if (x === u) { | ||
r2 = script.insert(bOffset + y, v - y); | ||
} else if (y === v) { | ||
r2 = script.delete(aOffset + x, u - x); | ||
} else { | ||
r2 = middleSnake(a, aOffset + x, u - x, b, bOffset + y, v - y, script); | ||
} | ||
this.diff = function(aOffset, aLength, bOffset, bLength) { | ||
checkBounds(a, aOffset, aLength); | ||
checkBounds(b, bOffset, bLength); | ||
if (r2 !== SUCCESS) { | ||
return r2; | ||
} | ||
var x = 0; | ||
var y = 0; | ||
return script.match(aOffset + u, aLength - u); // Suffix | ||
} | ||
while (x < aLength && y < bLength && a[aOffset + x] === b[bOffset + y]) { | ||
++x; | ||
++y; | ||
} | ||
function checkBounds(buffer, offset, length) { | ||
if (offset + length > buffer.length) { | ||
throw new Error("offset " + offset + " + " + length + " > " + buffer.length); | ||
} | ||
} | ||
var u = aLength; | ||
var v = bLength; | ||
function middleSnake(a, aOffset, aLength, b, bOffset, bLength, script) { | ||
var delta = aLength - bLength; | ||
var odd = delta & 1; | ||
while (u > x && v > y && a[aOffset + u - 1] === b[bOffset + v - 1]) { | ||
--u; | ||
--v; | ||
} | ||
setF(-1, 0); | ||
setR(1, aLength); | ||
var r1 = script.match(aOffset, x); // Prefix | ||
if (r1 !== SUCCESS) { | ||
return r1; | ||
} | ||
var d = 0; | ||
var r2; | ||
while (true) { | ||
for (var k1 = -d; k1 <= d; k1 +=2) { | ||
var x1 = nextF(k1, d); | ||
var u1 = x1; | ||
if (x === u) { | ||
r2 = script.insert(bOffset + y, v - y); | ||
} else if (y === v) { | ||
r2 = script.delete(aOffset + x, u - x); | ||
} else { | ||
r2 = self.middleSnake(aOffset + x, u - x, bOffset + y, v - y); | ||
} | ||
while (u1 < aLength && u1 + k1 < bLength && a[aOffset + u1] === b[bOffset + u1 + k1]) { | ||
++u1; | ||
} | ||
if (r2 !== SUCCESS) { | ||
return r2; | ||
} | ||
setF(k1, u1); | ||
return script.match(aOffset + u, aLength - u); // Suffix | ||
}; | ||
// Short circuit if d < 2. Suppose d == 1. There's at least | ||
// one difference, so either u < n or u < m - k. The next | ||
// test guarantees k == -delta == m-n. So u < n. We've not | ||
// made any reverse steps yet, so reverse(k + delta) is n. | ||
if (odd && d > 1 && Math.abs(k1 + delta) <= d - 1 && u1 >= getR(k1 + delta)) { | ||
return recurse(a, aOffset, aLength, b, bOffset, bLength, script, x1, u1, k1); | ||
this.middleSnake = function(aOffset, aLength, bOffset, bLength) { | ||
var delta = aLength - bLength; | ||
var odd = delta & 1; | ||
setF(-1, 0); | ||
setR(1, aLength); | ||
var d = 0; | ||
while (true) { | ||
for (var k1 = -d; k1 <= d; k1 +=2) { | ||
var x1 = nextF(k1, d); | ||
var u1 = x1; | ||
while (u1 < aLength && u1 + k1 < bLength && a[aOffset + u1] === b[bOffset + u1 + k1]) { | ||
++u1; | ||
} | ||
setF(k1, u1); | ||
// Short circuit if d < 2. Suppose d == 1. There's at least | ||
// one difference, so either u < n or u < m - k. The next | ||
// test guarantees k == -delta == m-n. So u < n. We've not | ||
// made any reverse steps yet, so reverse(k + delta) is n. | ||
if (odd && d > 1 && Math.abs(k1 + delta) <= d - 1 && u1 >= getR(k1 + delta)) { | ||
return self.recurse(aOffset, aLength, bOffset, bLength, x1, u1, k1); | ||
} | ||
} | ||
} | ||
for (var k2 = -d; k2 <= d; k2 += 2) { | ||
var u2 = nextR(k2, d); | ||
var x2 = u2; | ||
for (var k2 = -d; k2 <= d; k2 += 2) { | ||
var u2 = nextR(k2, d); | ||
var x2 = u2; | ||
var kd = k2 - delta; | ||
var kd = k2 - delta; | ||
while (x2 > 0 && x2 + kd > 0 && a[aOffset + x2 - 1] === b[bOffset + x2 + kd - 1]) { | ||
--x2; | ||
while (x2 > 0 && x2 + kd > 0 && a[aOffset + x2 - 1] === b[bOffset + x2 + kd - 1]) { | ||
--x2; | ||
} | ||
setR(k2, x2); | ||
// Short circuit if d < 1. Suppose d == 0, then k == 0. | ||
// There's at least one difference, so either x > 0 or | ||
// x > delta. The next test guarantees delta == 0, so x > 0. | ||
// So x > 0. But the first character is different, so | ||
// forward(kd) == 0. | ||
if (!odd && d > 0 && Math.abs(kd) <= d && x2 <= getF(kd)) { | ||
return self.recurse(aOffset, aLength, bOffset, bLength, x2, u2, kd); | ||
} | ||
} | ||
setR(k2, x2); | ||
if (d > bailOutLimit) { | ||
return REPLACE; | ||
} | ||
// Short circuit if d < 1. Suppose d == 0, then k == 0. | ||
// There's at least one difference, so either x > 0 or | ||
// x > delta. The next test guarantees delta == 0, so x > 0. | ||
// So x > 0. But the first character is different, so | ||
// forward(kd) == 0. | ||
if (!odd && d > 0 && Math.abs(kd) <= d && x2 <= getF(kd)) { | ||
return recurse(a, aOffset, aLength, b, bOffset, bLength, script, x2, u2, kd); | ||
++d; | ||
if (exceedsStorage(d)) { | ||
return REPLACE; | ||
} | ||
} | ||
}; | ||
++d; | ||
this.recurse = function(aOffset, aLength, bOffset, bLength, x, u, k) { | ||
var r1 = self.diff(aOffset, x, bOffset, x + k); | ||
if (exceedsStorage(d)) { | ||
return REPLACE; | ||
if (r1 !== SUCCESS) { | ||
return r1; | ||
} | ||
} | ||
} | ||
function recurse(a, aOffset, aLength, b, bOffset, bLength, script, x, u, k) { | ||
var r1 = diff(a, aOffset, x, b, bOffset, x + k, script); | ||
var r2 = script.match(aOffset + x, u - x); | ||
if (r1 !== SUCCESS) { | ||
return r1; | ||
} | ||
if (r2 !== SUCCESS) { | ||
return r2; | ||
} | ||
var r2 = script.match(aOffset + x, u - x); | ||
if (r2 !== SUCCESS) { | ||
return r2; | ||
} | ||
return diff(a, aOffset + u, aLength - u, b, bOffset + u + k, bLength - u - k, script); | ||
return self.diff(aOffset + u, aLength - u, bOffset + u + k, bLength - u - k); | ||
}; | ||
} | ||
@@ -289,7 +327,14 @@ | ||
* @param {Script} editScript - The edit script | ||
* @param {Number} [bailOutFactor] - Optional bail-out limit factor | ||
*/ | ||
module.exports = function binaryDiff(a, aOffset, aLength, b, bOffset, bLength, editScript) { | ||
module.exports = function binaryDiff(a, aOffset, aLength, b, bOffset, bLength, editScript, bailOutFactor) { | ||
if (bailOutFactor === undefined) { | ||
bailOutFactor = BAIL_OUT_FACTOR; | ||
} | ||
var script = coalesce(editScript, aOffset, bOffset); | ||
var result = diff(a, aOffset, aLength, b, bOffset, bLength, script); | ||
var execution = new Execution(a, b, script, calculateBailOutLimit(aLength, bLength, bailOutFactor)); | ||
var result = execution.diff(aOffset, aLength, bOffset, bLength); | ||
if (result !== SUCCESS) { | ||
@@ -296,0 +341,0 @@ return result; |
@@ -19,6 +19,4 @@ var implements = require('util/interface').implements; | ||
return self.readValue(val); | ||
} else if (val instanceof Object && val.constructor === Object) { | ||
} else { | ||
return self.readValue(encoder.encode(val).flush()); | ||
} else { | ||
throw new Error("Unable to read JSON value from: " + val); | ||
} | ||
@@ -25,0 +23,0 @@ } |
@@ -19,28 +19,2 @@ var SubscriptionImpl = require('features/topics/subscription'); | ||
// If we have a provided callback, we can automatically register the stream | ||
if (callback) { | ||
subscription.on('update', callback); | ||
if (fallback) { | ||
registry.addFallback(self); | ||
} else { | ||
registry.add(selector, self); | ||
} | ||
} else { | ||
// Monkey-patch so that we will only register this stream if it is subsequently used. | ||
subscription.on = function(event, fn) { | ||
if (pending) { | ||
if (fallback) { | ||
registry.addFallback(self); | ||
} else { | ||
registry.add(selector, self); | ||
} | ||
pending = false; | ||
} | ||
return stream.on.call(subscription, event, fn); | ||
}; | ||
} | ||
stream.on('close', function() { | ||
@@ -76,2 +50,28 @@ registry.remove(self); | ||
}; | ||
// If we have a provided callback, we can automatically register the stream | ||
if (callback) { | ||
subscription.on('update', callback); | ||
if (fallback) { | ||
registry.addFallback(self); | ||
} else { | ||
registry.add(selector, self); | ||
} | ||
} else { | ||
// Monkey-patch so that we will only register this stream if it is subsequently used. | ||
subscription.on = function(event, fn) { | ||
if (pending) { | ||
if (fallback) { | ||
registry.addFallback(self); | ||
} else { | ||
registry.add(selector, self); | ||
} | ||
pending = false; | ||
} | ||
return stream.on.call(subscription, event, fn); | ||
}; | ||
} | ||
}; |
@@ -21,27 +21,2 @@ var TypedSubscriptionImpl = require('features/topics/typed-subscription'); | ||
if (callback) { | ||
subscription.on('value', callback); | ||
if (fallback) { | ||
registry.addFallback(self); | ||
} else { | ||
registry.add(selector, self); | ||
} | ||
} else { | ||
// Monkey-patch so that we will only register this stream if it is subsequently used | ||
subscription.on = function(event, fn) { | ||
if (pending) { | ||
if (fallback) { | ||
registry.addFallback(self); | ||
} else { | ||
registry.add(selector, self); | ||
} | ||
pending = false; | ||
} | ||
return stream.on.call(subscription, event, fn); | ||
}; | ||
} | ||
stream.on('close', function() { | ||
@@ -81,2 +56,27 @@ registry.remove(self); | ||
}; | ||
if (callback) { | ||
subscription.on('value', callback); | ||
if (fallback) { | ||
registry.addFallback(self); | ||
} else { | ||
registry.add(selector, self); | ||
} | ||
} else { | ||
// Monkey-patch so that we will only register this stream if it is subsequently used | ||
subscription.on = function(event, fn) { | ||
if (pending) { | ||
if (fallback) { | ||
registry.addFallback(self); | ||
} else { | ||
registry.add(selector, self); | ||
} | ||
pending = false; | ||
} | ||
return stream.on.call(subscription, event, fn); | ||
}; | ||
} | ||
}; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
480057
256
13339