Fix baseSortedIndex on large arrays by avoiding >>> use.

This commit is contained in:
John-David Dalton
2014-09-15 01:14:29 -07:00
parent 8d6f7de046
commit edf83823f1
2 changed files with 18 additions and 16 deletions

View File

@@ -30,8 +30,9 @@
/** Used as the TypeError message for "Functions" methods */ /** Used as the TypeError message for "Functions" methods */
var FUNC_ERROR_TEXT = 'Expected a function'; var FUNC_ERROR_TEXT = 'Expected a function';
/** Used as a reference for the max length of an array */ /** Used as references for the max length and index of an array */
var MAX_ARRAY_LENGTH = Math.pow(2, 32) - 1; var MAX_ARRAY_LENGTH = Math.pow(2, 32) - 1,
MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1;
/** /**
* Used as the maximum length of an array-like value. * Used as the maximum length of an array-like value.
@@ -2285,13 +2286,14 @@
valIsUndef = typeof value == 'undefined'; valIsUndef = typeof value == 'undefined';
while (low < high) { while (low < high) {
var mid = (low + high) >>> 1, var mid = floor((low + high) / 2),
computed = iteratee(array[mid]); computed = iteratee(array[mid]),
isReflexive = computed === computed;
if (valIsNaN) { if (valIsNaN) {
var setLow = computed === computed; var setLow = isReflexive || retHighest;
} else if (valIsUndef) { } else if (valIsUndef) {
setLow = computed === computed && typeof computed != 'undefined'; setLow = isReflexive && (retHighest || typeof computed != 'undefined');
} else { } else {
setLow = retHighest ? (computed <= value) : (computed < value); setLow = retHighest ? (computed <= value) : (computed < value);
} }
@@ -2301,7 +2303,7 @@
high = mid; high = mid;
} }
} }
return high; return nativeMin(high, MAX_ARRAY_INDEX);
} }
/** /**

View File

@@ -10056,24 +10056,24 @@
], function(array) { ], function(array) {
deepEqual(_.sortBy(array), expected); deepEqual(_.sortBy(array), expected);
strictEqual(func(expected, 3), 2); strictEqual(func(expected, 3), 2);
strictEqual(func(expected, undefined), 3); strictEqual(func(expected, undefined), isSortedIndex ? 3 : 4);
strictEqual(func(expected, NaN), isSortedIndex ? 4 : 5); strictEqual(func(expected, NaN), isSortedIndex ? 4 : 6);
}); });
}); });
test('`_.' + methodName + '` should support arrays larger than `Math.pow(2, 31) - 1`', 1, function() { test('`_.' + methodName + '` should support arrays larger than `Math.pow(2, 31) - 1`', 2, function() {
var length = Math.pow(2, 32) - 1, var array = [0],
index = length - 1, length = Math.pow(2, 32) - 1,
array = Array(length),
steps = 0; steps = 0;
array.length = length;
if (array.length == length) { if (array.length == length) {
array[index] = index; var actual = func(array, undefined, function() { steps++; });
func(array, index, function() { steps++; });
strictEqual(steps, 33); strictEqual(steps, 33);
strictEqual(actual, isSortedIndex ? 0 : (length - 1));
} }
else { else {
skipTest(); skipTest(2);
} }
}); });
}); });