15 #ifndef STXXL_SORT_HEADER
16 #define STXXL_SORT_HEADER
20 #include <stxxl/bits/mng/mng.h>
21 #include <stxxl/bits/common/rand.h>
22 #include <stxxl/bits/mng/adaptor.h>
23 #include <stxxl/bits/common/simple_vector.h>
25 #include <stxxl/bits/mng/block_alloc_interleaved.h>
26 #include <stxxl/bits/io/request_operations.h>
27 #include <stxxl/bits/algo/sort_base.h>
28 #include <stxxl/bits/algo/sort_helper.h>
29 #include <stxxl/bits/algo/intksort.h>
30 #include <stxxl/bits/algo/adaptor.h>
31 #include <stxxl/bits/algo/async_schedule.h>
32 #include <stxxl/bits/mng/block_prefetcher.h>
33 #include <stxxl/bits/mng/buf_writer.h>
34 #include <stxxl/bits/algo/run_cursor.h>
35 #include <stxxl/bits/algo/losertree.h>
36 #include <stxxl/bits/algo/inmemsort.h>
37 #include <stxxl/bits/parallel.h>
38 #include <stxxl/bits/common/is_sorted.h>
41 __STXXL_BEGIN_NAMESPACE
51 template <
typename block_type,
typename b
id_type>
52 struct read_next_after_write_completed
59 *req = block->read(bid);
67 typename input_bid_iterator,
71 input_bid_iterator it,
77 typedef typename block_type::value_type type;
78 typedef typename block_type::bid_type bid_type;
79 STXXL_VERBOSE1(
"stxxl::create_runs nruns=" << nruns <<
" m=" << _m);
83 block_type * Blocks1 =
new block_type[m2];
84 block_type * Blocks2 =
new block_type[m2];
85 bid_type * bids1 =
new bid_type[m2];
86 bid_type * bids2 =
new bid_type[m2];
90 read_next_after_write_completed<block_type, bid_type> * next_run_reads =
91 new read_next_after_write_completed<block_type, bid_type>[m2];
93 disk_queues::get_instance()->set_priority_op(request_queue::WRITE);
96 int_type run_size = 0;
100 run_size = runs[0]->size();
101 assert(run_size == m2);
103 for (i = 0; i < run_size; ++i)
105 STXXL_VERBOSE1(
"stxxl::create_runs posting read " <<
long(Blocks1[i].elem));
107 read_reqs1[i] = Blocks1[i].read(bids1[i]);
110 run_size = runs[1]->size();
112 for (i = 0; i < run_size; ++i)
114 STXXL_VERBOSE1(
"stxxl::create_runs posting read " <<
long(Blocks2[i].elem));
116 read_reqs2[i] = Blocks2[i].read(bids2[i]);
119 for (int_type k = 0; k < nruns - 1; ++k)
121 run_type * run = runs[k];
122 run_size = run->size();
123 assert(run_size == m2);
125 int_type next_run_size = runs[k + 1]->size();
127 assert((next_run_size == m2) || (next_run_size <= m2 && k == nruns - 2));
129 STXXL_VERBOSE1(
"stxxl::create_runs start waiting read_reqs1");
131 STXXL_VERBOSE1(
"stxxl::create_runs finish waiting read_reqs1");
132 for (i = 0; i < run_size; ++i)
136 sort(make_element_iterator(Blocks1, 0),
137 make_element_iterator(Blocks1, run_size * block_type::size),
140 STXXL_VERBOSE1(
"stxxl::create_runs start waiting write_reqs");
143 STXXL_VERBOSE1(
"stxxl::create_runs finish waiting write_reqs");
145 int_type runplus2size = (k < nruns - 2) ? runs[k + 2]->size() : 0;
146 for (i = 0; i < m2; ++i)
148 STXXL_VERBOSE1(
"stxxl::create_runs posting write " <<
long(Blocks1[i].elem));
149 (*run)[i].value = Blocks1[i][0];
150 if (i >= runplus2size) {
151 write_reqs[i] = Blocks1[i].write((*run)[i].bid);
155 next_run_reads[i].block = Blocks1 + i;
156 next_run_reads[i].req = read_reqs1 + i;
157 bids1[i] = next_run_reads[i].bid = *(it++);
158 write_reqs[i] = Blocks1[i].write((*run)[i].bid, next_run_reads[i]);
161 std::swap(Blocks1, Blocks2);
162 std::swap(bids1, bids2);
163 std::swap(read_reqs1, read_reqs2);
166 run_type * run = runs[nruns - 1];
167 run_size = run->size();
168 STXXL_VERBOSE1(
"stxxl::create_runs start waiting read_reqs1");
170 STXXL_VERBOSE1(
"stxxl::create_runs finish waiting read_reqs1");
171 for (i = 0; i < run_size; ++i)
175 sort(make_element_iterator(Blocks1, 0),
176 make_element_iterator(Blocks1, run_size * block_type::size),
179 STXXL_VERBOSE1(
"stxxl::create_runs start waiting write_reqs");
181 STXXL_VERBOSE1(
"stxxl::create_runs finish waiting write_reqs");
183 for (i = 0; i < run_size; ++i)
185 STXXL_VERBOSE1(
"stxxl::create_runs posting write " <<
long(Blocks1[i].elem));
186 (*run)[i].value = Blocks1[i][0];
187 write_reqs[i] = Blocks1[i].write((*run)[i].bid);
190 STXXL_VERBOSE1(
"stxxl::create_runs start waiting write_reqs");
192 STXXL_VERBOSE1(
"stxxl::create_runs finish waiting write_reqs");
201 delete[] next_run_reads;
205 template <
typename block_type,
typename run_type,
typename value_cmp>
206 bool check_sorted_runs(run_type ** runs,
211 typedef typename block_type::value_type value_type;
213 STXXL_MSG(
"check_sorted_runs Runs: " << nruns);
214 unsigned_type irun = 0;
215 for (irun = 0; irun < nruns; ++irun)
217 const unsigned_type nblocks_per_run = runs[irun]->size();
218 unsigned_type blocks_left = nblocks_per_run;
219 block_type * blocks =
new block_type[m];
221 value_type last = cmp.min_value();
223 for (unsigned_type off = 0; off < nblocks_per_run; off += m)
225 const unsigned_type nblocks = STXXL_MIN(blocks_left, m);
226 const unsigned_type nelements = nblocks * block_type::size;
227 blocks_left -= nblocks;
229 for (unsigned_type j = 0; j < nblocks; ++j)
231 reqs[j] = blocks[j].read((*runs[irun])[j + off].bid);
235 if (off && cmp(blocks[0][0], last))
237 STXXL_MSG(
"check_sorted_runs wrong first value in the run " << irun);
238 STXXL_MSG(
" first value: " << blocks[0][0]);
239 STXXL_MSG(
" last value: " << last);
240 for (unsigned_type k = 0; k < block_type::size; ++k)
241 STXXL_MSG(
"Element " << k <<
" in the block is :" << blocks[0][k]);
246 for (unsigned_type j = 0; j < nblocks; ++j)
248 if (!(blocks[j][0] == (*runs[irun])[j + off].value))
250 STXXL_MSG(
"check_sorted_runs wrong trigger in the run " << irun <<
" block " << (j + off));
251 STXXL_MSG(
" trigger value: " << (*runs[irun])[j + off].value);
252 STXXL_MSG(
"Data in the block:");
253 for (unsigned_type k = 0; k < block_type::size; ++k)
254 STXXL_MSG(
"Element " << k <<
" in the block is :" << blocks[j][k]);
257 for (unsigned_type k = 0; k < nblocks; ++k)
260 STXXL_MSG(
"Bad one comes next.");
261 STXXL_MSG(
"BID " << (k + off) <<
" is: " << ((*runs[irun])[k + off].bid));
267 if (!stxxl::is_sorted(make_element_iterator(blocks, 0),
268 make_element_iterator(blocks, nelements),
271 STXXL_MSG(
"check_sorted_runs wrong order in the run " << irun);
272 STXXL_MSG(
"Data in blocks:");
273 for (unsigned_type j = 0; j < nblocks; ++j)
275 for (unsigned_type k = 0; k < block_type::size; ++k)
276 STXXL_MSG(
" Element " << k <<
" in block " << (j + off) <<
" is :" << blocks[j][k]);
279 for (unsigned_type k = 0; k < nblocks; ++k)
281 STXXL_MSG(
"BID " << (k + off) <<
" is: " << ((*runs[irun])[k + off].bid));
287 last = blocks[nblocks - 1][block_type::size - 1];
290 assert(blocks_left == 0);
299 template <
typename block_type,
typename run_type,
typename value_cmp>
300 void merge_runs(run_type ** in_runs, int_type nruns, run_type * out_run, unsigned_type _m, value_cmp cmp)
302 typedef typename block_type::value_type value_type;
303 typedef typename run_type::value_type trigger_entry_type;
305 typedef run_cursor2<block_type, prefetcher_type> run_cursor_type;
306 typedef sort_helper::run_cursor2_cmp<block_type, prefetcher_type, value_cmp> run_cursor2_cmp_type;
308 run_type consume_seq(out_run->size());
310 int_type * prefetch_seq =
new int_type[out_run->size()];
312 typename run_type::iterator copy_start = consume_seq.begin();
313 for (int_type i = 0; i < nruns; i++)
316 copy_start = std::copy(
322 std::stable_sort(consume_seq.begin(), consume_seq.end(),
323 sort_helper::trigger_entry_cmp<trigger_entry_type, value_cmp>(cmp) _STXXL_SORT_TRIGGER_FORCE_SEQUENTIAL);
325 int_type disks_number = config::get_instance()->disks_number();
327 #ifdef PLAY_WITH_OPT_PREF
328 const int_type n_write_buffers = 4 * disks_number;
330 const int_type n_prefetch_buffers = STXXL_MAX(2 * disks_number, (3 * (int_type(_m) - nruns) / 4));
331 const int_type n_write_buffers = STXXL_MAX(2 * disks_number, int_type(_m) - nruns - n_prefetch_buffers);
332 #if STXXL_SORT_OPTIMAL_PREFETCHING
334 const int_type n_opt_prefetch_buffers = 2 * disks_number + (3 * (n_prefetch_buffers - 2 * disks_number)) / 10;
338 #if STXXL_SORT_OPTIMAL_PREFETCHING
339 compute_prefetch_schedule(
342 n_opt_prefetch_buffers,
345 for (unsigned_type i = 0; i < out_run->size(); i++)
350 prefetcher_type prefetcher(consume_seq.begin(),
353 nruns + n_prefetch_buffers);
357 int_type out_run_size = out_run->size();
359 block_type * out_buffer = writer.get_free_block();
364 if (do_parallel_merge())
366 #if STXXL_PARALLEL_MULTIWAY_MERGE
370 typedef stxxl::int64 diff_type;
371 typedef std::pair<typename block_type::iterator, typename block_type::iterator> sequence;
372 typedef typename std::vector<sequence>::size_type seqs_size_type;
373 std::vector<sequence> seqs(nruns);
374 std::vector<block_type *> buffers(nruns);
376 for (int_type i = 0; i < nruns; i++)
378 buffers[i] = prefetcher.pull_block();
379 seqs[i] = std::make_pair(buffers[i]->begin(), buffers[i]->end());
383 #if STXXL_CHECK_ORDER_IN_SORTS
384 value_type last_elem = cmp.min_value();
386 diff_type num_currently_mergeable = 0;
388 for (int_type j = 0; j < out_run_size; ++j)
390 diff_type rest = block_type::size;
392 STXXL_VERBOSE1(
"output block " << j);
394 if (num_currently_mergeable < rest)
396 if (prefetcher.empty())
399 num_currently_mergeable = (out_run_size - j) * block_type::size
400 - (block_type::size - rest);
404 num_currently_mergeable = sort_helper::count_elements_less_equal(
405 seqs, consume_seq[prefetcher.pos()].value, cmp);
409 diff_type output_size = STXXL_MIN(num_currently_mergeable, rest);
411 STXXL_VERBOSE1(
"before merge " << output_size);
413 stxxl::parallel::multiway_merge(seqs.begin(), seqs.end(), out_buffer->end() - rest, cmp, output_size);
417 num_currently_mergeable -= output_size;
419 STXXL_VERBOSE1(
"after merge");
421 sort_helper::refill_or_remove_empty_sequences(seqs, buffers, prefetcher);
422 }
while (rest > 0 && seqs.size() > 0);
424 #if STXXL_CHECK_ORDER_IN_SORTS
425 if (!stxxl::is_sorted(out_buffer->begin(), out_buffer->end(), cmp))
427 for (value_type * i = out_buffer->begin() + 1; i != out_buffer->end(); i++)
428 if (cmp(*i, *(i - 1)))
430 STXXL_VERBOSE1(
"Error at position " << (i - out_buffer->begin()));
436 assert(cmp((*out_buffer)[0], last_elem) ==
false);
438 last_elem = (*out_buffer)[block_type::size - 1];
441 (*out_run)[j].value = (*out_buffer)[0];
443 out_buffer = writer.write(out_buffer, (*out_run)[j].bid);
449 STXXL_THROW_UNREACHABLE();
456 loser_tree<run_cursor_type, run_cursor2_cmp_type>
457 losers(&prefetcher, nruns, run_cursor2_cmp_type(cmp));
459 #if STXXL_CHECK_ORDER_IN_SORTS
460 value_type last_elem = cmp.min_value();
463 for (int_type i = 0; i < out_run_size; ++i)
465 losers.multi_merge(out_buffer->elem, out_buffer->elem + block_type::size);
466 (*out_run)[i].value = *(out_buffer->elem);
468 #if STXXL_CHECK_ORDER_IN_SORTS
469 assert(stxxl::is_sorted(
475 assert(cmp(*(out_buffer->elem), last_elem) ==
false);
477 last_elem = (*out_buffer).elem[block_type::size - 1];
480 out_buffer = writer.write(out_buffer, (*out_run)[i].bid);
486 delete[] prefetch_seq;
489 for (int_type i = 0; i < nruns; ++i)
491 unsigned_type sz = in_runs[i]->size();
492 for (unsigned_type j = 0; j < sz; ++j)
501 template <
typename block_type,
502 typename alloc_strategy,
503 typename input_bid_iterator,
505 simple_vector<sort_helper::trigger_entry<block_type> > *
506 sort_blocks(input_bid_iterator input_bids,
512 typedef typename block_type::value_type type;
513 typedef typename block_type::bid_type bid_type;
514 typedef sort_helper::trigger_entry<block_type> trigger_entry_type;
515 typedef simple_vector<trigger_entry_type> run_type;
516 typedef typename interleaved_alloc_traits<alloc_strategy>::strategy interleaved_alloc_strategy;
518 unsigned_type m2 = _m / 2;
519 unsigned_type full_runs = _n / m2;
520 unsigned_type partial_runs = ((_n % m2) ? 1 : 0);
521 unsigned_type nruns = full_runs + partial_runs;
528 double begin = timestamp(), after_runs_creation, end;
530 run_type ** runs =
new run_type *[nruns];
532 for (i = 0; i < full_runs; i++)
533 runs[i] =
new run_type(m2);
537 runs[i] =
new run_type(_n - full_runs * m2);
539 for (i = 0; i < nruns; ++i)
540 mng->
new_blocks(alloc_strategy(), make_bid_iterator(runs[i]->begin()), make_bid_iterator(runs[i]->end()));
542 sort_local::create_runs<block_type,
545 value_cmp>(input_bids, runs, nruns, _m, cmp);
547 after_runs_creation = timestamp();
549 double io_wait_after_rf = stats::get_instance()->get_io_wait_time();
551 disk_queues::get_instance()->set_priority_op(request_queue::WRITE);
553 const int_type merge_factor = optimal_merge_factor(nruns, _m);
554 run_type ** new_runs;
558 int_type new_nruns = div_ceil(nruns, merge_factor);
559 STXXL_VERBOSE(
"Starting new merge phase: nruns: " << nruns <<
560 " opt_merge_factor: " << merge_factor <<
" m:" << _m <<
" new_nruns: " << new_nruns);
562 new_runs =
new run_type *[new_nruns];
564 int_type runs_left = nruns;
565 int_type cur_out_run = 0;
566 int_type blocks_in_new_run = 0;
568 while (runs_left > 0)
570 int_type runs2merge = STXXL_MIN(runs_left, merge_factor);
571 blocks_in_new_run = 0;
572 for (unsigned_type i = nruns - runs_left; i < (nruns - runs_left + runs2merge); i++)
573 blocks_in_new_run += runs[i]->size();
576 new_runs[cur_out_run++] =
new run_type(blocks_in_new_run);
577 runs_left -= runs2merge;
580 if (cur_out_run == 1 && blocks_in_new_run == int_type(_n) && !input_bids->is_managed())
583 input_bid_iterator cur = input_bids;
584 for (int_type i = 0; cur != (input_bids + _n); ++cur)
586 (*new_runs[0])[i++].bid = *cur;
589 bid_type & firstBID = (*new_runs[0])[0].bid;
590 if (firstBID.is_managed())
596 bid_type & lastBID = (*new_runs[0])[_n - 1].bid;
597 if (lastBID.is_managed())
606 mng->
new_blocks(interleaved_alloc_strategy(new_nruns, alloc_strategy()),
607 RunsToBIDArrayAdaptor2<block_type::raw_size, run_type>(new_runs, 0, new_nruns, blocks_in_new_run),
608 RunsToBIDArrayAdaptor2<block_type::raw_size, run_type>(new_runs, _n, new_nruns, blocks_in_new_run));
613 while (runs_left > 0)
615 int_type runs2merge = STXXL_MIN(runs_left, merge_factor);
616 #if STXXL_CHECK_ORDER_IN_SORTS
617 assert((check_sorted_runs<block_type, run_type, value_cmp>(runs + nruns - runs_left, runs2merge, m2, cmp)));
619 STXXL_VERBOSE(
"Merging " << runs2merge <<
" runs");
620 merge_runs<block_type, run_type>(runs + nruns - runs_left,
621 runs2merge, *(new_runs + (cur_out_run++)), _m, cmp
623 runs_left -= runs2merge;
631 run_type * result = *runs;
636 STXXL_VERBOSE(
"Elapsed time : " << end - begin <<
" s. Run creation time: " <<
637 after_runs_creation - begin <<
" s");
638 STXXL_VERBOSE(
"Time in I/O wait(rf): " << io_wait_after_rf <<
" s");
639 STXXL_VERBOSE(*stats::get_instance());
640 STXXL_UNUSED(begin + after_runs_creation + end + io_wait_after_rf);
692 template <
typename ExtIterator_,
typename StrictWeakOrdering_>
700 void sort(ExtIterator_ first, ExtIterator_ last, StrictWeakOrdering_ cmp, unsigned_type M)
702 sort_helper::verify_sentinel_strict_weak_ordering(cmp);
704 typedef simple_vector<sort_helper::trigger_entry<typename ExtIterator_::block_type> > run_type;
706 typedef typename ExtIterator_::vector_type::value_type value_type;
707 typedef typename ExtIterator_::block_type block_type;
715 if ((last - first) *
sizeof(value_type) * sort_memory_usage_factor() < M)
717 stl_in_memory_sort(first, last, cmp);
721 if (!(2 * block_type::raw_size * sort_memory_usage_factor() <= M)) {
722 throw bad_parameter(
"stxxl::sort(): INSUFFICIENT MEMORY provided, please increase parameter 'M'");
725 if (first.block_offset())
727 if (last.block_offset())
730 typename ExtIterator_::block_type * first_block =
new typename ExtIterator_::block_type;
731 typename ExtIterator_::block_type * last_block =
new typename ExtIterator_::block_type;
732 typename ExtIterator_::bid_type first_bid, last_bid;
735 req = first_block->read(*first.bid());
741 req = last_block->read(*last.bid());
744 for ( ; i < first.block_offset(); ++i)
746 first_block->elem[i] = cmp.min_value();
752 req = first_block->write(first_bid);
753 for (i = last.block_offset(); i < block_type::size; ++i)
755 last_block->elem[i] = cmp.max_value();
761 req = last_block->write(last_bid);
763 n = last.bid() - first.bid() + 1;
765 std::swap(first_bid, *first.bid());
766 std::swap(last_bid, *last.bid());
775 sort_local::sort_blocks<
776 typename ExtIterator_::block_type,
777 typename ExtIterator_::vector_type::alloc_strategy_type,
778 typename ExtIterator_::bids_container_iterator>
779 (first.bid(), n, M / sort_memory_usage_factor() / block_type::raw_size, cmp);
782 first_block =
new typename ExtIterator_::block_type;
783 last_block =
new typename ExtIterator_::block_type;
784 typename ExtIterator_::block_type * sorted_first_block =
new typename ExtIterator_::block_type;
785 typename ExtIterator_::block_type * sorted_last_block =
new typename ExtIterator_::block_type;
788 reqs[0] = first_block->read(first_bid);
789 reqs[1] = sorted_first_block->read((*(out->begin())).bid);
794 reqs[0] = last_block->read(last_bid);
795 reqs[1] = sorted_last_block->read(((*out)[out->size() - 1]).bid);
797 for (i = first.block_offset(); i < block_type::size; i++)
799 first_block->elem[i] = sorted_first_block->elem[i];
805 req = first_block->write(first_bid);
807 for (i = 0; i < last.block_offset(); ++i)
809 last_block->elem[i] = sorted_last_block->elem[i];
814 req = last_block->write(last_bid);
819 *first.bid() = first_bid;
820 *last.bid() = last_bid;
822 typename run_type::iterator it = out->begin();
824 typename ExtIterator_::bids_container_iterator cur_bid = first.bid();
827 for ( ; cur_bid != last.bid(); ++cur_bid, ++it)
829 *cur_bid = (*it).bid;
833 delete sorted_first_block;
834 delete sorted_last_block;
847 typename ExtIterator_::block_type * first_block =
new typename ExtIterator_::block_type;
848 typename ExtIterator_::bid_type first_bid;
851 req = first_block->read(*first.bid());
857 for ( ; i < first.block_offset(); ++i)
859 first_block->elem[i] = cmp.min_value();
862 req = first_block->write(first_bid);
864 n = last.bid() - first.bid();
866 std::swap(first_bid, *first.bid());
874 sort_local::sort_blocks<
875 typename ExtIterator_::block_type,
876 typename ExtIterator_::vector_type::alloc_strategy_type,
877 typename ExtIterator_::bids_container_iterator>
878 (first.bid(), n, M / sort_memory_usage_factor() / block_type::raw_size, cmp);
881 first_block =
new typename ExtIterator_::block_type;
883 typename ExtIterator_::block_type * sorted_first_block =
new typename ExtIterator_::block_type;
887 reqs[0] = first_block->read(first_bid);
888 reqs[1] = sorted_first_block->read((*(out->begin())).bid);
893 for (i = first.block_offset(); i < block_type::size; ++i)
895 first_block->elem[i] = sorted_first_block->elem[i];
898 req = first_block->write(first_bid);
902 *first.bid() = first_bid;
904 typename run_type::iterator it = out->begin();
906 typename ExtIterator_::bids_container_iterator cur_bid = first.bid();
909 for ( ; cur_bid != last.bid(); ++cur_bid, ++it)
911 *cur_bid = (*it).bid;
914 *cur_bid = (*it).bid;
916 delete sorted_first_block;
927 if (last.block_offset())
930 typename ExtIterator_::block_type * last_block =
new typename ExtIterator_::block_type;
931 typename ExtIterator_::bid_type last_bid;
935 req = last_block->read(*last.bid());
940 for (i = last.block_offset(); i < block_type::size; ++i)
942 last_block->elem[i] = cmp.max_value();
945 req = last_block->write(last_bid);
947 n = last.bid() - first.bid() + 1;
949 std::swap(last_bid, *last.bid());
957 sort_local::sort_blocks<
958 typename ExtIterator_::block_type,
959 typename ExtIterator_::vector_type::alloc_strategy_type,
960 typename ExtIterator_::bids_container_iterator>
961 (first.bid(), n, M / sort_memory_usage_factor() / block_type::raw_size, cmp);
964 last_block =
new typename ExtIterator_::block_type;
965 typename ExtIterator_::block_type * sorted_last_block =
new typename ExtIterator_::block_type;
968 reqs[0] = last_block->read(last_bid);
969 reqs[1] = sorted_last_block->read(((*out)[out->size() - 1]).bid);
974 for (i = 0; i < last.block_offset(); ++i)
976 last_block->elem[i] = sorted_last_block->elem[i];
979 req = last_block->write(last_bid);
983 *last.bid() = last_bid;
985 typename run_type::iterator it = out->begin();
986 typename ExtIterator_::bids_container_iterator cur_bid = first.bid();
988 for ( ; cur_bid != last.bid(); ++cur_bid, ++it)
990 *cur_bid = (*it).bid;
993 delete sorted_last_block;
1004 n = last.bid() - first.bid();
1007 sort_local::sort_blocks<
typename ExtIterator_::block_type,
1008 typename ExtIterator_::vector_type::alloc_strategy_type,
1009 typename ExtIterator_::bids_container_iterator>
1010 (first.bid(), n, M / sort_memory_usage_factor() / block_type::raw_size, cmp);
1012 typename run_type::iterator it = out->begin();
1013 typename ExtIterator_::bids_container_iterator cur_bid = first.bid();
1015 for ( ; cur_bid != last.bid(); ++cur_bid, ++it)
1017 *cur_bid = (*it).bid;
1025 #if STXXL_CHECK_ORDER_IN_SORTS
1026 typedef typename ExtIterator_::const_iterator const_iterator;
1027 assert(stxxl::is_sorted(const_iterator(first), const_iterator(last), cmp));
1033 __STXXL_END_NAMESPACE
1035 #endif // !STXXL_SORT_HEADER
fully randomized disk allocation scheme functor
Definition: block_alloc.h:69
Encapsulates asynchronous buffered block writing engine.
Definition: buf_writer.h:37
void sort(ExtIterator_ first, ExtIterator_ last, StrictWeakOrdering_ cmp, unsigned_type M)
Sort records comparison-based.
Definition: sort.h:700
Request with basic properties like file and offset.
Definition: request.h:39
void new_blocks(const DiskAssignFunctor &functor, BIDIteratorClass bidbegin, BIDIteratorClass bidend, unsigned_type offset=0)
Allocates new blocks.
Definition: mng.h:90
Implemented as reference counting smart pointer.
Definition: request_ptr.h:34
Encapsulates asynchronous prefetching engine.
Definition: block_prefetcher.h:54
void wait_all(request_iterator_ reqs_begin, request_iterator_ reqs_end)
Collection of functions to track statuses of a number of requests.
Definition: request_operations.h:36
void new_block(const DiskAssignFunctor &functor, BID< BLK_SIZE > &bid, unsigned_type offset=0)
Definition: mng.h:131
Provides a static class to store runtime tuning parameters.
void delete_block(const BID< BLK_SIZE > &bid)
Deallocates a block.
Definition: mng.h:204
virtual void wait(bool measure_time=true)=0
Suspends calling thread until completion of the request.
Block manager class.
Definition: mng.h:59