Commit b9ed2084 authored by Tristan Cavelier's avatar Tristan Cavelier

query sort, limit, select now done in workers

parent cd5cf1e5
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */ /*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global parseStringToObject: true, emptyFunction: true, sortOn: true, limit: /*global parseStringToObject: true, emptyFunction: true, sortOn: true, limit:
true, select: true, exports, stringEscapeRegexpCharacters: true, true, select: true, exports, stringEscapeRegexpCharacters: true,
deepClone, RSVP, sequence */ deepClone, RSVP, sequence, background, jIO, metadataValueToStringArray,
sortFunction */
/** /**
* The query to use to filter a list of objects. * The query to use to filter a list of objects.
...@@ -63,6 +64,39 @@ function Query() { ...@@ -63,6 +64,39 @@ function Query() {
* second is the length. * second is the length.
*/ */
Query.prototype.exec = function (item_list, option) { Query.prototype.exec = function (item_list, option) {
if (!background.removeUnmatchedSortLimitAndSelect) {
background.removeUnmatchedSortLimitAndSelect = function (event) {
var j, task = event.data.option, array = event.data.item_list;
// remove unmatched documents
if (task.match_list) {
for (j = task.match_list.length - 1; j >= 0; j -= 1) {
if (!task.match_list[j]) {
array.splice(j, 1);
}
}
}
// sort documents
if (task.sort_on) {
sortOn(task.sort_on, array);
}
// limit documents
if (task.limit) {
limit(task.limit, array);
}
// select values
select(task.select_list || [], array);
/*global resolve */
resolve(array);
};
background.removeUnmatchedSortLimitAndSelect = jIO.util.worker(
metadataValueToStringArray.toString() +
sortFunction.toString() +
sortOn.toString() +
limit.toString() +
select.toString() +
"onmessage = " + background.removeUnmatchedSortLimitAndSelect.toString()
);
}
var i, promises = []; var i, promises = [];
if (!Array.isArray(item_list)) { if (!Array.isArray(item_list)) {
throw new TypeError("Query().exec(): Argument 1 is not of type 'array'"); throw new TypeError("Query().exec(): Argument 1 is not of type 'array'");
...@@ -84,28 +118,18 @@ Query.prototype.exec = function (item_list, option) { ...@@ -84,28 +118,18 @@ Query.prototype.exec = function (item_list, option) {
return sequence([function () { return sequence([function () {
return RSVP.all(promises); return RSVP.all(promises);
}, function (answers) { }, function (answers) {
var j; option = {
for (j = answers.length - 1; j >= 0; j -= 1) { "match_list": answers,
if (!answers[j]) { "limit": option.limit,
item_list.splice(j, 1); "sort_on": option.sort_on,
} "select_list": option.select_list
} };
if (option.sort_on) { var tmp = background.removeUnmatchedSortLimitAndSelect({
j = sortOn(option.sort_on, item_list); "item_list": item_list,
// sortOn clones the list, to avoid to get it twice, free memory "option": option
item_list = undefined; });
return j; item_list = undefined; // free memory
} return tmp;
return item_list;
}, function (list) {
item_list = list;
if (option.limit) {
return limit(option.limit, item_list);
}
}, function () {
return select(option.select_list || [], item_list);
}, function () {
return item_list;
}]); }]);
}; };
......
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */ /*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global Query, RSVP, deepClone, background, jIO */ /*global Query, RSVP, deepClone */
/** /**
* Escapes regexp special chars from a string. * Escapes regexp special chars from a string.
...@@ -173,41 +173,31 @@ function select(select_option, list, clone) { ...@@ -173,41 +173,31 @@ function select(select_option, list, clone) {
Query.select = select; Query.select = select;
/** /**
* Sort a list of items, according to keys and directions. This function acts on * Sort a list of items, according to keys and directions. If `clone` is true,
* a cloned list. * then the method will act on a cloned list.
* *
* @param {Array} sort_on_option List of couples [key, direction] * @param {Array} sort_on_option List of couples [key, direction]
* @param {Array} list The item list to sort * @param {Array} list The item list to sort
* @param {Boolean} [clone=false] If true, modifies a clone of the list
* @return {Array} The filtered list * @return {Array} The filtered list
*/ */
function sortOn(sort_on_option, list) { function sortOn(sort_on_option, list, clone) {
if (!background.sortOn) { var sort_index;
background.sortOn = function (event) {
var sort_index, option = event.data.option, array = event.data.array;
for (sort_index = option.length - 1; sort_index >= 0;
sort_index -= 1) {
array.sort(sortFunction(
option[sort_index][0],
option[sort_index][1]
));
}
/*global resolve*/
resolve(array);
};
background.sortOn = jIO.util.worker(
metadataValueToStringArray.toString() +
sortFunction.toString() +
"onmessage = " + background.sortOn.toString()
);
}
if (!Array.isArray(sort_on_option)) { if (!Array.isArray(sort_on_option)) {
throw new TypeError("jioquery.sortOn(): " + throw new TypeError("jioquery.sortOn(): " +
"Argument 1 is not of type 'array'"); "Argument 1 is not of type 'array'");
} }
return background.sortOn({ if (clone) {
"option": sort_on_option, list = deepClone(list);
"array": list }
}); for (sort_index = sort_on_option.length - 1; sort_index >= 0;
sort_index -= 1) {
list.sort(sortFunction(
sort_on_option[sort_index][0],
sort_on_option[sort_index][1]
));
}
return list;
} }
Query.sortOn = sortOn; Query.sortOn = sortOn;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment