Skip to content

Commit

Permalink
Pass store and query as a closure instead of pushing to a stack.
Browse files Browse the repository at this point in the history
  • Loading branch information
tomhuda committed May 1, 2011
1 parent 79233b6 commit 79e1c99
Showing 1 changed file with 7 additions and 82 deletions.
89 changes: 7 additions & 82 deletions frameworks/datastore/system/query.js
Expand Up @@ -1293,29 +1293,14 @@ SC.Query.mixin( /** @scope SC.Query */ {
orderStoreKeys: function(storeKeys, query, store) {
// apply the sort if there is one
if (storeKeys) {

// Set tmp variable because we can't pass variables to sort function.
// Do this instead of generating a temporary closure function for perf.
// We'll use a stack-based approach in case our sort routine ends up
// calling code that triggers a recursive invocation of orderStoreKeys.
var K = SC.Query,
tempStores = K._TMP_STORES,
tempQueries = K._TMP_QUERIES;
if (!tempStores) tempStores = K._TMP_STORES = [];
if (!tempQueries) tempQueries = K._TMP_QUERIES = [];

tempStores.push(store);
tempQueries.push(query);

var res = storeKeys.sort(SC.Query.compareStoreKeys);

K._TMP_STORES.pop();
K._TMP_QUERIES.pop();
var res = storeKeys.sort(function(a, b) {
return SC.Query.compareStoreKeys(query, store, a, b);
});
}

return storeKeys;
},

/**
Default sort method that is used when calling `containsStoreKeys()`
or `containsRecords()` on this query. Simply materializes two records
Expand All @@ -1325,71 +1310,11 @@ SC.Query.mixin( /** @scope SC.Query */ {
@param {Number} storeKey2 a store key
@returns {Number} -1 if record1 < record2, +1 if record1 > record2, 0 if equal
*/
compareStoreKeys: function(storeKey1, storeKey2) {
var K = SC.Query,
tempStores = K._TMP_STORES,
tempQueries = K._TMP_QUERIES,
store = tempStores[tempStores.length - 1],
query = tempQueries[tempQueries.length - 1],
compareFunc = query.compare,
record1 = store.materializeRecord(storeKey1),
compareStoreKeys: function(query, store, storeKey1, storeKey2) {
var record1 = store.materializeRecord(storeKey1),
record2 = store.materializeRecord(storeKey2);

// If the query implements a custom 'compare' function, then use it.
// Otherwise, we have the logic from the standard version inlined here.
if (compareFunc !== K.prototype.compare) {
return compareFunc.call(query, record1, record2);
}
else {
// THIS CODE IS THE SAME AS THE 'compare' METHOD, EXCEPT THAT 'this' HAS
// BEEN CHANGED TO 'query'.
//
// It is inlined here to avoid the extra method invocation in the
// typical case where the client does not supply a custom 'compare'
// function.

var result = 0,
propertyName, order, len, i;

// fast cases go here
if (record1 === record2) return 0;

// if called for the first time we have to build the order array
if (!query._isReady) query.parse();
if (!query._isReady) { // can't parse. guid is wrong but consistent
return SC.compare(record1.get('id'),record2.get('id'));
}

// For every property specified in orderBy until non-eql result is found.
// Or, if orderBy is a comparison function, simply invoke it with the
// records.
order = query._order;
if (SC.typeOf(order) === SC.T_FUNCTION) {
result = order.call(null, record1, record2);
}
else {
len = order ? order.length : 0;
for (i=0; result===0 && (i < len); i++) {
propertyName = order[i].propertyName;
// if query property has a registered comparison use that
if (SC.Query.comparisons[propertyName]) {
result = SC.Query.comparisons[propertyName](
record1.get(propertyName),record2.get(propertyName));

// if not use default SC.compare()
} else {
result = SC.compare(
record1.get(propertyName), record2.get(propertyName) );
}

if ((result!==0) && order[i].descending) result = (-1) * result;
}
}

// return result or compare by guid
if (result !== 0) return result ;
else return SC.compare(record1.get('id'),record2.get('id'));
}
return query.compare(record1, record2);
},

/**
Expand Down

0 comments on commit 79e1c99

Please sign in to comment.