Skip to content

Commit

Permalink
Merge pull request #3988 from chadhietala/allocating-alex
Browse files Browse the repository at this point in the history
[PERF] Don't use array methods
  • Loading branch information
fivetanley committed Dec 16, 2015
2 parents c64ce94 + 0e355c0 commit ed6679f
Show file tree
Hide file tree
Showing 9 changed files with 165 additions and 72 deletions.
24 changes: 17 additions & 7 deletions addon/-private/serializers/embedded-records-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -348,11 +348,17 @@ export default Ember.Mixin.create({
*/
_generateSerializedHasMany(snapshot, relationship) {
let hasMany = snapshot.hasMany(relationship.key);
return Ember.A(hasMany).map((embeddedSnapshot) => {
var embeddedJson = embeddedSnapshot.record.serialize({ includeId: true });
let manyArray = Ember.A(hasMany);
let ret = new Array(manyArray.length);

for (let i = 0, l = manyArray.length; i < l; i++) {
let embeddedSnapshot = manyArray[i];
let embeddedJson = embeddedSnapshot.record.serialize({ includeId: true });
this.removeEmbeddedForeignKey(snapshot, embeddedSnapshot, relationship, embeddedJson);
return embeddedJson;
});
ret[i] = embeddedJson;
}

return ret;
},

/**
Expand Down Expand Up @@ -450,20 +456,24 @@ export default Ember.Mixin.create({
*/
_extractEmbeddedHasMany(store, key, hash, relationshipMeta) {
let relationshipHash = get(hash, `data.relationships.${key}.data`);

if (!relationshipHash) {
return;
}

let hasMany = relationshipHash.map(item => {
let hasMany = new Array(relationshipHash.length);

for (let i = 0, l = relationshipHash.length; i < l; i++) {
let item = relationshipHash[i];
let { data, included } = this._normalizeEmbeddedRelationship(store, relationshipMeta, item);
hash.included = hash.included || [];
hash.included.push(data);
if (included) {
hash.included.push(...included);
}

return { id: data.id, type: data.type };
});
hasMany[i] = { id: data.id, type: data.type };
}

let relationship = { data: hasMany };
set(hash, `data.relationships.${key}`, relationship);
Expand Down
42 changes: 33 additions & 9 deletions addon/-private/serializers/json-api-serializer.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,26 @@ const JSONAPISerializer = JSONSerializer.extend({

if (Ember.typeOf(documentHash.data) === 'object') {
documentHash.data = this._normalizeResourceHelper(documentHash.data);
} else if (Ember.typeOf(documentHash.data) === 'array') {
documentHash.data = documentHash.data.map(this._normalizeResourceHelper, this);
} else if (Array.isArray(documentHash.data)) {
let ret = new Array(documentHash.data.length);

for (let i = 0, l = documentHash.data.length; i < l; i++) {
let data = documentHash.data[i];
ret[i] = this._normalizeResourceHelper(data);
}

documentHash.data = ret;
}

if (Ember.typeOf(documentHash.included) === 'array') {
documentHash.included = documentHash.included.map(this._normalizeResourceHelper, this);
if (Array.isArray(documentHash.included)) {
let ret = new Array(documentHash.included.length);

for (let i = 0, l = documentHash.included.length; i < l; i++) {
let included = documentHash.included[i];
ret[i] = this._normalizeResourceHelper(included);
}

documentHash.included = ret;
}

return documentHash;
Expand Down Expand Up @@ -215,8 +229,15 @@ const JSONAPISerializer = JSONSerializer.extend({
relationshipHash.data = this._normalizeRelationshipDataHelper(relationshipHash.data);
}

if (Ember.typeOf(relationshipHash.data) === 'array') {
relationshipHash.data = relationshipHash.data.map(this._normalizeRelationshipDataHelper, this);
if (Array.isArray(relationshipHash.data)) {
let ret = new Array(relationshipHash.data.length);

for (let i = 0, l = relationshipHash.data.length; i < l; i++) {
let data = relationshipHash.data[i];
ret[i] = this._normalizeRelationshipDataHelper(data);
}

relationshipHash.data = ret;
}

return relationshipHash;
Expand Down Expand Up @@ -456,12 +477,15 @@ const JSONAPISerializer = JSONSerializer.extend({
payloadKey = this.keyForRelationship(key, 'hasMany', 'serialize');
}

let data = hasMany.map((item) => {
return {
let data = new Array(hasMany.length);

for (let i = 0, l = hasMany.length; i < l; i++) {
let item = hasMany[i];
data[i] = {
type: this.payloadKeyFromModelName(item.modelName),
id: item.id
};
});
}

json.relationships[payloadKey] = { data };
}
Expand Down
18 changes: 14 additions & 4 deletions addon/-private/serializers/json-serializer.js
Original file line number Diff line number Diff line change
Expand Up @@ -453,13 +453,17 @@ export default Serializer.extend({
documentHash.included = included;
}
} else {
documentHash.data = payload.map((item) => {
let ret = new Array(payload.length);
for (let i = 0, l = payload.length; i < l; i++) {
let item = payload[i];
let { data, included } = this.normalize(primaryModelClass, item);
if (included) {
documentHash.included.push(...included);
}
return data;
});
ret[i] = data;
}

documentHash.data = ret;
}

return documentHash;
Expand Down Expand Up @@ -644,7 +648,13 @@ export default Serializer.extend({
data = this.extractRelationship(relationshipMeta.type, relationshipHash);
}
} else if (relationshipMeta.kind === 'hasMany') {
data = Ember.isNone(relationshipHash) ? null : relationshipHash.map((item) => this.extractRelationship(relationshipMeta.type, item));
if (!Ember.isNone(relationshipHash)) {
data = new Array(relationshipHash.length);
for (let i = 0, l = relationshipHash.length; i < l; i++) {
let item = relationshipHash[i];
data[i] = this.extractRelationship(relationshipMeta.type, item);
}
}
}
relationship = { data };
}
Expand Down
24 changes: 17 additions & 7 deletions addon/-private/system/model/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -272,14 +272,24 @@ export default Ember.ArrayProxy.extend(Ember.Evented, {
@private
*/
_findOrCreateMessages(attribute, messages) {
var errors = this.errorsFor(attribute);
let errors = this.errorsFor(attribute);
let messagesArray = makeArray(messages);
let _messages = new Array(messagesArray.length);

for (let i = 0, l = messagesArray.length; i < l; i++) {
let message = messagesArray[i];
let err = errors.findBy('message', message);
if (err) {
_messages[i] = err;
} else {
_messages[i] = {
attribute: attribute,
message: message
};
}
}

return makeArray(messages).map((message) => {
return errors.findBy('message', message) || {
attribute: attribute,
message: message
};
});
return _messages;
},

/**
Expand Down
10 changes: 6 additions & 4 deletions addon/-private/system/model/internal-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -571,11 +571,13 @@ InternalModel.prototype = {

_preloadHasMany(key, preloadValue, type) {
assert("You need to pass in an array to set a hasMany property on a record", Ember.isArray(preloadValue));
var internalModel = this;
let recordsToSet = new Array(preloadValue.length);

for (let i = 0, l = preloadValue.length; i < l; i++) {
let recordToPush = preloadValue[i];
recordsToSet[i] = this._convertStringOrNumberIntoInternalModel(recordToPush, type);
}

var recordsToSet = preloadValue.map((recordToPush) => {
return internalModel._convertStringOrNumberIntoInternalModel(recordToPush, type);
});
//We use the pathway of setting the hasMany as if it came from the adapter
//because the user told us that they know this relationships exists already
this._relationships.get(key).updateRecordsFromAdapter(recordsToSet);
Expand Down
15 changes: 9 additions & 6 deletions addon/-private/system/relationships/ext.js
Original file line number Diff line number Diff line change
Expand Up @@ -569,16 +569,19 @@ Model.reopenClass({
@param {any} binding the value to which the callback's `this` should be bound
*/
eachRelatedType(callback, binding) {
get(this, 'relatedTypes').forEach((type) => {
let relationshipTypes = get(this, 'relatedTypes');

for (let i = 0; i < relationshipTypes.length; i++) {
let type = relationshipTypes[i];
callback.call(binding, type);
});
}
},

determineRelationshipType(knownSide, store) {
var knownKey = knownSide.key;
var knownKind = knownSide.kind;
var inverse = this.inverseFor(knownKey, store);
var key, otherKind;
let knownKey = knownSide.key;
let knownKind = knownSide.kind;
let inverse = this.inverseFor(knownKey, store);
let key, otherKind;

if (!inverse) {
return knownKind === 'belongsTo' ? 'oneToNone' : 'manyToNone';
Expand Down
22 changes: 14 additions & 8 deletions addon/-private/system/relationships/state/has-many.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,15 +166,21 @@ ManyRelationship.prototype.fetchLink = function() {
};

ManyRelationship.prototype.findRecords = function() {
let manyArray = this.manyArray.toArray();
let internalModels = new Array(manyArray.length);

for (let i = 0, l = manyArray.length; i < l; i++) {
internalModels[i] = manyArray[i]._internalModel;
}

//TODO CLEANUP
return this.store.findMany(this.manyArray.toArray().map((rec) => rec._internalModel)).
then(() => {
if (!this.manyArray.get('isDestroyed')) {
//Goes away after the manyArray refactor
this.manyArray.set('isLoaded', true);
}
return this.manyArray;
});
return this.store.findMany(internalModels).then(() => {
if (!this.manyArray.get('isDestroyed')) {
//Goes away after the manyArray refactor
this.manyArray.set('isLoaded', true);
}
return this.manyArray;
});
};
ManyRelationship.prototype.notifyHasManyChanged = function() {
this.record.notifyHasManyAdded(this.key);
Expand Down
62 changes: 42 additions & 20 deletions addon/-private/system/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -579,11 +579,13 @@ Store = Service.extend({
*/
findByIds(modelName, ids) {
assert('Passing classes to store methods has been removed. Please pass a dasherized string instead of '+ Ember.inspect(modelName), typeof modelName === 'string');
var store = this;
let promises = new Array(ids.length);

for (let i = 0, l = ids.length; i < l; i++) {
promises[i] = this.findRecord(modelName, ids[i]);
}

return promiseArray(Ember.RSVP.all(ids.map((id) => {
return store.findRecord(modelName, id);
})).then(Ember.A, null, "DS: Store#findByIds of " + modelName + " complete"));
return promiseArray(Ember.RSVP.all(promises).then(Ember.A, null, "DS: Store#findByIds of " + modelName + " complete"));
},

/**
Expand All @@ -610,8 +612,17 @@ Store = Service.extend({
},

scheduleFetchMany(records) {
var internalModels = records.map((record) => record._internalModel);
return Promise.all(internalModels.map(this.scheduleFetch, this));
let internalModels = new Array(records.length);
let fetches = new Array(records.length);
for (let i = 0, l = records.length; i < l; i++) {
internalModels[i] = records[i]._internalModel;
}

for (let i = 0, l = internalModels.length; i < l; i++) {
fetches[i] = this.scheduleFetch(internalModels[i]);
}

return Ember.RSVP.Promise.all(fetches);
},

scheduleFetch(internalModel, options) {
Expand Down Expand Up @@ -842,7 +853,13 @@ Store = Service.extend({
@return {Promise} promise
*/
findMany(internalModels) {
return Promise.all(internalModels.map((internalModel) => this._findByInternalModel(internalModel)));
let finds = new Array(internalModels.length);

for (let i = 0, l = internalModels.length; i < l; i++) {
finds[i] = this._findByInternalModel(internalModels[i]);
}

return Promise.all(finds);
},


Expand Down Expand Up @@ -1099,30 +1116,29 @@ Store = Service.extend({
unloadAll(modelName) {
assert('Passing classes to store methods has been removed. Please pass a dasherized string instead of '+ Ember.inspect(modelName), !modelName || typeof modelName === 'string');
if (arguments.length === 0) {
var typeMaps = this.typeMaps;
var keys = Object.keys(typeMaps);
let typeMaps = this.typeMaps;
let keys = Object.keys(typeMaps);
let types = new Array(keys.length);

var types = keys.map(byType);
for (let i = 0, l = keys.length; i < l; i++) {
types[i] = typeMaps[keys[i]]['type'].modelName;
}

types.forEach(this.unloadAll, this);
} else {
var typeClass = this.modelFor(modelName);
var typeMap = this.typeMapFor(typeClass);
var records = typeMap.records.slice();
var record;
let typeClass = this.modelFor(modelName);
let typeMap = this.typeMapFor(typeClass);
let records = typeMap.records.slice();
let record;

for (var i = 0; i < records.length; i++) {
for (let i = 0; i < records.length; i++) {
record = records[i];
record.unloadRecord();
record.destroy(); // maybe within unloadRecord
}

typeMap.metadata = new EmptyObject();
}

function byType(entry) {
return typeMaps[entry]['type'].modelName;
}
},

/**
Expand Down Expand Up @@ -2102,7 +2118,13 @@ function deserializeRecordIds(store, key, relationship, ids) {
}

assert(`A ${relationship.parentType} record was pushed into the store with the value of ${key} being '${Ember.inspect(ids)}', but ${key} is a hasMany relationship so the value must be an array. You should probably check your data payload or serializer.`, isArray(ids));
return ids.map((id) => deserializeRecordId(store, key, relationship, id));
let _ids = new Array(ids.length);

for (let i = 0, l = ids.length; i < l; i++) {
_ids[i] = deserializeRecordId(store, key, relationship, ids[i]);
}

return _ids;
}

// Delegation to the adapter and promise management
Expand Down
Loading

0 comments on commit ed6679f

Please sign in to comment.