+\r
+ \r
+ // Recursive partition for quicksort.\r
+ // Dataflex arrays track the type of each row and perform a sort acordingly\r
+ // but we have no easy way of knowing. So perform compare based on what a\r
+ // value looks "like" unless told otherwise. \r
+ // Index from (lo_in), index to (hi_in), numeric/string mode (1=integer, 0=string), invert (1=descending, 0=ascending)\r
+ procedure partition integer lo_in integer hi_in integer mode integer itemy integer invert\r
+ local integer pivot lo_idx hi_idx t\r
+ local string pivot_val lo_row hi_row lo_val hi_val \r
+ \r
+ if ((hi_in-lo_in) > 0) begin\r
+ move lo_in to lo_idx\r
+ move hi_in to hi_idx \r
+ move ((lo_in+hi_in)/2) to pivot\r
+ \r
+ while ((lo_idx <= pivot) AND (hi_idx >= pivot))\r
+ \r
+ forward get array_value item pivot to pivot_val\r
+ get column_value item itemy item pivot_val to pivot_val\r
+ \r
+ forward get array_value item lo_idx to lo_row\r
+ get column_value item itemy item lo_row to lo_val\r
+\r
+ forward get array_value item hi_idx to hi_row\r
+ get column_value item itemy item hi_row to hi_val\r
+\r
+ \r
+ if (invert) begin\r
+ while ( ( ((mode) and (number(lo_val) > number(pivot_val))) or (not (mode) and (lo_val > pivot_val))) and (lo_idx <= pivot))\r
+ increment lo_idx\r
+ forward get array_value item lo_idx to lo_row\r
+ get column_value item itemy item lo_row to lo_val\r
+ loop\r
+ while ( ( ((mode) and (number(hi_val) < number(pivot_val))) or (not (mode) and (hi_val < pivot_val))) and (hi_idx >= pivot))\r
+ decrement hi_idx\r
+ forward get array_value item hi_idx to hi_row\r
+ get column_value item itemy item hi_row to hi_val\r
+ loop\r
+ end\r
+ else begin\r
+ while ( ( ((mode) and (number(lo_val) < number(pivot_val))) or (not (mode) and (lo_val < pivot_val))) and (lo_idx <= pivot))\r
+ increment lo_idx\r
+ forward get array_value item lo_idx to lo_row\r
+ get column_value item itemy item lo_row to lo_val\r
+ loop\r
+ while ( ( ((mode) and (number(hi_val) > number(pivot_val))) or (not (mode) and (hi_val > pivot_val))) and (hi_idx >= pivot))\r
+ decrement hi_idx\r
+ forward get array_value item hi_idx to hi_row\r
+ get column_value item itemy item hi_row to hi_val\r
+ loop\r
+ end\r
+ \r
+ forward set array_value item lo_idx to hi_row\r
+ forward set array_value item hi_idx to lo_row\r
+ \r
+ increment lo_idx\r
+ decrement hi_idx\r
+ \r
+ if ((lo_idx-1) = pivot) begin\r
+ increment hi_idx\r
+ move hi_idx to pivot\r
+ end\r
+ else if ((hi_idx+1) = pivot) begin\r
+ decrement lo_idx\r
+ move lo_idx to pivot\r
+ end\r
+ \r
+ loop\r
+ \r
+ if ((pivot-lo_in) > 1);\r
+ send partition lo_in (pivot-1) mode itemy invert\r
+ if ((hi_in-pivot) > 1);\r
+ send partition (pivot+1) hi_in mode itemy invert\r
+ end \r
+ end_procedure \r
+ \r
+ // Perform a quick sort on a perticular column (y) in the martix\r
+ // This is done in native dataflex, so no match for compiled C\r
+ procedure quick_sort integer itemy string order integer mode\r
+ local integer l_i l_j l_iHashOn l_iMax l_iInvert\r
+ local string l_sBuf\r
+ \r
+ if (uppercase(left(trim(order),4)) = "DESC") move 1 to l_iInvert\r
+ else move 0 to l_iInvert \r
+ \r
+ get item_count to l_iMax\r
+ \r
+ // If we've not been told string/numeric, try and work out here.\r
+ if (mode = -1) begin\r
+ for l_i from 0 to (l_iMax-1)\r
+ forward get array_value item l_i to l_sBuf\r
+ get column_value item itemy item l_sBuf to l_sBuf\r
+ move (is_number(l_sBuf)) to mode\r
+ if (mode = 0) break\r
+ loop\r
+ end\r
+ \r
+ // Remove the current hash index if there is one \r
+ get c_iHashOn to l_iHashOn\r
+ if (l_iHashOn <> -1);\r
+ send remove_hash_on_column \r
+ \r
+ // Do the quick-sort\r
+ send partition 0 (l_iMax-1) mode itemy l_iInvert\r
+ \r
+ // Recreate any the hash if there was one\r
+ if (l_iHashOn <> -1);\r
+ send hash_on_column l_iHashOn\r
+\r
+ end_procedure\r
+ \r
+ //Wrapper for sort_items\r
+ procedure sort_items integer itemy string order\r
+ send quick_sort itemy order -1\r
+ end_procedure\r
+ \r
+ //Wrapper for sort_items\r
+ procedure sort_items_ascii integer itemy string order\r
+ send quick_sort itemy order 0\r
+ end_procedure \r
+ \r
+ //Wrapper for sort_items\r
+ procedure sort_items_num integer itemy string order\r
+ send quick_sort itemy order 1\r
+ end_procedure \r