1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 // We use varying sorts across the self-hosted codebase. All sorts are
6 // consolidated here to avoid confusion and re-implementation of existing
9 // For sorting small typed arrays.
10 function InsertionSort(array, from, to, comparefn) {
12 for (i = from + 1; i <= to; i++) {
14 for (j = i - 1; j >= from; j--) {
16 if (callContentFunction(comparefn, undefined, swap, item) <= 0) {
25 // A helper function for MergeSortTypedArray.
27 // Merge comparefn-sorted slices list[start..<=mid] and list[mid+1..<=end],
28 // storing the merged sequence in out[start..<=end].
29 function MergeTypedArray(list, out, start, mid, end, comparefn) {
30 // Skip lopsided runs to avoid doing useless work.
31 // Skip calling the comparator if the sub-list is already sorted.
34 callContentFunction(comparefn, undefined, list[mid], list[mid + 1]) <= 0
36 for (var i = start; i <= end; i++) {
45 while (i <= mid && j <= end) {
48 if (callContentFunction(comparefn, undefined, lvalue, rvalue) <= 0) {
57 // Empty out any remaining elements.
66 // Iterative, bottom up, mergesort. Optimized version for TypedArrays.
67 function MergeSortTypedArray(array, len, comparefn) {
69 IsPossiblyWrappedTypedArray(array),
70 "MergeSortTypedArray works only with typed arrays."
73 // Use the same TypedArray kind for the buffer.
74 var C = ConstructorForTypedArray(array);
76 var lBuffer = new C(len);
78 // Copy all elements into a temporary buffer, so that any modifications
79 // when calling |comparefn| are ignored.
80 for (var i = 0; i < len; i++) {
81 lBuffer[i] = array[i];
84 // Insertion sort for small arrays, where "small" is defined by performance
87 InsertionSort(lBuffer, 0, len - 1, comparefn);
92 // We do all of our allocating up front.
93 var rBuffer = new C(len);
95 // Use insertion sort for the initial ranges.
97 for (var start = 0; start < len - 1; start += windowSize) {
98 var end = std_Math_min(start + windowSize - 1, len - 1);
99 InsertionSort(lBuffer, start, end, comparefn);
102 for (; windowSize < len; windowSize = 2 * windowSize) {
103 for (var start = 0; start < len; start += 2 * windowSize) {
104 // The midpoint between the two subarrays.
105 var mid = start + windowSize - 1;
107 // To keep from going over the edge.
108 var end = std_Math_min(start + 2 * windowSize - 1, len - 1);
110 MergeTypedArray(lBuffer, rBuffer, start, mid, end, comparefn);