Skip to content

Commit

Permalink
Optimize the update of a has-many relationship. (#7090)
Browse files Browse the repository at this point in the history
  • Loading branch information
pieter-v authored Jul 2, 2020
1 parent da70e6c commit 5b2dfaa
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 34 deletions.
22 changes: 22 additions & 0 deletions packages/record-data/addon/-private/ordered-set.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { assert } from '@ember/debug';
import { guidFor } from '@ember/object/internals';
import EmberOrderedSet from '@ember/ordered-set';

Expand Down Expand Up @@ -27,4 +28,25 @@ export default class EmberDataOrderedSet<T> extends EmberOrderedSet<T> {

return this;
}

deleteWithIndex(obj: T | null, idx?: number): boolean {
let guid = guidFor(obj);
let presenceSet = this.presenceSet;
let list = this.list;

if (presenceSet[guid] === true) {
delete presenceSet[guid];

assert('object is not present at specified index', idx === undefined || list[idx] === obj);

let index = idx !== undefined ? idx : list.indexOf(obj);
if (index > -1) {
list.splice(index, 1);
}
this.size = list.length;
return true;
} else {
return false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -154,14 +154,14 @@ export default class BelongsToRelationship extends Relationship {
storeWrapper.notifyBelongsToChange(recordData.modelName, recordData.id, recordData.clientId, this.key);
}

removeCanonicalRecordDataFromOwn(recordData: RelationshipRecordData) {
removeCanonicalRecordDataFromOwn(recordData: RelationshipRecordData, idx?: number) {
if (!this.canonicalMembers.has(recordData)) {
return;
}
this.canonicalState = null;
this.setHasAnyRelationshipData(true);
this.setRelationshipIsEmpty(true);
super.removeCanonicalRecordDataFromOwn(recordData);
super.removeCanonicalRecordDataFromOwn(recordData, idx);
}

removeAllCanonicalRecordDatasFromOwn() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { isNone } from '@ember/utils';
import { CUSTOM_MODEL_CLASS } from '@ember-data/canary-features';
import { assertPolymorphicType } from '@ember-data/store/-debug';

import OrderedSet from '../../ordered-set';
import Relationship from './relationship';

type RelationshipSchema = import('@ember-data/store/-private/ts-interfaces/record-data-schemas').RelationshipSchema;
Expand Down Expand Up @@ -156,24 +155,12 @@ export default class ManyRelationship extends Relationship {
}

computeChanges(recordDatas: RelationshipRecordData[] = []) {
let members = this.canonicalMembers;
let recordDatasToRemove: RelationshipRecordData[] = [];
let recordDatasSet = setForArray(recordDatas);

members.forEach(member => {
if (recordDatasSet.has(member)) {
return;
}

recordDatasToRemove.push(member);
});

this.removeCanonicalRecordDatas(recordDatasToRemove);

const members = this.canonicalMembers.toArray();
for (let i = members.length - 1; i >= 0; i--) {
this.removeCanonicalRecordData(members[i], i);
}
for (let i = 0, l = recordDatas.length; i < l; i++) {
let recordData = recordDatas[i];
this.removeCanonicalRecordData(recordData);
this.addCanonicalRecordData(recordData, i);
this.addCanonicalRecordData(recordDatas[i], i);
}
}

Expand Down Expand Up @@ -255,15 +242,3 @@ export default class ManyRelationship extends Relationship {
}
}
}

function setForArray(array) {
var set = new OrderedSet();

if (array) {
for (var i = 0, l = array.length; i < l; i++) {
set.add(array[i]);
}
}

return set;
}
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ export default class Relationship {

removeCanonicalRecordData(recordData: RelationshipRecordData, idx?: number) {
if (this.canonicalMembers.has(recordData)) {
this.removeCanonicalRecordDataFromOwn(recordData);
this.removeCanonicalRecordDataFromOwn(recordData, idx);
if (this.inverseKey) {
this.removeCanonicalRecordDataFromInverse(recordData);
} else {
Expand Down Expand Up @@ -478,7 +478,7 @@ export default class Relationship {
}

removeCanonicalRecordDataFromOwn(recordData: RelationshipRecordData | null, idx?: number) {
this.canonicalMembers.delete(recordData);
this.canonicalMembers.deleteWithIndex(recordData, idx);
this.flushCanonicalLater();
}

Expand Down

0 comments on commit 5b2dfaa

Please sign in to comment.