mirror of
https://github.com/google/blockly.git
synced 2026-01-11 10:57:07 +01:00
Merge pull request #2254 from google/connection-array
Speed up the connection DB
This commit is contained in:
@@ -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.
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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++;
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -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_;
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -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};
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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_);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -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));
|
||||
@@ -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));
|
||||
@@ -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
|
||||
@@ -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_);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user