Browse Source

Replaced for-in loops in DataSet.js and DataView.js with Object-key iteration of cached length for greater computational performance.

webworkersNetwork
Philippe Mimms 9 years ago
parent
commit
627d708efb
2 changed files with 151 additions and 138 deletions
  1. +139
    -121
      lib/DataSet.js
  2. +12
    -17
      lib/DataView.js

+ 139
- 121
lib/DataSet.js View File

@ -60,15 +60,15 @@ function DataSet (data, options) {
// all variants of a Date are internally stored as Date, so we can convert // all variants of a Date are internally stored as Date, so we can convert
// from everything to everything (also from ISODate to Number for example) // from everything to everything (also from ISODate to Number for example)
if (this._options.type) { if (this._options.type) {
for (var field in this._options.type) {
if (this._options.type.hasOwnProperty(field)) {
var value = this._options.type[field];
if (value == 'Date' || value == 'ISODate' || value == 'ASPDate') {
this._type[field] = 'Date';
}
else {
this._type[field] = value;
}
var fields = Object.keys(this._options.type);
for (var i = 0, len = fields.length; i < len; i++) {
var field = fields[i];
var value = this._options.type[field];
if (value == 'Date' || value == 'ISODate' || value == 'ASPDate') {
this._type[field] = 'Date';
}
else {
this._type[field] = value;
} }
} }
} }
@ -184,7 +184,7 @@ DataSet.prototype._trigger = function (event, params, senderId) {
subscribers = subscribers.concat(this._subscribers['*']); subscribers = subscribers.concat(this._subscribers['*']);
} }
for (var i = 0; i < subscribers.length; i++) {
for (var i = 0, len = subscribers.length; i < len; i++) {
var subscriber = subscribers[i]; var subscriber = subscribers[i];
if (subscriber.callback) { if (subscriber.callback) {
subscriber.callback(event, params, senderId || null); subscriber.callback(event, params, senderId || null);
@ -340,7 +340,7 @@ DataSet.prototype.get = function (args) {
// build options // build options
var type = options && options.type || this._options.type; var type = options && options.type || this._options.type;
var filter = options && options.filter; var filter = options && options.filter;
var items = [], item, itemId, i, len;
var items = [], item, itemIds, itemId, i, len;
// convert items // convert items
if (id != undefined) { if (id != undefined) {
@ -361,12 +361,12 @@ DataSet.prototype.get = function (args) {
} }
else { else {
// return all items // return all items
for (itemId in this._data) {
if (this._data.hasOwnProperty(itemId)) {
item = me._getItem(itemId, type);
if (!filter || filter(item)) {
items.push(item);
}
itemIds = Object.keys(this._data);
for (i = 0, len = itemIds.length; i < len; i++) {
itemId = itemIds[i];
item = me._getItem(itemId, type);
if (!filter || filter(item)) {
items.push(item);
} }
} }
} }
@ -391,9 +391,11 @@ DataSet.prototype.get = function (args) {
// return the results // return the results
if (returnType == 'Object') { if (returnType == 'Object') {
var result = {};
for (i = 0; i < items.length; i++) {
result[items[i].id] = items[i];
var result = {},
resultant;
for (i = 0, len = items.length; i < len; i++) {
resultant = items[i];
result[resultant.id] = resultant;
} }
return result; return result;
} }
@ -422,6 +424,7 @@ DataSet.prototype.getIds = function (options) {
filter = options && options.filter, filter = options && options.filter,
order = options && options.order, order = options && options.order,
type = options && options.type || this._options.type, type = options && options.type || this._options.type,
itemIds = Object.keys(data),
i, i,
len, len,
id, id,
@ -434,29 +437,27 @@ DataSet.prototype.getIds = function (options) {
if (order) { if (order) {
// create ordered list // create ordered list
items = []; items = [];
for (id in data) {
if (data.hasOwnProperty(id)) {
item = this._getItem(id, type);
if (filter(item)) {
items.push(item);
}
for (i = 0, len = itemIds.length; i < len; i++) {
id = itemIds[i];
item = this._getItem(id, type);
if (filter(item)) {
items.push(item);
} }
} }
this._sort(items, order); this._sort(items, order);
for (i = 0, len = items.length; i < len; i++) { for (i = 0, len = items.length; i < len; i++) {
ids[i] = items[i][this._fieldId];
ids.push(items[i][this._fieldId]);
} }
} }
else { else {
// create unordered list // create unordered list
for (id in data) {
if (data.hasOwnProperty(id)) {
item = this._getItem(id, type);
if (filter(item)) {
ids.push(item[this._fieldId]);
}
for (i = 0, len = itemIds.length; i < len; i++) {
id = itemIds[i];
item = this._getItem(id, type);
if (filter(item)) {
ids.push(item[this._fieldId]);
} }
} }
} }
@ -466,25 +467,23 @@ DataSet.prototype.getIds = function (options) {
if (order) { if (order) {
// create an ordered list // create an ordered list
items = []; items = [];
for (id in data) {
if (data.hasOwnProperty(id)) {
items.push(data[id]);
}
for (i = 0, len = itemIds.length; i < len; i++) {
id = itemIds[i];
items.push(data[id]);
} }
this._sort(items, order); this._sort(items, order);
for (i = 0, len = items.length; i < len; i++) { for (i = 0, len = items.length; i < len; i++) {
ids[i] = items[i][this._fieldId];
ids.push(items[i][this._fieldId]);
} }
} }
else { else {
// create unordered list // create unordered list
for (id in data) {
if (data.hasOwnProperty(id)) {
item = data[id];
ids.push(item[this._fieldId]);
}
for (i = 0, len = itemIds.length; i < len; i++) {
id = itemIds[i];
item = data[id];
ids.push(item[this._fieldId]);
} }
} }
} }
@ -514,6 +513,9 @@ DataSet.prototype.forEach = function (callback, options) {
var filter = options && options.filter, var filter = options && options.filter,
type = options && options.type || this._options.type, type = options && options.type || this._options.type,
data = this._data, data = this._data,
itemIds = Object.key(data),
i,
len,
item, item,
id; id;
@ -521,7 +523,7 @@ DataSet.prototype.forEach = function (callback, options) {
// execute forEach on ordered list // execute forEach on ordered list
var items = this.get(options); var items = this.get(options);
for (var i = 0, len = items.length; i < len; i++) {
for (i = 0, len = items.length; i < len; i++) {
item = items[i]; item = items[i];
id = item[this._fieldId]; id = item[this._fieldId];
callback(item, id); callback(item, id);
@ -529,12 +531,11 @@ DataSet.prototype.forEach = function (callback, options) {
} }
else { else {
// unordered // unordered
for (id in data) {
if (data.hasOwnProperty(id)) {
item = this._getItem(id, type);
if (!filter || filter(item)) {
callback(item, id);
}
for (i = 0, len = itemIds.length; i < len; i++) {
id = itemIds[i];
item = this._getItem(id, type);
if (!filter || filter(item)) {
callback(item, id);
} }
} }
} }
@ -556,15 +557,18 @@ DataSet.prototype.map = function (callback, options) {
type = options && options.type || this._options.type, type = options && options.type || this._options.type,
mappedItems = [], mappedItems = [],
data = this._data, data = this._data,
itemIds = Object.keys(data),
i,
len,
id,
item; item;
// convert and filter items // convert and filter items
for (var id in data) {
if (data.hasOwnProperty(id)) {
item = this._getItem(id, type);
if (!filter || filter(item)) {
mappedItems.push(callback(item, id));
}
for (i = 0, len = itemIds.length; i < len; i++) {
id = itemIds[i];
item = this._getItem(id, type);
if (!filter || filter(item)) {
mappedItems.push(callback(item, id));
} }
} }
@ -588,17 +592,23 @@ DataSet.prototype._filterFields = function (item, fields) {
return item; return item;
} }
var filteredItem = {};
var filteredItem = {},
itemFields = Object.keys(item),
len = itemFields.length,
i,
field;
if(Array.isArray(fields)){ if(Array.isArray(fields)){
for (var field in item) {
if (item.hasOwnProperty(field) && (fields.indexOf(field) != -1)) {
for (i = 0; i < len; i++) {
field = itemFields[i];
if (fields.indexOf(field) != -1) {
filteredItem[field] = item[field]; filteredItem[field] = item[field];
} }
} }
}else{ }else{
for (var field in item) {
if (item.hasOwnProperty(field) && fields.hasOwnProperty(field)) {
for (i = 0; i < len; i++) {
field = itemFields[i];
if (fields.hasOwnProperty(field)) {
filteredItem[fields[field]] = item[field]; filteredItem[fields[field]] = item[field];
} }
} }
@ -715,17 +725,19 @@ DataSet.prototype.clear = function (senderId) {
*/ */
DataSet.prototype.max = function (field) { DataSet.prototype.max = function (field) {
var data = this._data, var data = this._data,
itemIds = Object.keys(data),
max = null, max = null,
maxField = null;
for (var id in data) {
if (data.hasOwnProperty(id)) {
var item = data[id];
var itemField = item[field];
if (itemField != null && (!max || itemField > maxField)) {
max = item;
maxField = itemField;
}
maxField = null,
i,
len;
for (i = 0, len = itemIds.length; i < len; i++) {
var id = itemIds[i];
var item = data[id];
var itemField = item[field];
if (itemField != null && (!max || itemField > maxField)) {
max = item;
maxField = itemField;
} }
} }
@ -739,17 +751,19 @@ DataSet.prototype.max = function (field) {
*/ */
DataSet.prototype.min = function (field) { DataSet.prototype.min = function (field) {
var data = this._data, var data = this._data,
itemIds = Object.keys(data),
min = null, min = null,
minField = null;
for (var id in data) {
if (data.hasOwnProperty(id)) {
var item = data[id];
var itemField = item[field];
if (itemField != null && (!min || itemField < minField)) {
min = item;
minField = itemField;
}
minField = null,
i,
len;
for (i = 0, len = itemIds.length; i < len; i++) {
var id = itemIds[i];
var item = data[id];
var itemField = item[field];
if (itemField != null && (!min || itemField < minField)) {
min = item;
minField = itemField;
} }
} }
@ -765,31 +779,33 @@ DataSet.prototype.min = function (field) {
*/ */
DataSet.prototype.distinct = function (field) { DataSet.prototype.distinct = function (field) {
var data = this._data; var data = this._data;
var itemIds = Object.keys(data);
var values = []; var values = [];
var fieldType = this._options.type && this._options.type[field] || null; var fieldType = this._options.type && this._options.type[field] || null;
var count = 0; var count = 0;
var i;
for (var prop in data) {
if (data.hasOwnProperty(prop)) {
var item = data[prop];
var value = item[field];
var exists = false;
for (i = 0; i < count; i++) {
if (values[i] == value) {
exists = true;
break;
}
}
if (!exists && (value !== undefined)) {
values[count] = value;
count++;
var i,
j,
len;
for (i = 0, len = itemIds.length; i < len; i++) {
var id = itemIds[i];
var item = data[id];
var value = item[field];
var exists = false;
for (j = 0; j < count; j++) {
if (values[j] == value) {
exists = true;
break;
} }
} }
if (!exists && (value !== undefined)) {
values[count] = value;
count++;
}
} }
if (fieldType) { if (fieldType) {
for (i = 0; i < values.length; i++) {
for (i = 0, len = values.length; i < len; i++) {
values[i] = util.convert(values[i], fieldType); values[i] = util.convert(values[i], fieldType);
} }
} }
@ -819,12 +835,14 @@ DataSet.prototype._addItem = function (item) {
item[this._fieldId] = id; item[this._fieldId] = id;
} }
var d = {};
for (var field in item) {
if (item.hasOwnProperty(field)) {
var fieldType = this._type[field]; // type may be undefined
d[field] = util.convert(item[field], fieldType);
}
var d = {},
fields = Object.keys(item),
i,
len;
for (i = 0, len = fields.length; i < len; i++) {
var field = fields[i];
var fieldType = this._type[field]; // type may be undefined
d[field] = util.convert(item[field], fieldType);
} }
this._data[id] = d; this._data[id] = d;
this.length++; this.length++;
@ -840,7 +858,7 @@ DataSet.prototype._addItem = function (item) {
* @private * @private
*/ */
DataSet.prototype._getItem = function (id, types) { DataSet.prototype._getItem = function (id, types) {
var field, value;
var field, value, i, len;
// get the item from the dataset // get the item from the dataset
var raw = this._data[id]; var raw = this._data[id];
@ -849,22 +867,22 @@ DataSet.prototype._getItem = function (id, types) {
} }
// convert the items field types // convert the items field types
var converted = {};
var converted = {},
fields = Object.keys(raw);
if (types) { if (types) {
for (field in raw) {
if (raw.hasOwnProperty(field)) {
value = raw[field];
converted[field] = util.convert(value, types[field]);
}
for (i = 0, len = fields.length; i < len; i++) {
field = fields[i];
value = raw[field];
converted[field] = util.convert(value, types[field]);
} }
} }
else { else {
// no field types specified, no converting needed // no field types specified, no converting needed
for (field in raw) {
if (raw.hasOwnProperty(field)) {
value = raw[field];
converted[field] = value;
}
for (i = 0, len = fields.length; i < len; i++) {
field = fields[i];
value = raw[field];
converted[field] = value;
} }
} }
return converted; return converted;
@ -890,11 +908,11 @@ DataSet.prototype._updateItem = function (item) {
} }
// merge with current item // merge with current item
for (var field in item) {
if (item.hasOwnProperty(field)) {
var fieldType = this._type[field]; // type may be undefined
d[field] = util.convert(item[field], fieldType);
}
var fields = Object.keys(item);
for (var i = 0, len = fields.length; i < len; i++) {
var field = fields[i];
var fieldType = this._type[field]; // type may be undefined
d[field] = util.convert(item[field], fieldType);
} }
return id; return id;

+ 12
- 17
lib/DataView.js View File

@ -35,7 +35,7 @@ function DataView (data, options) {
* @param {DataSet | DataView} data * @param {DataSet | DataView} data
*/ */
DataView.prototype.setData = function (data) { DataView.prototype.setData = function (data) {
var ids, i, len;
var ids, id, i, len;
if (this._data) { if (this._data) {
// unsubscribe from current dataset // unsubscribe from current dataset
@ -44,12 +44,7 @@ DataView.prototype.setData = function (data) {
} }
// trigger a remove of all items in memory // trigger a remove of all items in memory
ids = [];
for (var id in this._ids) {
if (this._ids.hasOwnProperty(id)) {
ids.push(id);
}
}
ids = Object.keys(this._ids);
this._ids = {}; this._ids = {};
this.length = 0; this.length = 0;
this._trigger('remove', {items: ids}); this._trigger('remove', {items: ids});
@ -84,34 +79,34 @@ DataView.prototype.setData = function (data) {
* containing a variable parameter. * containing a variable parameter.
*/ */
DataView.prototype.refresh = function () { DataView.prototype.refresh = function () {
var id;
var id, i, len;
var ids = this._data.getIds({filter: this._options && this._options.filter}); var ids = this._data.getIds({filter: this._options && this._options.filter});
var oldIds = Object.keys(this._ids);
var newIds = {}; var newIds = {};
var added = []; var added = [];
var removed = []; var removed = [];
// check for additions // check for additions
for (var i = 0; i < ids.length; i++) {
for (i = 0, len = ids.length; i < len; i++) {
id = ids[i]; id = ids[i];
newIds[id] = true; newIds[id] = true;
if (!this._ids[id]) { if (!this._ids[id]) {
added.push(id); added.push(id);
this._ids[id] = true; this._ids[id] = true;
this.length++;
} }
} }
// check for removals // check for removals
for (id in this._ids) {
if (this._ids.hasOwnProperty(id)) {
if (!newIds[id]) {
removed.push(id);
delete this._ids[id];
this.length--;
}
for (i = 0, len = oldIds.length; i < len; i++) {
id = oldIds[i];
if (!newIds[id]) {
removed.push(id);
delete this._ids[id];
} }
} }
this.length += added.length - removed.length;
// trigger events // trigger events
if (added.length) { if (added.length) {
this._trigger('add', {items: added}); this._trigger('add', {items: added});

Loading…
Cancel
Save