@@ -16,10 +16,11 @@ type ('a : any mod separable) t = 'a array
1616type % template ('a : k ) t = 'a array [@@ kind k = (base_non_value, immediate, immediate64)]
1717
1818[%% rederive.portable
19- type nonrec 'a t = 'a array [@@ deriving globalize , sexp ~stackify , sexp_grammar ]]
19+ type nonrec ('a : value_or_null mod separable) t = 'a array
20+ [@@ deriving globalize , sexp ~stackify , sexp_grammar ]]
2021
2122(* This module implements a new in-place, constant heap sorting algorithm to replace the
22- one used by the standard libraries. Its only purpose is to be faster (hopefully
23+ one used by the standard libraries. Its only purpose is to be faster (hopefully
2324 strictly faster) than the base sort and stable_sort.
2425
2526 At a high level the algorithm is:
@@ -39,11 +40,10 @@ type%template ('a : k) t = 'a array [@@kind k = (base_non_value, immediate, imme
3940 behavior
4041
4142 See the following for more information:
42- - "Dual-Pivot Quicksort" by Vladimir Yaroslavskiy.
43- Available at
43+ - "Dual-Pivot Quicksort" by Vladimir Yaroslavskiy. Available at
4444 http://www.kriche.com.ar/root/programming/spaceTimeComplexity/DualPivotQuicksort.pdf
45- - "Quicksort is Optimal" by Sedgewick and Bentley.
46- Slides at http://www.cs.princeton.edu/~rs/talks/QuicksortIsOptimal.pdf
45+ - "Quicksort is Optimal" by Sedgewick and Bentley. Slides at
46+ http://www.cs.princeton.edu/~rs/talks/QuicksortIsOptimal.pdf
4747 - http://www.sorting-algorithms.com/quick-sort-3-way *)
4848
4949module % template.portable
7575 (* http://en.wikipedia.org/wiki/Insertion_sort *)
7676 module Insertion_sort : Sort = struct
7777 (* loop invariants:
78- 1. the subarray arr[left .. i-1] is sorted
79- 2. the subarray arr[i+1 .. pos] is sorted and contains only elements > v
80- 3. arr[i] may be thought of as containing v
78+ 1. the subarray arr[left .. i-1] is sorted
79+ 2. the subarray arr[i+1 .. pos] is sorted and contains only elements > v
80+ 3. arr[i] may be thought of as containing v
8181 *)
8282 let rec insert_loop arr ~left ~compare i v =
8383 let i_next = i - 1 in
8989 ;;
9090
9191 let sort arr ~compare ~left ~right =
92- (* loop invariant:
93- [arr] is sorted from [left] to [pos - 1], inclusive *)
92+ (* loop invariant: [arr] is sorted from [left] to [pos - 1], inclusive *)
9493 for pos = left + 1 to right do
9594 let v = get arr pos in
9695 let final_pos = insert_loop arr ~left ~compare pos v in
@@ -101,8 +100,7 @@ struct
101100
102101 (* http://en.wikipedia.org/wiki/Heapsort *)
103102 module Heap_sort : Sort = struct
104- (* loop invariant:
105- root's children are both either roots of max-heaps or > right *)
103+ (* loop invariant: root's children are both either roots of max-heaps or > right *)
106104 let rec heapify arr ~compare root ~left ~right =
107105 let relative_root = root - left in
108106 let left_child = (2 * relative_root) + left + 1 in
@@ -124,7 +122,7 @@ struct
124122 ;;
125123
126124 let build_heap arr ~compare ~left ~right =
127- (* Elements in the second half of the array are already heaps of size 1. We move
125+ (* Elements in the second half of the array are already heaps of size 1. We move
128126 through the first half of the array from back to front examining the element at
129127 hand, and the left and right children, fixing the heap property as we go. *)
130128 for i = (left + right) / 2 downto left do
@@ -135,9 +133,9 @@ struct
135133 let sort arr ~compare ~left ~right =
136134 build_heap arr ~compare ~left ~right ;
137135 (* loop invariants:
138- 1. the subarray arr[left ... i] is a max-heap H
139- 2. the subarray arr[i+1 ... right] is sorted (call it S)
140- 3. every element of H is less than every element of S *)
136+ 1. the subarray arr[left ... i] is a max-heap H
137+ 2. the subarray arr[i+1 ... right] is sorted (call it S)
138+ 3. every element of H is less than every element of S *)
141139 for i = right downto left + 1 do
142140 swap arr left i;
143141 heapify arr ~compare left ~left ~right: (i - 1 )
@@ -175,7 +173,7 @@ struct
175173 4-----o--------o--o--|-----o--4
176174 | | |
177175 5-----o--------------o-----o--5
178- v} *)
176+ v} *)
179177 compare_and_swap m1 m2;
180178 compare_and_swap m4 m5;
181179 compare_and_swap m1 m3;
@@ -188,13 +186,11 @@ struct
188186 ;;
189187
190188 (* choose pivots for the array by sorting 5 elements and examining the center three
191- elements. The goal is to choose two pivots that will either:
192- - break the range up into 3 even partitions
193- or
194- - eliminate a commonly appearing element by sorting it into the center partition
195- by itself
196- To this end we look at the center 3 elements of the 5 and return pairs of equal
197- elements or the widest range *)
189+ elements. The goal is to choose two pivots that will either:
190+ - break the range up into 3 even partitions or
191+ - eliminate a commonly appearing element by sorting it into the center partition by
192+ itself To this end we look at the center 3 elements of the 5 and return pairs of
193+ equal elements or the widest range *)
198194 let choose_pivots arr ~(local_ compare : _ -> _ -> _ ) ~left ~right =
199195 let sixth = (right - left) / 6 in
200196 let m1 = left + sixth in
@@ -215,7 +211,7 @@ struct
215211
216212 let dual_pivot_partition arr ~(local_ compare : _ -> _ -> _ ) ~left ~right =
217213 let #(pivot1, pivot2, pivots_equal) = choose_pivots arr ~compare ~left ~right in
218- (* loop invariants:
214+ (* = loop invariants:
219215 1. left <= l < r <= right
220216 2. l <= p <= r
221217 3. l <= x < p implies arr[x] >= pivot1
@@ -233,7 +229,7 @@ struct
233229 loop (l + 1 ) (p + 1 ) r)
234230 else if compare pv pivot2 > 0
235231 then (
236- (* loop invariants: same as those of the outer loop *)
232+ (* loop invariants: same as those of the outer loop *)
237233 let rec scan_backwards r =
238234 if r > p && compare (get arr r) pivot2 > 0
239235 then scan_backwards (r - 1 )
@@ -251,7 +247,7 @@ struct
251247 let rec intro_sort arr ~max_depth ~compare ~left ~right =
252248 let len = right - left + 1 in
253249 (* This takes care of some edge cases, such as left > right or very short arrays,
254- since Insertion_sort.sort handles these cases properly. Thus we don't need to
250+ since Insertion_sort.sort handles these cases properly. Thus we don't need to
255251 make sure that left and right are valid in recursive calls. *)
256252 if len < = 32
257253 then Insertion_sort. sort arr ~compare ~left ~right
@@ -691,8 +687,7 @@ let check_length2_exn name t1 t2 =
691687 if n1 <> n2 then raise_length_mismatch name n1 n2
692688;;
693689
694- (* [of_list_map] and [of_list_rev_map] are based on functions from the OCaml
695- distribution. *)
690+ (* [of_list_map] and [of_list_rev_map] are based on functions from the OCaml distribution. *)
696691
697692let of_list_map (xs : (_ List.Constructors.t[@kind k1]) ) ~f =
698693 match xs with
@@ -1062,8 +1057,8 @@ let sorted_copy t ~compare =
10621057let last_exn t = t.(length t - 1 )
10631058let last = last_exn
10641059
1065- (* Convert to a sequence but does not attempt to protect against modification
1066- in the array. *)
1060+ (* Convert to a sequence but does not attempt to protect against modification in the
1061+ array. *)
10671062let to_sequence_mutable t =
10681063 Sequence. unfold_step ~init: 0 ~f: (fun i ->
10691064 if i > = length t
0 commit comments