Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Speed up the connection DB #2254

Merged
merged 2 commits into from Feb 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
52 changes: 26 additions & 26 deletions core/connection_db.js
Expand Up @@ -36,15 +36,14 @@ goog.require('Blockly.Connection');
* @constructor
*/
Blockly.ConnectionDB = function() {
/**
* Array of connections sorted by y coordinate.
* @type {!Array.<!Blockly.Connection>}
* @private
*/
this.connections_ = [];
};

Blockly.ConnectionDB.prototype = new Array();
/**
* Don't inherit the constructor from Array.
* @type {!Function}
*/
Blockly.ConnectionDB.constructor = Blockly.ConnectionDB;

/**
* Add a connection to the database. Must not already exist in DB.
* @param {!Blockly.Connection} connection The connection to be added.
Expand All @@ -58,7 +57,7 @@ Blockly.ConnectionDB.prototype.addConnection = function(connection) {
return;
}
var position = this.findPositionForConnection_(connection);
this.splice(position, 0, connection);
this.connections_.splice(position, 0, connection);
connection.inDB_ = true;
};

Expand All @@ -71,12 +70,12 @@ Blockly.ConnectionDB.prototype.addConnection = function(connection) {
* not found.
*/
Blockly.ConnectionDB.prototype.findConnection = function(conn) {
if (!this.length) {
if (!this.connections_.length) {
return -1;
}

var bestGuess = this.findPositionForConnection_(conn);
if (bestGuess >= this.length) {
if (bestGuess >= this.connections_.length) {
// Not in list
return -1;
}
Expand All @@ -85,15 +84,16 @@ Blockly.ConnectionDB.prototype.findConnection = function(conn) {
// Walk forward and back on the y axis looking for the connection.
var pointerMin = bestGuess;
var pointerMax = bestGuess;
while (pointerMin >= 0 && this[pointerMin].y_ == yPos) {
if (this[pointerMin] == conn) {
while (pointerMin >= 0 && this.connections_[pointerMin].y_ == yPos) {
if (this.connections_[pointerMin] == conn) {
return pointerMin;
}
pointerMin--;
}

while (pointerMax < this.length && this[pointerMax].y_ == yPos) {
if (this[pointerMax] == conn) {
while (pointerMax < this.connections_.length &&
this.connections_[pointerMax].y_ == yPos) {
if (this.connections_[pointerMax] == conn) {
return pointerMax;
}
pointerMax++;
Expand All @@ -111,16 +111,16 @@ Blockly.ConnectionDB.prototype.findConnection = function(conn) {
*/
Blockly.ConnectionDB.prototype.findPositionForConnection_ = function(
connection) {
if (!this.length) {
if (!this.connections_.length) {
return 0;
}
var pointerMin = 0;
var pointerMax = this.length;
var pointerMax = this.connections_.length;
while (pointerMin < pointerMax) {
var pointerMid = Math.floor((pointerMin + pointerMax) / 2);
if (this[pointerMid].y_ < connection.y_) {
if (this.connections_[pointerMid].y_ < connection.y_) {
pointerMin = pointerMid + 1;
} else if (this[pointerMid].y_ > connection.y_) {
} else if (this.connections_[pointerMid].y_ > connection.y_) {
pointerMax = pointerMid;
} else {
pointerMin = pointerMid;
Expand All @@ -144,7 +144,7 @@ Blockly.ConnectionDB.prototype.removeConnection_ = function(connection) {
throw Error('Unable to find connection in connectionDB.');
}
connection.inDB_ = false;
this.splice(removalIndex, 1);
this.connections_.splice(removalIndex, 1);
};

/**
Expand All @@ -156,7 +156,7 @@ Blockly.ConnectionDB.prototype.removeConnection_ = function(connection) {
* @return {!Array.<Blockly.Connection>} List of connections.
*/
Blockly.ConnectionDB.prototype.getNeighbours = function(connection, maxRadius) {
var db = this;
var db = this.connections_;
var currentX = connection.x_;
var currentY = connection.y_;

Expand Down Expand Up @@ -218,7 +218,7 @@ Blockly.ConnectionDB.prototype.getNeighbours = function(connection, maxRadius) {
* @private
*/
Blockly.ConnectionDB.prototype.isInYRange_ = function(index, baseY, maxRadius) {
return (Math.abs(this[index].y_ - baseY) <= maxRadius);
return (Math.abs(this.connections_[index].y_ - baseY) <= maxRadius);
};

/**
Expand All @@ -235,7 +235,7 @@ Blockly.ConnectionDB.prototype.isInYRange_ = function(index, baseY, maxRadius) {
Blockly.ConnectionDB.prototype.searchForClosest = function(conn, maxRadius,
dxy) {
// Don't bother.
if (!this.length) {
if (!this.connections_.length) {
return {connection: null, radius: maxRadius};
}

Expand All @@ -258,7 +258,7 @@ Blockly.ConnectionDB.prototype.searchForClosest = function(conn, maxRadius,
// Walk forward and back on the y axis looking for the closest x,y point.
var pointerMin = closestIndex - 1;
while (pointerMin >= 0 && this.isInYRange_(pointerMin, conn.y_, maxRadius)) {
temp = this[pointerMin];
temp = this.connections_[pointerMin];
if (conn.isConnectionAllowed(temp, bestRadius)) {
bestConnection = temp;
bestRadius = temp.distanceFrom(conn);
Expand All @@ -267,9 +267,9 @@ Blockly.ConnectionDB.prototype.searchForClosest = function(conn, maxRadius,
}

var pointerMax = closestIndex;
while (pointerMax < this.length && this.isInYRange_(pointerMax, conn.y_,
maxRadius)) {
temp = this[pointerMax];
while (pointerMax < this.connections_.length &&
this.isInYRange_(pointerMax, conn.y_, maxRadius)) {
temp = this.connections_[pointerMax];
if (conn.isConnectionAllowed(temp, bestRadius)) {
bestConnection = temp;
bestRadius = temp.distanceFrom(conn);
Expand Down
24 changes: 12 additions & 12 deletions tests/jsunit/connection_db_test.js
Expand Up @@ -20,10 +20,10 @@
'use strict';

function verify_DB_(msg, expected, db) {
var equal = (expected.length == db.length);
var equal = (expected.length == db.connections_.length);
if (equal) {
for (var i = 0; i < expected.length; i++) {
if (expected[i] != db[i]) {
if (expected[i] != db.connections_[i]) {
equal = false;
break;
}
Expand All @@ -32,7 +32,7 @@ function verify_DB_(msg, expected, db) {
if (equal) {
assertTrue(msg, true);
} else {
assertEquals(msg, expected, db);
assertEquals(msg, expected, db.connections_);
}
}

Expand Down Expand Up @@ -122,21 +122,21 @@ function test_DB_getNeighbours() {
var result = helper_getNeighbours(db, 0, 0, 4);
assertEquals(5, result.length);
for (i = 0; i < result.length; i++) {
assertNotEquals(result.indexOf(db[i]), -1); // contains
assertNotEquals(result.indexOf(db.connections_[i]), -1); // contains
}

// Test block belongs at middle.
result = helper_getNeighbours(db, 0, 4, 2);
assertEquals(5, result.length);
for (i = 0; i < result.length; i++) {
assertNotEquals(result.indexOf(db[i + 2]), -1); // contains
assertNotEquals(result.indexOf(db.connections_[i + 2]), -1); // contains
}

// Test block belongs at end.
result = helper_getNeighbours(db, 0, 9, 4);
assertEquals(5, result.length);
for (i = 0; i < result.length; i++) {
assertNotEquals(result.indexOf(db[i + 5]), -1); // contains
assertNotEquals(result.indexOf(db.connections_[i + 5]), -1); // contains
}

// Test block has no neighbours due to being out of range in the x direction.
Expand Down Expand Up @@ -165,7 +165,7 @@ function test_DB_findPositionForConnection() {
db.addConnection(helper_createConnection(0, 5, Blockly.PREVIOUS_STATEMENT,
null, true));

assertEquals(5, db.length);
assertEquals(5, db.connections_.length);
var conn = helper_createConnection(0, 3, Blockly.PREVIOUS_STATEMENT, null,
true);
assertEquals(3, db.findPositionForConnection_(conn));
Expand All @@ -183,7 +183,7 @@ function test_DB_findConnection() {
var conn = helper_createConnection(3, 3, Blockly.PREVIOUS_STATEMENT, null,
true);
db.addConnection(conn);
assertEquals(conn, db[db.findConnection(conn)]);
assertEquals(conn, db.connections_[db.findConnection(conn)]);

conn = helper_createConnection(3, 3, Blockly.PREVIOUS_STATEMENT, null, true);
assertEquals(-1, db.findConnection(conn));
Expand All @@ -197,7 +197,7 @@ function test_DB_ordering() {
}

for (i = 0; i < 10; i++) {
assertEquals(i, db[i].y_);
assertEquals(i, db.connections_[i].y_);
}

// quasi-random
Expand All @@ -221,7 +221,7 @@ function test_DB_ordering() {
}

for (i = 1; i < xCoords.length; i++) {
assertTrue(db[i].y_ >= db[i - 1].y_);
assertTrue(db.connections_[i].y_ >= db.connections_[i - 1].y_);
}
}

Expand All @@ -246,13 +246,13 @@ function test_SearchForClosest() {
}

// Should be at 0, 9.
var last = db[db.length - 1];
var last = db.connections_[db.connections_.length - 1];
// Correct connection is last in db; many connections in radius.
assertEquals(last, helper_searchDB(db, 0, 10, 15, sharedWorkspace));
// Nothing nearby.
assertEquals(null, helper_searchDB(db, 100, 100, 3, sharedWorkspace));
// First in db, exact match.
assertEquals(db[0], helper_searchDB(db, 0, 0, 0, sharedWorkspace));
assertEquals(db.connections_[0], helper_searchDB(db, 0, 0, 0, sharedWorkspace));

tempConn = helper_createConnection(6, 6, Blockly.PREVIOUS_STATEMENT,
sharedWorkspace, true);
Expand Down