sproutcore/sproutcore — Issue #626: SC.ManyArray#addInverseRecord: possible infinite loop
Author: rajeshsegu
Created: 2011-11-11 19:05:07+00:00
State: open

I have SC.Records setup like: ( using SC 1.6 )

File {
versions: SC.Record.toMany("Version", {
inverse: "parent",
isMaster: true,
orderBy: function(){... return 1, -1, 0....}
})
}

Version {

parent: SC.Record.toOne("File", {
key: "fileId",
inverse: "versions",
isMaster: false
})
}

adding a Version record to File record using addInverseRecord() method tends to get into infinite loop with the combination of use of "orderBy". Specially happens when I am inserting the second record. Consistently reproducible.

eg: fileRecord.get("versions").addInverseRecord(versionRecord);

Found that issue that the binary sort algorithm employed to find the index before insertion. Looks like the indices are not incremented/decremented while doing the recursion in SC.ManyArray#_findInsertionLocation() ( binary sort )

Fixed it like this ( see comments in the below code)

_findInsertionLocation: function(rec, min, max, orderBy) {
var idx = min+Math.floor((max-min)/2),
cur = this.objectAt(idx),
order = this._compare(rec, cur, orderBy);
if (order < 0) {
if (idx===0) return idx;
//idx changed to idx-1
else return this._findInsertionLocation(rec, 0, idx-1, orderBy);
} else if (order > 0) {
if (idx >= max) return idx;
//idx changed to idx+1
else return this._findInsertionLocation(rec, idx+1, max, orderBy);
} else return idx;
}

Hope this makes it into the SC1.7 :)