OLD | NEW |
---|---|
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 630 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
641 this[i++] = %_Arguments(arguments_index++); | 641 this[i++] = %_Arguments(arguments_index++); |
642 } | 642 } |
643 this.length = len - del_count + num_additional_args; | 643 this.length = len - del_count + num_additional_args; |
644 | 644 |
645 // Return the deleted elements. | 645 // Return the deleted elements. |
646 return deleted_elements; | 646 return deleted_elements; |
647 }; | 647 }; |
648 | 648 |
649 | 649 |
650 function ArraySort(comparefn) { | 650 function ArraySort(comparefn) { |
651 // Standard in-place HeapSort algorithm. | 651 // Standard in-place HeapSort algorithm. |
mdakin
2008/09/25 14:25:28
I think it is Quicksort now.
| |
652 | 652 |
653 function Compare(x,y) { | 653 function Compare(x,y) { |
654 if (IS_UNDEFINED(x)) { | 654 if (IS_UNDEFINED(x)) { |
655 if (IS_UNDEFINED(y)) return 0; | 655 if (IS_UNDEFINED(y)) return 0; |
656 return 1; | 656 return 1; |
657 } | 657 } |
658 if (IS_UNDEFINED(y)) return -1; | 658 if (IS_UNDEFINED(y)) return -1; |
659 | 659 |
660 if (IS_FUNCTION(comparefn)) { | 660 if (IS_FUNCTION(comparefn)) { |
661 return comparefn.call(null, x, y); | 661 return comparefn.call(null, x, y); |
662 } | 662 } |
663 if (%_IsSmi(x) && %_IsSmi(y)) { | 663 if (%_IsSmi(x) && %_IsSmi(y)) { |
664 return %SmiLexicographicCompare(x, y); | 664 return %SmiLexicographicCompare(x, y); |
665 } | 665 } |
666 x = ToString(x); | 666 x = ToString(x); |
667 y = ToString(y); | 667 y = ToString(y); |
668 if (x == y) return 0; | 668 if (x == y) return 0; |
669 else return x < y ? -1 : 1; | 669 else return x < y ? -1 : 1; |
670 }; | 670 }; |
671 | 671 |
672 function QuickSort(a, from, to) { | |
673 if (from >= to - 1) return; | |
674 var pivot_index = global.Math.floor(global.Math.random() * (to - from)) + fr om; | |
Mads Ager (chromium)
2008/09/24 12:34:43
We need to make sure that we use the original Math
| |
675 var pivot = a[pivot_index]; | |
676 a[pivot_index] = a[to - 1]; | |
677 a[to - 1] = pivot; | |
678 var partition = from; | |
679 for (var i = from; i < to - 1; i++) { | |
680 var element = a[i]; | |
681 if (Compare(element, pivot) < 0) { | |
682 a[i] = a[partition]; | |
683 a[partition] = element; | |
684 partition++; | |
685 } | |
686 } | |
687 a[to - 1] = a[partition]; | |
688 a[partition] = pivot; | |
689 QuickSort(a, from, partition); | |
690 QuickSort(a, partition + 1, to); | |
691 } | |
692 | |
672 var old_length = ToUint32(this.length); | 693 var old_length = ToUint32(this.length); |
673 | 694 |
674 %RemoveArrayHoles(this); | 695 %RemoveArrayHoles(this); |
675 | 696 |
676 var length = ToUint32(this.length); | 697 var length = ToUint32(this.length); |
mdakin
2008/09/25 14:25:28
Maybe using insertion sort for small arrays (<10 e
| |
677 | 698 QuickSort(this, 0, length); |
678 // Bottom-up max-heap construction. | |
679 for (var i = 1; i < length; ++i) { | |
680 var child_index = i; | |
681 while (child_index > 0) { | |
682 var parent_index = ((child_index + 1) >> 1) - 1; | |
683 var parent_value = this[parent_index], child_value = this[child_index]; | |
684 if (Compare(parent_value, child_value) < 0) { | |
685 this[parent_index] = child_value; | |
686 this[child_index] = parent_value; | |
687 } else { | |
688 break; | |
689 } | |
690 child_index = parent_index; | |
691 } | |
692 } | |
693 | |
694 // Extract element and create sorted array. | |
695 for (var i = length - 1; i > 0; --i) { | |
696 // Put the max element at the back of the array. | |
697 var t0 = this[0]; this[0] = this[i]; this[i] = t0; | |
698 // Sift down the new top element. | |
699 var parent_index = 0; | |
700 while (true) { | |
701 var child_index = ((parent_index + 1) << 1) - 1; | |
702 if (child_index >= i) break; | |
703 var child1_value = this[child_index]; | |
704 var child2_value = this[child_index + 1]; | |
705 var parent_value = this[parent_index]; | |
706 if (child_index + 1 >= i || Compare(child1_value, child2_value) > 0) { | |
707 if (Compare(parent_value, child1_value) > 0) break; | |
708 this[child_index] = parent_value; | |
709 this[parent_index] = child1_value; | |
710 parent_index = child_index; | |
711 } else { | |
712 if (Compare(parent_value, child2_value) > 0) break; | |
713 this[child_index + 1] = parent_value; | |
714 this[parent_index] = child2_value; | |
715 parent_index = child_index + 1; | |
716 } | |
717 } | |
718 } | |
719 | |
720 // We only changed the length of the this object (in | |
721 // RemoveArrayHoles) if it was an array. We are not allowed to set | |
722 // the length of the this object if it is not an array because this | |
723 // might introduce a new length property. | |
724 if (IS_ARRAY(this)) { | |
Mads Ager (chromium)
2008/09/24 12:34:43
This piece of code should still be needed. If we
| |
725 this.length = old_length; | |
726 } | |
727 | |
728 return this; | 699 return this; |
729 }; | 700 }; |
730 | 701 |
731 | 702 |
732 // The following functions cannot be made efficient on sparse arrays while | 703 // The following functions cannot be made efficient on sparse arrays while |
733 // preserving the semantics, since the calls to the receiver function can add | 704 // preserving the semantics, since the calls to the receiver function can add |
734 // or delete elements from the array. | 705 // or delete elements from the array. |
735 | 706 |
736 function ArrayFilter(f, receiver) { | 707 function ArrayFilter(f, receiver) { |
737 if (!IS_FUNCTION(f)) { | 708 if (!IS_FUNCTION(f)) { |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
919 ArrayEvery: 1, | 890 ArrayEvery: 1, |
920 ArrayMap: 1, | 891 ArrayMap: 1, |
921 ArrayIndexOf: 1, | 892 ArrayIndexOf: 1, |
922 ArrayLastIndexOf: 1, | 893 ArrayLastIndexOf: 1, |
923 ArrayPush: 1 | 894 ArrayPush: 1 |
924 }); | 895 }); |
925 }; | 896 }; |
926 | 897 |
927 | 898 |
928 SetupArray(); | 899 SetupArray(); |
OLD | NEW |