Skip to content
This repository
Browse code

Switch priority queue to using std::merge for merging sequences rathe…

…r than just sorting two sorted sequences
  • Loading branch information...
commit 800c05f6a9212b0aacf43f4170d64b01f9d1c566 1 parent cb8d651
Mathias Rav Mortal authored

Showing 2 changed files with 72 additions and 37 deletions. Show diff stats Hide diff stats

  1. +59 0 tpie/priority_queue.h
  2. +13 37 tpie/priority_queue.inl
59 tpie/priority_queue.h
@@ -198,6 +198,65 @@ class priority_queue {
198 198 * in memory. */
199 199 tpie::array<T> gbuffer0;
200 200
  201 + class cyclic_array_iterator : public boost::iterator_facade<cyclic_array_iterator, T, boost::random_access_traversal_tag> {
  202 + tpie::array<T> & arr;
  203 + memory_size_type idx;
  204 + memory_size_type first;
  205 +
  206 + public:
  207 + cyclic_array_iterator(tpie::array<T> & arr, memory_size_type idx, memory_size_type first)
  208 + : arr(arr), idx(idx % arr.size()), first(first)
  209 + {
  210 + }
  211 +
  212 + private:
  213 + friend class boost::iterator_core_access;
  214 + T & dereference() const {
  215 + return arr[idx];
  216 + }
  217 + void increment() {
  218 + if (idx+1 == arr.size()) idx = 0;
  219 + else ++idx;
  220 + }
  221 + void decrement() {
  222 + if (idx == 0) idx = arr.size() - 1;
  223 + else --idx;
  224 + }
  225 + void advance(memory_size_type n) {
  226 + idx = (idx + n) % arr.size();
  227 + }
  228 + memory_size_type from_beginning() const {
  229 + return (idx < first) ? (idx + arr.size() - first) : (idx - first);
  230 + }
  231 + memory_offset_type distance_to(const cyclic_array_iterator & other) const {
  232 + return static_cast<memory_offset_type>(other.from_beginning())
  233 + -static_cast<memory_offset_type>(from_beginning());
  234 + }
  235 + bool equal(const cyclic_array_iterator & other) const {
  236 + return idx == other.idx;
  237 + }
  238 + };
  239 +
  240 + template <typename IT>
  241 + void assert_sorted(IT i, IT j, memory_size_type n) {
  242 + if (j-i != n) {
  243 + log_error() << "Bad distance" << std::endl;
  244 + }
  245 + IT k = i;
  246 + ++k;
  247 + --n;
  248 + while (k != j) {
  249 + if (comp_(*k, *i)) {
  250 + log_error() << "Not a sorted sequence" << std::endl;
  251 + }
  252 + ++k, ++i;
  253 + --n;
  254 + }
  255 + if (n != 0) {
  256 + log_error() << "Bad steps" << std::endl;
  257 + }
  258 + }
  259 +
201 260 /** 2*(#slots) integers. Slot i contains its elements in cyclic ascending order,
202 261 * starting at index slot_state[2*i]. Slot i contains slot_state[2*i+1] elements.
203 262 * Its data is in data file i. */
50 tpie/priority_queue.inl
@@ -246,15 +246,10 @@ void priority_queue<T, Comparator>::push(const T& x) {
246 246
247 247 // Bubble lesser elements down into deletion buffer
248 248 if(buffer_size > 0) {
249   -
250   - // fetch insertion buffer
251   - std::copy(arr.begin(), arr.end(), mergebuffer.begin());
252   -
253   - // fetch deletion buffer
254   - std::copy(buffer.find(buffer_start), buffer.find(buffer_start+buffer_size), mergebuffer.find(setting_m));
255   -
256   - // sort buffer elements
257   - parallel_sort(mergebuffer.begin(), mergebuffer.find(buffer_size+setting_m), comp_);
  249 + // merge deletion and insertion buffer
  250 + std::merge(buffer.find(buffer_start), buffer.find(buffer_start + buffer_size),
  251 + arr.begin(), arr.end(),
  252 + mergebuffer.begin(), comp_);
258 253
259 254 // smaller elements go in deletion buffer
260 255 std::copy(mergebuffer.begin(), mergebuffer.find(buffer_size), buffer.find(buffer_start));
@@ -268,19 +263,11 @@ void priority_queue<T, Comparator>::push(const T& x) {
268 263
269 264 // Merge insertion buffer and group buffer 0
270 265 assert(group_state[0].size+setting_m <= setting_m*2);
271   - memory_size_type j = 0;
272   -
273   - // fetch gbuffer0
274   - for(stream_size_type i = group_state[0].start; i < group_state[0].start+group_state[0].size; i++) {
275   - mergebuffer[j] = gbuffer0[static_cast<memory_size_type>(i%setting_m)];
276   - ++j;
277   - }
278 266
279   - // fetch insertion buffer
280   - std::copy(arr.begin(), arr.find(setting_m), mergebuffer.find(j));
281   -
282   - // sort
283   - parallel_sort(mergebuffer.get(), mergebuffer.get()+(group_state[0].size+setting_m), comp_);
  267 + std::merge(cyclic_array_iterator(gbuffer0, group_state[0].start, group_state[0].start),
  268 + cyclic_array_iterator(gbuffer0, group_state[0].start + group_state[0].size, group_state[0].start),
  269 + arr.begin(), arr.end(),
  270 + mergebuffer.begin(), comp_);
284 271
285 272 // smaller elements go in gbuffer0
286 273 std::copy(mergebuffer.begin(), mergebuffer.find(group_state[0].size), gbuffer0.begin());
@@ -890,22 +877,11 @@ void priority_queue<T, Comparator>::remove_group_buffer(group_type group) {
890 877 // merge group buffer with group buffer 0
891 878 array<T> mergebuffer(group_state[0].size + group_state[group].size);
892 879
893   - if (group_state[0].start + group_state[0].size <= setting_m) {
894   - std::copy(gbuffer0.find(group_state[0].start),
895   - gbuffer0.find(group_state[0].start + group_state[0].size),
896   - mergebuffer.begin());
897   - } else {
898   - memory_size_type first_read = setting_m - group_state[0].start;
899   - memory_size_type second_read = group_state[0].size - first_read;
900   - std::copy(gbuffer0.find(group_state[0].start),
901   - gbuffer0.find(group_state[0].start + first_read),
902   - mergebuffer.begin());
903   - std::copy(gbuffer0.begin(),
904   - gbuffer0.find(second_read),
905   - mergebuffer.find(first_read));
906   - }
907   - std::copy(arr.begin(), arr.find(group_state[group].size), mergebuffer.find(group_state[0].size));
908   - parallel_sort(mergebuffer.begin(), mergebuffer.find(group_state[0].size + group_state[group].size), comp_);
  880 + std::merge(cyclic_array_iterator(gbuffer0, group_state[0].start, group_state[0].start),
  881 + cyclic_array_iterator(gbuffer0, group_state[0].start + group_state[0].size, group_state[0].start),
  882 + arr.begin(), arr.find(group_state[group].size),
  883 + mergebuffer.begin(), comp_);
  884 +
909 885 std::copy(mergebuffer.begin(), mergebuffer.find(group_state[0].size), gbuffer0.begin());
910 886 group_state[0].start = 0;
911 887 std::copy(mergebuffer.find(group_state[0].size), mergebuffer.find(group_state[0].size + group_state[group].size), arr.begin());

0 comments on commit 800c05f

Please sign in to comment.
Something went wrong with that request. Please try again.