Permalink
Browse files

Increased fastSort performance, particularly sortOn feature

  • Loading branch information...
1 parent f5a822f commit fab584331fd4958ea15e18809f5238346b41ef9a @skyboy committed Mar 14, 2012
Showing with 565 additions and 168 deletions.
  1. +565 −168 skyboy/utils/fastSort.as
View
733 skyboy/utils/fastSort.as
@@ -56,45 +56,77 @@ package skyboy.utils {
* @author skyboy
*/
/**
- * fastSort(*, uint);
- * fastSort(*, String, uint);
+ * fastSort(* obj, uint options [, uint length, uint startIndex] );
+ * fastSort(* obj, String name, uint options [, uint length, uint startIndex] );
*
- * fastSort(vectorRef, "z", Array.NUMERIC);
* @param *: input The object to be sorted. Either an Array, Vector, or any Object (or subclass of) that has a length property and numeric indicies
- * @param *: ...rest The second parameter can either be options (pass in the same you would for Array's sort method) or a String to trigger sortOn functionality, the third should then be the options.
+ * @param *: rest0 Either options (pass in the same you would for Array's sort method) or a String to trigger sortOn functionality (def: stringSort)
+ * @param *: rest1 Either options if rest0 is a String or length (def: stringSort or input.length)
+ * @param *: rest2 Either length if rest0 is String or startIndex for sorting (def: input.length or 0)
+ * @param *: rest3 Either startIndex if rest0 is String or undefined (def: 0 or undefined)
*/
public function fastSort(input:*, ...rest):void {
- if (!input || !("length" in input) || !(input.length is int)) return;
- sortVec.length = 0;
- sortVec.length = input.length as uint;
- if (rest[0] is String) {
- if (!(rest[1] is Number)) rest[1] = 0;
- if (input is Array) {
- sortOnArray(input, rest[0], rest[1]);
- } else if (input is Vector.<*>) {
- sortOn(input, rest[0], rest[1]);
- } else {
- sortOnObject(input, rest[0], rest[1]);
- }
+ //public function fastSort(input:*, rest0:* = 0, rest1:* = undefined, rest2:* = undefined, rest3:* = undefined):void {
+ if (!input) throw new ArgumentError("Can not sort null");
+ var sortON:Boolean = rest[0] is String;
+ var optI:uint = int(sortON);
+ var lenI:uint = 1 + optI;
+ var startI:uint = 2 + optI;
+ if (("length" in input) && (input.length is int)) {// grab length from the input
+ length = input.length;
+ if (!(rest[startI] is Number)) rest[startI] = 0;
+ if (rest[lenI] is Number) length = rest[lenI];
} else {
- if (!(rest[0] is Number)) rest[0] = 0;
- if (input is Array) {
- sortArray(input, rest[0]);
- } else if (input is Vector.<*>) {
- sort(input, rest[0]);
+ if (!(rest[lenI] is Number)) throw new Error("Length is unknown. Can not sort.");
+ length = rest[lenI];
+ if (!(rest[startI] is Number)) rest[startI] = 0;
+ }
+ if (!(rest[optI] is Number)) rest[optI] = 0;
+ optI = rest[optI];
+ if (sortON) {
+ if (optI & NUMERIC) {
+ numVec.length = length + rest[startI];
+ sortOnNumber(input, rest[0], optI, length, rest[startI]);
} else {
- sortObject(input, rest[0]);
+ sortVec.length = length + rest[startI];
+ if (input is Array) {
+ sortOnArray(input, rest[0], optI, length, rest[startI]);
+ } else if (input is Vector.<*>) {// numeric vectors not included
+ sortOn(input, rest[0], optI, length, rest[startI]);
+ } else {
+ sortOnObject(input, rest[0], optI, length, rest[startI]);
+ }
}
+ } else {
+ if (!(optI & NUMERIC)) sortVec.length = length + rest[startI];
+ f = LookupTable[input.constructor];
+ if (Boolean(f)) f(input, optI, length, rest[startI]);
+ else sortObject(input, optI, length, rest[startI]);
}
+ sortVec.length = 0;// clear the vectors (O(1) operation)
+ tempVec.length = 0;
+ numVec.length = 0;
+ return;
+ var length:uint, f:Function;// avoid compiler setting default values for these
}
}
-internal const NUMERIC:uint = Array.NUMERIC;
-internal const DESCENDING:uint = Array.DESCENDING;
-internal const CASEINSENSITIVE:uint = Array.CASEINSENSITIVE;
-internal const sortVec:Vector.<*> = new Vector.<*>(0xFFFF); // reserve a large amount of space in memory for growth when sorting.
-internal function quickSort(input:Vector.<*>, left:uint, right:uint, d:uint):void {
- if (right >= input.length) right = input.length - 1;
+import flash.system.System;
+import flash.utils.Dictionary;
+//{
+internal const NUMERIC:uint = Array.NUMERIC;
+internal const DESCENDING:uint = Array.DESCENDING;
+internal const CASEINSENSITIVE:uint = Array.CASEINSENSITIVE;
+internal const sortVec:Vector.<*> = new Vector.<*>(0xFFFF);
+internal const tempVec:Vector.<*> = new Vector.<*>(0xFFFF);
+internal const numVec:Vector.<Number> = new Vector.<Number>(0xFFFF);
+internal const LookupTable:Dictionary = new Dictionary;
+LookupTable[Vector.<Number>] = sortNumber;
+LookupTable[Vector.<int>] = sortInt;
+LookupTable[Vector.<uint>] = sortUint;
+LookupTable[Vector.<*>] = sortVector;
+LookupTable[Array] = sortArray;
+internal function quickSort(input:Vector.<*>, left:uint, right:uint, d:int):void {
if (left >= right) return;
var j:uint = right, i:uint = left;
var size:uint = right - left;
@@ -130,14 +162,15 @@ internal function quickSort(input:Vector.<*>, left:uint, right:uint, d:uint):voi
}
}
if (right) {
- if (left == right) {
+ if (left === right) {
if (input[left] < pivotPoint) ++left;
else if (input[right] > pivotPoint) --right;
}
if (i < right) {
quickSort(input, i, right, d + 1);
}
- } else if (!left) left = 1;
+ }
+ left |= int(!left) & int(!right);
if (j <= left) return;
i = left;
right = j;
@@ -146,11 +179,11 @@ internal function quickSort(input:Vector.<*>, left:uint, right:uint, d:uint):voi
++d;
} while (true);
}
-internal function quickSortOn(input:Vector.<*>, sInput:Vector.<*>, left:uint, right:uint, d:uint):void {
- var j:uint = right >= input.length ? right = input.length - 1 : right;
+internal function quickSortOn(input:Vector.<*>, sInput:Vector.<*>, left:int, right:int, d:int):void {
if (left >= right) return;
- var i:uint = left;
- var size:uint = right - left;
+ var j:int = right;
+ var i:int = left;
+ var size:int = right - left;
var pivotPoint:* = input[(right + left) >>> 1], t:*;
do {
if (size < 9) {
@@ -192,15 +225,16 @@ internal function quickSortOn(input:Vector.<*>, sInput:Vector.<*>, left:uint, ri
}
}
if (right) {
- if (left == right) {
+ if (left === right) {
if (input[right] > pivotPoint) --right;
else if (input[left] < pivotPoint) ++left;
else ++left, --right;
}
if (i < right) {
quickSortOn(input, sInput, i, right, d + 1);
}
- } else if (!left) left = 1;
+ }
+ left |= int(!left) & int(!right);
if (j <= left) return;
i = left;
right = j;
@@ -209,11 +243,10 @@ internal function quickSortOn(input:Vector.<*>, sInput:Vector.<*>, left:uint, ri
++d;
} while (true);
}
-internal function quickSortArray(input:Array, left:uint, right:uint, d:uint):void {
- if (right >= input.length) right = input.length - 1;
+internal function quickSortArray(input:Array, left:int, right:int, d:int):void {
if (left >= right) return;
- var j:uint = right, i:uint = left;
- var size:uint = right - left;
+ var j:int = right, i:int = left;
+ var size:int = right - left;
var pivotPoint:* = input[(right + left) >>> 1], t:*;
do {
if (size < 9) {
@@ -246,14 +279,15 @@ internal function quickSortArray(input:Array, left:uint, right:uint, d:uint):voi
}
}
if (right) {
- if (left == right) {
+ if (left === right) {
if (input[left] < pivotPoint) ++left;
else if (input[right] > pivotPoint) --right;
}
if (i < right) {
quickSortArray(input, i, right, d + 1);
}
- } else if (!left) left = 1;
+ }
+ left |= int(!left) & int(!right);
if (j <= left) return;
i = left;
right = j;
@@ -262,11 +296,11 @@ internal function quickSortArray(input:Array, left:uint, right:uint, d:uint):voi
++d;
} while (true);
}
-internal function quickSortOnArray(input:Vector.<*>, sInput:Array, left:uint, right:uint, d:uint):void {
- var j:uint = right >= input.length ? right = input.length - 1 : right;
+internal function quickSortOnArray(input:Vector.<*>, sInput:Array, left:int, right:int, d:int):void {
if (left >= right) return;
- var i:uint = left;
- var size:uint = right - left;
+ var j:int = right;
+ var i:int = left;
+ var size:int = right - left;
var pivotPoint:* = input[(right + left) >>> 1], t:*;
do {
if (size < 9) {
@@ -308,15 +342,16 @@ internal function quickSortOnArray(input:Vector.<*>, sInput:Array, left:uint, ri
}
}
if (right) {
- if (left == right) {
+ if (left === right) {
if (input[right] > pivotPoint) --right;
else if (input[left] < pivotPoint) ++left;
else ++left, --right;
}
if (i < right) {
quickSortOnArray(input, sInput, i, right, d + 1);
}
- } else if (!left) left = 1;
+ }
+ left |= int(!left) & int(!right);
if (j <= left) return;
i = left;
right = j;
@@ -325,8 +360,7 @@ internal function quickSortOnArray(input:Vector.<*>, sInput:Array, left:uint, ri
++d;
} while (true);
}
-internal function quickSortObject(input:*, left:uint, right:uint, d:uint):void {
- if (right >= input.length) right = input.length - 1;
+internal function quickSortObject(input:Object, left:uint, right:uint, d:int):void {
if (left >= right) return;
var j:uint = right, i:uint = left;
var size:uint = right - left;
@@ -362,14 +396,15 @@ internal function quickSortObject(input:*, left:uint, right:uint, d:uint):void {
}
}
if (right) {
- if (left == right) {
+ if (left === right) {
if (input[left] < pivotPoint) ++left;
else if (input[right] > pivotPoint) --right;
}
if (i < right) {
quickSortObject(input, i, right, d + 1);
}
- } else if (!left) left = 1;
+ }
+ left |= int(!left) & int(!right);
if (j <= left) return;
i = left;
right = j;
@@ -378,11 +413,11 @@ internal function quickSortObject(input:*, left:uint, right:uint, d:uint):void {
++d;
} while (true);
}
-internal function quickSortOnObject(input:Vector.<*>, sInput:*, left:uint, right:uint, d:uint):void {
- var j:uint = right >= input.length ? right = input.length - 1 : right;
+internal function quickSortOnObject(input:Vector.<*>, sInput:Object, left:int, right:int, d:int):void {
if (left >= right) return;
- var i:uint = left;
- var size:uint = right - left;
+ var j:int = right;
+ var i:int = left;
+ var size:int = right - left;
var pivotPoint:* = input[(right + left) >>> 1], t:*;
do {
if (size < 9) {
@@ -424,15 +459,191 @@ internal function quickSortOnObject(input:Vector.<*>, sInput:*, left:uint, right
}
}
if (right) {
- if (left == right) {
+ if (left === right) {
if (input[right] > pivotPoint) --right;
else if (input[left] < pivotPoint) ++left;
else ++left, --right;
}
if (i < right) {
quickSortOnObject(input, sInput, i, right, d + 1);
}
- } else if (!left) left = 1;
+ }
+ left |= int(!left) & int(!right);
+ if (j <= left) return;
+ i = left;
+ right = j;
+ pivotPoint = input[(right + left) >>> 1];
+ size = right - left;
+ ++d;
+ } while (true);
+}
+internal function quickSortOnNumber(input:Vector.<Number>, sInput:Object, left:int, right:int, d:int):void {
+ if (left >= right) return;
+ var j:int = right;
+ var i:int = left;
+ var size:int = right - left;
+ var pivotPoint:Number = input[(right + left) >>> 1];
+ do {
+ if (size < 9) {
+ do {
+ pivotPoint = input[left];
+ do {
+ ++left;
+ if (pivotPoint > input[left]) {
+ pivotPoint = input[left];
+ t = sInput[left];
+ do {
+ q = left - 1;
+ e = input[q];
+ input[left] = e;
+ sInput[left] = sInput[q];
+ left = q;
+ } while (int(left > i) & int(pivotPoint < e));
+ input[left] = pivotPoint;
+ sInput[left] = t;
+ }
+ } while (left < right);
+ ++i;
+ left = i;
+ } while (i < right);
+ return;
+ }
+ while (left < right) {
+ if (input[right] > pivotPoint) do {
+ --right;
+ } while (input[right] > pivotPoint);
+ if (input[left] < pivotPoint) do {
+ ++left;
+ } while (input[left] < pivotPoint);
+ if (left < right) {
+ e = input[left];
+ input[left] = input[right];
+ input[right] = e;
+ t = sInput[left];
+ sInput[left] = sInput[right];
+ sInput[right] = t;
+ ++left, --right;
+ }
+ }
+ if (right) {
+ if (left === right) {
+ e = input[left];
+ right -= int(e >= pivotPoint);
+ left += int(e <= pivotPoint);
+ }
+ if (i < right) {
+ quickSortOnNumber(input, sInput, i, right, d + 1);
+ }
+ }
+ left |= int(!left) & int(!right);
+ if (j <= left) return;
+ i = left;
+ right = j;
+ pivotPoint = input[(right + left) >>> 1];
+ size = right - left;
+ ++d;
+ } while (true);
+ return;
+ var e:Number, t:*, q:int;
+}
+internal function quickSortInt(input:Vector.<int>, left:uint, right:uint, d:int):void {
+ if (left >= right) return;
+ var j:uint = right, i:uint = left;
+ var size:uint = right - left;
+ var pivotPoint:int = input[(right + left) >>> 1], t:int;
+ do {
+ if (size < 9) {
+ pivotPoint = input[left];
+ do {
+ do {
+ ++left;
+ if (input[left] < pivotPoint) {
+ pivotPoint = input[left];
+ do { // this section can be improved.
+ input[left--] = input[left];
+ } while (left > i && pivotPoint < input[left]);
+ input[left] = pivotPoint;
+ }
+ } while (left < right);
+ ++i;
+ left = i;
+ pivotPoint = input[left];
+ } while (i < right);
+ return;
+ }
+ while (left < right) {
+ if (input[right] > pivotPoint) do { --right; } while (input[right] > pivotPoint);
+ if (input[left] < pivotPoint) do { ++left; } while (input[left] < pivotPoint);
+ if (left < right) {
+ t = input[left];
+ input[left] = input[right];
+ input[right] = t;
+ ++left, --right;
+ }
+ }
+ if (right) {
+ if (left === right) {
+ if (input[left] < pivotPoint) ++left;
+ else if (input[right] > pivotPoint) --right;
+ }
+ if (i < right) {
+ quickSortInt(input, i, right, d + 1);
+ }
+ }
+ left |= int(!left) & int(!right);
+ if (j <= left) return;
+ i = left;
+ right = j;
+ pivotPoint = input[(right + left) >>> 1];
+ size = right - left;
+ ++d;
+ } while (true);
+}
+internal function quickSortUint(input:Vector.<uint>, left:uint, right:uint, d:int):void {
+ if (left >= right) return;
+ var j:uint = right, i:uint = left;
+ var size:uint = right - left;
+ var pivotPoint:uint = input[(right + left) >>> 1], t:uint;
+ do {
+ if (size < 9) {
+ pivotPoint = input[left];
+ do {
+ do {
+ ++left;
+ if (input[left] < pivotPoint) {
+ pivotPoint = input[left];
+ do { // this section can be improved.
+ input[left] = input[(--left,left)];
+ } while (left > i && pivotPoint < input[left]);
+ input[left] = pivotPoint;
+ }
+ } while (left < right);
+ ++i;
+ left = i;
+ pivotPoint = input[left];
+ } while (i < right);
+ return;
+ }
+ while (left < right) {
+ if (input[right] > pivotPoint) do { --right; } while (input[right] > pivotPoint);
+ if (input[left] < pivotPoint) do { ++left; } while (input[left] < pivotPoint);
+ if (left < right) {
+ t = input[left];
+ input[left] = input[right];
+ input[right] = t;
+ ++left, --right;
+ }
+ }
+ if (right) {
+ if (left === right) {
+ if (input[left] < pivotPoint) ++left;
+ else if (input[right] > pivotPoint) --right;
+ }
+ if (i < right) {
+ quickSortUint(input, i, right, d + 1);
+ }
+ }
+ left |= int(!left) & int(!right);
if (j <= left) return;
i = left;
right = j;
@@ -441,12 +652,65 @@ internal function quickSortOnObject(input:Vector.<*>, sInput:*, left:uint, right
++d;
} while (true);
}
-internal function sort(input:Vector.<*>, options:uint):void {
- var n:uint = input.length;
+internal function quickSortNumber(input:Vector.<Number>, left:uint, right:uint, d:int):void {
+ if (left >= right) return;
+ var j:uint = right, i:uint = left;
+ var size:uint = right - left;
+ var pivotPoint:Number = input[(right + left) >>> 1], t:Number;
+ do {
+ if (size < 9) {
+ pivotPoint = input[left];
+ do {
+ do {
+ ++left;
+ if (input[left] < pivotPoint) {
+ pivotPoint = input[left];
+ do { // this section can be improved.
+ input[left--] = input[left];
+ } while (left > i && pivotPoint < input[left]);
+ input[left] = pivotPoint;
+ }
+ } while (left < right);
+ ++i;
+ left = i;
+ pivotPoint = input[left];
+ } while (i < right);
+ return;
+ }
+ while (left < right) {
+ if (input[right] > pivotPoint) do { --right; } while (input[right] > pivotPoint);
+ if (input[left] < pivotPoint) do { ++left; } while (input[left] < pivotPoint);
+ if (left < right) {
+ t = input[left];
+ input[left] = input[right];
+ input[right] = t;
+ ++left, --right;
+ }
+ }
+ if (right) {
+ if (left === right) {
+ if (input[left] < pivotPoint) ++left;
+ else if (input[right] > pivotPoint) --right;
+ }
+ if (i < right) {
+ quickSortNumber(input, i, right, d + 1);
+ }
+ }
+ left |= int(!left) & int(!right);
+ if (j <= left) return;
+ i = left;
+ right = j;
+ pivotPoint = input[(right + left) >>> 1];
+ size = right - left;
+ ++d;
+ } while (true);
+}
+internal function sort(input:Vector.<*>, options:uint, length:uint, startIndex:uint):void {
+ var n:uint = length;
if (n < 2) return;
- var q:uint, left:uint, right:uint = n;
+ var q:uint = startIndex, left:uint = q, right:uint = q + n;
var t:*;
- while (q != right) {
+ while (q !== right) {
t = input[q];
if (t === undefined) {
--right;
@@ -463,15 +727,15 @@ internal function sort(input:Vector.<*>, options:uint):void {
q = left;
while (q < right) {
t = input[q];
- if (t != t) {
+ if (t !== t) {
--right;
input[q] = input[right];
input[right] = NaN;
} else ++q;
}
- if (--right) {
+ if ((--right,right)) {
if (uint(right - 1) > left) {
- if (options == NUMERIC) {
+ if (options === NUMERIC) {
quickSort(input, left, right, 0);
} else {
var tempVec:Vector.<*> = sortVec;
@@ -489,45 +753,48 @@ internal function sort(input:Vector.<*>, options:uint):void {
}
}
if (options & DESCENDING) {
- var i:uint = 0;
- while (n < i) {
+ var i:uint = startIndex;
+ n += i;
+ while (n > i) {
t = input[i];
- input[i++] = input[--n];
+ input[i] = input[(--n,n)];
input[n] = t;
+ ++i;
}
}
}
-internal function sortOn(input:Vector.<*>, name:String, options:uint):void {
- var n:uint = input.length;
+internal function sortOn(input:Vector.<*>, name:String, options:uint, length:int, startIndex:int):void {
+ var n:int = length;
if (n < 2) return;
- var tempVec:Vector.<*> = sortVec, i:uint = n, t:*, j:uint = i;
- var left:uint, right:uint = i;
- while (j--) {
+ var left:int = startIndex, right:int = left + n;
+ var tempVec:Vector.<*> = sortVec, i:int = right, j:int = n, t:*;
+ while (j) {--j;
t = input[j];
t = name in t ? t[name] : t;
if (t === null) {
t = input[j];
input[j] = input[left];
input[left] = t;
- tempVec[left++] = null;
+ tempVec[left] = null;
+ ++left;
++j;
} else if (t === undefined) {
- if (--i != --right) {
+ if ((--i,i) !== (--right,right)) {
tempVec[i] = tempVec[right];
tempVec[right] = undefined;
t = input[right];
input[right] = input[j];
input[j] = t;
}
- } else tempVec[--i] = t;
- if (j == left) break;
+ } else tempVec[(--i,i)] = t;
+ if (j === left) break;
}
if (right > left) {
j = right;
- while (--j > left) {
+ while ((--j,j) > left) {
t = tempVec[j];
- if (t != t) {
- if (j != --right) {
+ if (t !== t) {
+ if (j !== (--right,right)) {
tempVec[j] = tempVec[right];
tempVec[right] = NaN;
t = input[right];
@@ -536,37 +803,49 @@ internal function sortOn(input:Vector.<*>, name:String, options:uint):void {
}
}
}
- if (--right) {
- if (uint(right - 1) > left) {
+ if ((--right,right)) {
+ if (right - 1 > left) {
if (!(options & NUMERIC)) {
- i = right;
+ i = left;
if (options & CASEINSENSITIVE) {
tempVec[i] = String(tempVec[i]).toUpperCase();
- while (i-- > left) tempVec[i] = String(tempVec[i]).toUpperCase();
+ while (i < right) ++i, tempVec[i] = String(tempVec[i]).toUpperCase();
} else {
tempVec[i] = String(tempVec[i]);
- while (i-- > left) tempVec[i] = String(tempVec[i]);
+ while (i < right) ++i, tempVec[i] = String(tempVec[i]);
}
}
quickSortOn(tempVec, input, left, right, 0);
}
}
}
if (options & DESCENDING) {
- i = 0;
- while (n != i) {
+ i = startIndex, n += i;
+ if (n & 1) {
t = input[i];
- input[i++] = input[--n];
+ input[i] = input[(--n,n)];
input[n] = t;
+ ++i;
+ }
+ n >>>= 1;
+ while (n > i) {
+ t = input[i];
+ input[i] = input[(--n,n)];
+ input[n] = t;
+ ++i;
+ t = input[i];
+ input[i] = input[(--n,n)];
+ input[n] = t;
+ ++i;
}
}
}
-internal function sortArray(input:Array, options:uint):void {
- var n:uint = input.length;
+internal function sortArray(input:Array, options:uint, length:uint, startIndex:uint):void {
+ var n:uint = length;
if (n < 2) return;
- var q:uint, left:uint, right:uint = n;
+ var q:uint = startIndex, left:uint = q, right:uint = q + n;
var t:*;
- while (q != right) {
+ while (q !== right) {
t = input[q];
if (t === undefined) {
--right;
@@ -583,71 +862,74 @@ internal function sortArray(input:Array, options:uint):void {
q = left;
while (q < right) {
t = input[q];
- if (t != t) {
+ if (t !== t) {
--right;
input[q] = input[right];
input[right] = NaN;
} else ++q;
}
- if (--right) {
+ if ((--right,right)) {
if (uint(right - 1) > left) {
- if (options == NUMERIC) {
+ if (options === NUMERIC) {
quickSortArray(input, left, right, 0);
} else {
var tempVec:Vector.<*> = sortVec;
q = right;
if (!(options & NUMERIC)) if (options & CASEINSENSITIVE) {
tempVec[q] = String(input[q]).toLowerCase();
- while (q-- > left) tempVec[q] = String(input[q]).toLowerCase();
+ while (q > left) --q, tempVec[q] = String(input[q]).toLowerCase();
} else {
tempVec[q] = String(input[q]);
- while (q-- > left) tempVec[q] = String(input[q]);
+ while (q > left) --q, tempVec[q] = String(input[q]);
}
quickSortOnArray(tempVec, input, left, right, 0);
}
}
}
}
if (options & DESCENDING) {
- var i:uint = 0;
- while (n < i) {
+ var i:uint = startIndex;
+ n += i;
+ while (n > i) {
t = input[i];
- input[i++] = input[--n];
+ input[i] = input[(--n,n)];
input[n] = t;
+ ++i;
}
}
}
-internal function sortOnArray(input:Array, name:String, options:uint):void {
- var n:uint = input.length;
+internal function sortOnArray(input:Array, name:String, options:uint, length:uint, startIndex:uint):void {
+ var n:uint = length;
if (n < 2) return;
- var tempVec:Vector.<*> = sortVec, i:uint = n, t:*, j:uint = i;
- var left:uint, right:uint = i;
- while (j--) {
+ var left:uint = startIndex, right:uint = left + n;
+ var tempVec:Vector.<*> = sortVec, i:uint = right, t:*, j:uint = n;
+ while (j) {--j;
t = input[j];
t = name in t ? t[name] : t;
if (t === null) {
t = input[j];
input[j] = input[left];
input[left] = t;
- tempVec[left++] = null;
+ tempVec[left] = null;
+ ++left;
++j;
} else if (t === undefined) {
- if (--i != --right) {
+ if ((--i,i) !== (--right,right)) {
tempVec[i] = tempVec[right];
tempVec[right] = undefined;
t = input[right];
input[right] = input[j];
input[j] = t;
}
- } else tempVec[--i] = t;
- if (j == left) break;
+ } else tempVec[(--i,i)] = t;
+ if (j === left) break;
}
if (right > left) {
j = right;
- while (--j > left) {
+ while ((--j,j) > left) {
t = tempVec[j];
- if (t != t) {
- if (j != --right) {
+ if (t !== t) {
+ if (j !== (--right,right)) {
tempVec[j] = tempVec[right];
tempVec[right] = NaN;
t = input[right];
@@ -656,37 +938,38 @@ internal function sortOnArray(input:Array, name:String, options:uint):void {
}
}
}
- if (--right) {
+ if ((--right,right)) {
if (uint(right - 1) > left) {
if (!(options & NUMERIC)) {
i = right;
if (options & CASEINSENSITIVE) {
tempVec[i] = String(tempVec[i]).toUpperCase();
- while (i-- > left) tempVec[i] = String(tempVec[i]).toUpperCase();
+ while (i > left) --i, tempVec[i] = String(tempVec[i]).toUpperCase();
} else {
tempVec[i] = String(tempVec[i]);
- while (i-- > left) tempVec[i] = String(tempVec[i]);
+ while (i > left) --i, tempVec[i] = String(tempVec[i]);
}
}
quickSortOnArray(tempVec, input, left, right, 0);
}
}
}
if (options & DESCENDING) {
- i = 0;
- while (n < i) {
+ i = startIndex, n += i;
+ while (n > i) {
t = input[i];
- input[i++] = input[--n];
+ input[i] = input[(--n,n)];
input[n] = t;
+ ++i;
}
}
}
-internal function sortObject(input:*, options:uint):void {
- var n:uint = input.length;
+internal function sortObject(input:Object, options:uint, length:uint, startIndex:uint):void {
+ var n:int = length;
if (n < 2) return;
- var q:uint, left:uint, right:uint = n;
+ var q:int = startIndex, left:uint = q, right:uint = q + n;
var t:*;
- while (q != right) {
+ while (uint(q) !== right) {
t = input[q];
if (t === undefined) {
--right;
@@ -701,73 +984,74 @@ internal function sortObject(input:*, options:uint):void {
}
if (right > left) {
q = left;
- while (q < right) {
+ while (uint(q) < right) {
t = input[q];
- if (t != t) {
+ if (t !== t) {
--right;
input[q] = input[right];
input[right] = NaN;
} else ++q;
}
- if (--right) {
+ if ((--right,right)) {
if (uint(right - 1) > left) {
- if (options == NUMERIC) {
+ if (options & NUMERIC) {
quickSortObject(input, left, right, 0);
} else {
var tempVec:Vector.<*> = sortVec;
q = right;
- if (!(options & NUMERIC)) if (options & CASEINSENSITIVE) {
+ if (options & CASEINSENSITIVE) {
tempVec[q] = String(input[q]).toLowerCase();
- while (q-- > left) tempVec[q] = String(input[q]).toLowerCase();
+ while (q > left) --q, tempVec[q] = String(input[q]).toLowerCase();
} else {
tempVec[q] = String(input[q]);
- while (q-- > left) tempVec[q] = String(input[q]);
+ while (q > left) --q, tempVec[q] = String(input[q]);
}
quickSortOnObject(tempVec, input, left, right, 0);
}
}
}
}
if (options & DESCENDING) {
- var i:uint = 0;
- while (n < i) {
+ var i:int = 0;
+ while (n > i) {
t = input[i];
- input[i++] = input[--n];
+ input[i] = input[(--n,n)];
input[n] = t;
+ ++i;
}
}
}
-internal function sortOnObject(input:*, name:String, options:uint):void {
- var n:uint = input.length;
+internal function sortOnObject(input:Object, name:String, options:uint, n:uint, startIndex:uint):void {
if (n < 2) return;
- var tempVec:Vector.<*> = sortVec, i:uint = n, t:*, j:uint = i;
- var left:uint, right:uint = i;
- while (j--) {
+ var left:uint = startIndex, right:uint = left + n;
+ var tempVec:Vector.<*> = sortVec, i:uint = right, t:*, j:uint = right;
+ while (j > left) {--j;
t = input[j];
t = name in t ? t[name] : t;
if (t === null) {
t = input[j];
input[j] = input[left];
input[left] = t;
- tempVec[left++] = null;
+ tempVec[left] = null;
+ ++left;
++j;
} else if (t === undefined) {
- if (--i != --right) {
+ if ((--i,i) !== (--right,right)) {
tempVec[i] = tempVec[right];
tempVec[right] = undefined;
t = input[right];
input[right] = input[j];
input[j] = t;
}
- } else tempVec[--i] = t;
- if (j == left) break;
+ } else tempVec[(--i,i)] = t;
+ if (j === left) break;
}
if (right > left) {
j = right;
- while (--j > left) {
+ while (j > left) { --j;
t = tempVec[j];
- if (t != t) {
- if (j != --right) {
+ if (t !== t) {
+ if (j !== (--right,right)) {
tempVec[j] = tempVec[right];
tempVec[right] = NaN;
t = input[right];
@@ -776,52 +1060,165 @@ internal function sortOnObject(input:*, name:String, options:uint):void {
}
}
}
- if (--right) {
+ --right;
+ if (right) {
if (uint(right - 1) > left) {
if (!(options & NUMERIC)) {
i = right;
if (options & CASEINSENSITIVE) {
tempVec[i] = String(tempVec[i]).toUpperCase();
- while (i-- > left) tempVec[i] = String(tempVec[i]).toUpperCase();
+ while (i > left) --i, tempVec[i] = String(tempVec[i]).toUpperCase();
} else {
tempVec[i] = String(tempVec[i]);
- while (i-- > left) tempVec[i] = String(tempVec[i]);
+ while (i > left) --i, tempVec[i] = String(tempVec[i]);
}
}
quickSortOnObject(tempVec, input, left, right, 0);
}
}
}
if (options & DESCENDING) {
- i = 0;
- while (n < i) {
+ i = startIndex, n += i;
+ --n;
+ while (n > i) {
t = input[i];
- input[i++] = input[--n];
+ input[i] = input[n];
input[n] = t;
+ ++i, --n;
}
}
}
+internal function sortOnNumber(input:Object, name:String, options:uint, length:uint, startIndex:uint):void {
+ if (length < 2) return;
+ var left:uint = startIndex, right:uint = left + length;
+ var tempVec:Vector.<Number> = numVec, i:uint = right, j:uint = right;
+ var p:Number = input[j - 1][name], s:int = 1;
+ while (j > left) { --j;
+ e = input[j];
+ t = e[name];
+ s &= int(!(t > p)); // ! > instead of <= to account for NaN
+ if (t !== t) {
+ --right;
+ tempVec[j] = tempVec[right];
+ input[j] = input[right];
+ input[right] = e;
+ }
+ }
+ --right;
+ if (int(!s) & int(right > left)) {
+ quickSortOnNumber(tempVec, input, left, right, 0);
+ }
+ if (options & DESCENDING) {
+ i = startIndex;
+ options = i + length - 1;
+ while (options > i) {
+ e = input[i];
+ input[i] = input[options];
+ input[options] = e;
+ ++i;
+ --options;
+ }
+ }
+ return;
+ var t:Number, e:*;
+}
+internal function sortNumber(input:Vector.<Number>, options:uint, n:uint, startIndex:uint):void {
+ if (n < 2) return;
+ var q:uint = startIndex, left:uint = q, right:uint = q + n, t:Number;
+ while (q < right) {
+ t = input[q];
+ if (t !== t) {
+ --right;
+ input[q] = input[right];
+ input[right] = NaN;
+ } else ++q;
+ }
+ --right;
+ if (right > left) {
+ if (options === NUMERIC) {
+ quickSortNumber(input, left, right, 0);
+ } else {
+ var tempVec:Vector.<*> = sortVec;
+ q = right;
+ if (!(options & NUMERIC)) {
+ tempVec[q] = String(input[q]);
+ while (q-- > left) tempVec[q] = String(input[q]);
+ }
+ quickSortOnObject(tempVec, input, left, right, 0);
+ }
+ }
+ if (options & DESCENDING) {
+ var i:uint = startIndex;
+ n += i;
+ while (n > i) {
+ t = input[i];
+ input[i] = input[(--n,n)];
+ input[n] = t;
+ ++i;
+ }
+ }
+}
+internal function sortInt(input:Vector.<int>, options:uint, length:uint, startIndex:uint):void {
+ if (length < 2) return;
+ var q:uint = startIndex, left:uint = q, right:uint = q + length - 1;
+ if (right > left) {
+ if (options & NUMERIC) {
+ quickSortInt(input, left, right, length);
+ } else {
+ var tempVec:Vector.<*> = sortVec;
+ q = right;
+ tempVec[q] = String(input[q]);
+ while (q < right) ++q, tempVec[q] = String(input[q]);
+ quickSortOnObject(tempVec, input, left, right, 0);
+ }
+ }
+ var t:int;
+ if (options & DESCENDING) {
+ options = startIndex;
+ length += options;
+ while (length > options) {
+ t = input[options];
+ input[options] = input[(--length,length)];
+ input[length] = t;
+ ++options;
+ }
+ }
+}
+internal function sortUint(input:Vector.<uint>, options:uint, n:uint, startIndex:uint):void {
+ if (n < 2) return;
+ var q:uint = startIndex, left:uint = q, right:uint = q + n - 1, t:uint = input[q];
+ if (right > left) {
+ if (options === NUMERIC) {
+ quickSortUint(input, left, right, 0);
+ } else {
+ var tempVec:Vector.<*> = sortVec;
+ q = right;
+ if (!(options & NUMERIC)) {
+ tempVec[q] = String(input[q]);
+ while (q-- > left) tempVec[q] = String(input[q]);
+ }
+ quickSortOnObject(tempVec, input, left, right, 0);
+ }
+ }
+ if (options & DESCENDING) {
+ var i:uint = startIndex;
+ n += i;
+ while (n > i) {
+ t = input[i];
+ input[i] = input[(--n,n)];
+ input[n] = t;
+ ++i;
+ }
+ }
+}
+internal function sortVector(input:*, options:uint, length:uint, startIndex:uint):void {
+ if (input is Vector.<*>) sort(input, options, length, startIndex);
+ else sortObject(input, options, length, startIndex);
+}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+//}

0 comments on commit fab5843

Please sign in to comment.