static VOID IViewHistRedrawContent P2C(IVIEW_WINDOW, w, LVAL, hdata) { int left, top, width, height, x, y, vleft, vtop, vwidth, vheight; StGWWinInfo *gwinfo; gwinfo = IViewWindowWinInfo(w); if (IViewMouseMode(w) == brushing) IViewEraseBrush(w); IViewGetContentMarginRect(w, &left, &top, &width, &height); StGrGetContentVariables(gwinfo, &x, &y); StGWStartBuffering(gwinfo); StGWSetClipRect(gwinfo, TRUE, left, top, width + 1, height + 1); /*StGWEraseRect(gwinfo, left, top, width + 1, height + 1);*/ IViewClearContent(w); sort_bins(w, hdata); size_bins(w, hdata); draw_hist(w, hdata); IViewDrawDataLines(w, x, y, 0, IViewNumLines(w)); #ifdef USESTRINGS IViewDrawDataStrings(w, x, y, 0, IViewNumStrings(w)); #endif /* USESTRINGS */ StGWBufferToScreen(gwinfo, left, top, width + 1, height + 1); StGWGetViewRect(gwinfo, &vleft, &vtop, &vwidth, &vheight); StGWSetClipRect(gwinfo, TRUE, vleft, vtop, vwidth, vheight); if (IViewMouseMode(w) == brushing) IViewDrawBrush(w); IViewResetScreenStates(w); }
inline void negative_float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset, size_t *bin_sizes) { Div_type max, min; if (is_sorted_or_find_extremes<RandomAccessIter, Div_type>(first, last, max, min)) return; unsigned log_divisor = get_log_divisor<float_log_mean_bin_size>( last - first, rough_log_2_size(Size_type(max - min))); Div_type div_min = min >> log_divisor; Div_type div_max = max >> log_divisor; unsigned bin_count = unsigned(div_max - div_min) + 1; unsigned cache_end; RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count); //Calculating the size of each bin for (RandomAccessIter current = first; current != last;) bin_sizes[unsigned((cast_float_iter<Div_type, RandomAccessIter>( current++) >> log_divisor) - div_min)]++; bins[bin_count - 1] = first; for (int ii = bin_count - 2; ii >= 0; --ii) bins[ii] = bins[ii + 1] + bin_sizes[ii + 1]; //Swap into place RandomAccessIter nextbinstart = first; //The last bin will always have the correct elements in it for (int ii = bin_count - 1; ii > 0; --ii) float_swap_loop<RandomAccessIter, Div_type> (bins, nextbinstart, ii, bin_sizes, log_divisor, div_min); //Update the end position because we don't process the last bin bin_cache[cache_offset] = last; //Return if we've completed bucketsorting if (!log_divisor) return; //Recursing size_t max_count = get_min_count<float_log_mean_bin_size, float_log_min_split_count, float_log_finishing_count>(log_divisor); RandomAccessIter lastPos = first; for (int ii = cache_end - 1; ii >= static_cast<int>(cache_offset); lastPos = bin_cache[ii], --ii) { size_t count = bin_cache[ii] - lastPos; if (count < 2) continue; if (count < max_count) boost::sort::pdqsort(lastPos, bin_cache[ii]); else negative_float_sort_rec<RandomAccessIter, Div_type, Size_type> (lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes); } }
inline void positive_float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset , size_t *bin_sizes) { Div_type max, min; if (is_sorted_or_find_extremes<RandomAccessIter, Div_type>(first, last, max, min)) return; unsigned log_divisor = get_log_divisor<float_log_mean_bin_size>( last - first, rough_log_2_size(Size_type(max - min))); Div_type div_min = min >> log_divisor; Div_type div_max = max >> log_divisor; unsigned bin_count = unsigned(div_max - div_min) + 1; unsigned cache_end; RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count); //Calculating the size of each bin for (RandomAccessIter current = first; current != last;) bin_sizes[unsigned((cast_float_iter<Div_type, RandomAccessIter>( current++) >> log_divisor) - div_min)]++; bins[0] = first; for (unsigned u = 0; u < bin_count - 1; u++) bins[u + 1] = bins[u] + bin_sizes[u]; //Swap into place RandomAccessIter nextbinstart = first; for (unsigned u = 0; u < bin_count - 1; ++u) float_swap_loop<RandomAccessIter, Div_type> (bins, nextbinstart, u, bin_sizes, log_divisor, div_min); bins[bin_count - 1] = last; //Return if we've completed bucketsorting if (!log_divisor) return; //Recursing size_t max_count = get_min_count<float_log_mean_bin_size, float_log_min_split_count, float_log_finishing_count>(log_divisor); RandomAccessIter lastPos = first; for (unsigned u = cache_offset; u < cache_end; lastPos = bin_cache[u], ++u) { size_t count = bin_cache[u] - lastPos; if (count < 2) continue; if (count < max_count) std::sort(lastPos, bin_cache[u]); else positive_float_sort_rec<RandomAccessIter, Div_type, Size_type> (lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes); } }
inline void float_sort_rec(RandomAccessIter first, RandomAccessIter last, std::vector<RandomAccessIter> &bin_cache, unsigned cache_offset, size_t *bin_sizes, Right_shift rshift, Compare comp) { Div_type max, min; if (is_sorted_or_find_extremes(first, last, max, min, rshift)) return; unsigned log_divisor = get_log_divisor<float_log_mean_bin_size>( last - first, rough_log_2_size(Size_type(max - min))); Div_type div_min = min >> log_divisor; Div_type div_max = max >> log_divisor; unsigned bin_count = unsigned(div_max - div_min) + 1; unsigned cache_end; RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count); //Calculating the size of each bin for (RandomAccessIter current = first; current != last;) bin_sizes[unsigned(rshift(*(current++), log_divisor) - div_min)]++; //The index of the first positive bin unsigned first_positive = (div_min < 0) ? static_cast<unsigned>(-div_min) : 0; //Resetting if all bins are negative if (cache_offset + first_positive > cache_end) first_positive = cache_end - cache_offset; //Reversing the order of the negative bins //Note that because of the negative/positive ordering direction flip //We can not depend upon bin order and positions matching up //so bin_sizes must be reused to contain the end of the bin if (first_positive > 0) { bins[first_positive - 1] = first; for (int ii = first_positive - 2; ii >= 0; --ii) { bins[ii] = first + bin_sizes[ii + 1]; bin_sizes[ii] += bin_sizes[ii + 1]; } //Handling positives following negatives if (static_cast<unsigned>(first_positive) < bin_count) { bins[first_positive] = first + bin_sizes[0]; bin_sizes[first_positive] += bin_sizes[0]; } } else bins[0] = first; for (unsigned u = first_positive; u < bin_count - 1; u++) { bins[u + 1] = first + bin_sizes[u]; bin_sizes[u + 1] += bin_sizes[u]; } //Swap into place RandomAccessIter next_bin_start = first; for (unsigned u = 0; u < bin_count; ++u) { next_bin_start = first + bin_sizes[u]; inner_swap_loop<RandomAccessIter, Div_type, Right_shift> (bins, next_bin_start, u, rshift, log_divisor, div_min); } //Return if we've completed bucketsorting if (!log_divisor) return; //Handling negative values first size_t max_count = get_min_count<float_log_mean_bin_size, float_log_min_split_count, float_log_finishing_count>(log_divisor); RandomAccessIter lastPos = first; for (int ii = cache_offset + first_positive - 1; ii >= static_cast<int>(cache_offset); lastPos = bin_cache[ii--]) { size_t count = bin_cache[ii] - lastPos; if (count < 2) continue; if (count < max_count) std::sort(lastPos, bin_cache[ii], comp); //sort negative values using reversed-bin spreadsort else negative_float_sort_rec<RandomAccessIter, Div_type, Right_shift, Compare, Size_type>(lastPos, bin_cache[ii], bin_cache, cache_end, bin_sizes, rshift, comp); } for (unsigned u = cache_offset + first_positive; u < cache_end; lastPos = bin_cache[u], ++u) { size_t count = bin_cache[u] - lastPos; if (count < 2) continue; if (count < max_count) std::sort(lastPos, bin_cache[u], comp); //sort positive values using normal spreadsort else spreadsort_rec<RandomAccessIter, Div_type, Right_shift, Compare, Size_type, float_log_mean_bin_size, float_log_min_split_count, float_log_finishing_count> (lastPos, bin_cache[u], bin_cache, cache_end, bin_sizes, rshift, comp); } }