15 #ifndef STXXL_ALGO_RANDOM_SHUFFLE_HEADER
16 #define STXXL_ALGO_RANDOM_SHUFFLE_HEADER
44 template <
typename ExtIterator_,
45 typename RandomNumberGenerator_,
48 typename AllocStrategy_>
51 RandomNumberGenerator_& rand,
56 typedef typename ExtIterator_::value_type value_type;
59 BlockSize_, void, 0, AllocStrategy_>::result stack_type;
60 typedef typename stack_type::block_type block_type;
63 STXXL_STATIC_ASSERT(
int(BlockSize_) < 0 &&
"This implementation was never tested. Please report to the stxxl developers if you have an ExtIterator_ that works with this implementation.");
68 if (M < 6 * BlockSize_ + PageSize_ * BlockSize_) {
69 STXXL_ERRMSG(
"random_shuffle: insufficient memory, " << M <<
" bytes supplied,");
70 M = 6 * BlockSize_ + PageSize_ * BlockSize_;
71 STXXL_ERRMSG(
"random_shuffle: increasing to " << M <<
" bytes (6 blocks + 1 page)");
79 value_type* temp_array;
81 PageSize_, 4, BlockSize_, AllocStrategy_>::result temp_vector_type;
82 temp_vector_type* temp_vector;
84 STXXL_VERBOSE1(
"random_shuffle: " << M / BlockSize_ - k <<
" write buffers for " << k <<
" buckets");
90 buckets =
new stack_type*[k];
91 for (j = 0; j < k; j++)
92 buckets[j] =
new stack_type(pool, 0);
101 for (i = 0; i < n; ++i) {
102 random_bucket = rand(k);
103 buckets[random_bucket]->push(*in);
113 PageSize_ * BlockSize_;
114 ExtIterator_ Writer = first;
115 ExtIterator_ it = first;
117 for (i = 0; i < k; i++) {
118 STXXL_VERBOSE1(
"random_shuffle: bucket no " << i <<
" contains " << buckets[i]->size() <<
" elements");
122 for (i = 0; i < k; i++) {
123 buckets[i]->set_prefetch_aggr(PageSize_);
124 size = buckets[i]->size();
127 if (size *
sizeof(value_type) < space_left) {
131 temp_array =
new value_type[size];
132 for (j = 0; j < size; j++) {
133 temp_array[j] = buckets[i]->top();
142 for (j = 0; j < size; j++) {
143 *Writer = temp_array[j];
154 temp_vector =
new temp_vector_type(size);
156 for (j = 0; j < size; j++) {
157 (*temp_vector)[j] = buckets[i]->top();
162 space_left += PageSize_ * BlockSize_;
167 temp_vector->end(), rand, space_left);
172 for (j = 0; j < size; j++) {
173 *Writer = (*temp_vector)[j];
183 space_left += BlockSize_;
194 template <
typename Tp_,
typename AllocStrategy_,
typename SzTp_,
typename DiffTp_,
195 unsigned BlockSize_,
typename PgTp_,
unsigned PageSize_,
typename RandomNumberGenerator_>
198 RandomNumberGenerator_& rand,
202 typedef typename ExtIterator_::value_type value_type;
205 typedef typename stack_type::block_type block_type;
210 if (M < 6 * BlockSize_ + PageSize_ * BlockSize_) {
211 STXXL_ERRMSG(
"random_shuffle: insufficient memory, " << M <<
" bytes supplied,");
212 M = 6 * BlockSize_ + PageSize_ * BlockSize_;
213 STXXL_ERRMSG(
"random_shuffle: increasing to " << M <<
" bytes (6 blocks + 1 page)");
221 value_type* temp_array;
223 PageSize_, 4, BlockSize_, AllocStrategy_>::result temp_vector_type;
224 temp_vector_type* temp_vector;
228 stack_type** buckets;
231 buckets =
new stack_type*[k];
232 for (j = 0; j < k; j++)
233 buckets[j] =
new stack_type(pool, 0);
242 buf_istream_type in(first.bid(), last.
bid() + ((last.
block_offset()) ? 1 : 0), 2);
244 buf_ostream_type out(first.bid(), 2);
246 ExtIterator_ _cur = first - first.block_offset();
249 for ( ; _cur != first; ++_cur)
251 typename ExtIterator_::value_type tmp;
260 for (i = 0; i < n; ++i, ++_cur) {
261 random_bucket = rand((
unsigned)k);
262 typename ExtIterator_::value_type tmp;
264 buckets[random_bucket]->push(tmp);
273 PageSize_ * BlockSize_;
275 for (i = 0; i < k; i++) {
276 STXXL_VERBOSE1(
"random_shuffle: bucket no " << i <<
" contains " << buckets[i]->size() <<
" elements");
280 for (i = 0; i < k; i++) {
281 buckets[i]->set_prefetch_aggr(PageSize_);
282 size = buckets[i]->size();
285 if (size *
sizeof(value_type) < space_left) {
289 temp_array =
new value_type[size];
290 for (j = 0; j < size; j++) {
291 temp_array[j] = buckets[i]->top();
300 for (j = 0; j < size; j++) {
301 typename ExtIterator_::value_type tmp;
311 temp_vector =
new temp_vector_type(size);
313 for (j = 0; j < size; j++) {
314 (*temp_vector)[j] = buckets[i]->top();
319 space_left += PageSize_ * BlockSize_;
325 temp_vector->end(), rand, space_left);
330 for (j = 0; j < size; j++) {
331 typename ExtIterator_::value_type tmp;
332 tmp = (*temp_vector)[j];
342 space_left += BlockSize_;
350 ExtIterator_ _last_block_end = last + (block_type::size - last.
block_offset());
351 for ( ; _cur != _last_block_end; ++_cur)
353 typename ExtIterator_::value_type tmp;
364 template <
typename Tp_,
typename AllocStrategy_,
typename SzTp_,
typename DiffTp_,
365 unsigned BlockSize_,
typename PgTp_,
unsigned PageSize_>
379 #endif // !STXXL_ALGO_RANDOM_SHUFFLE_HEADER
Uniform [0, N) pseudo-random generator.
void random_shuffle(ExtIterator_ first, ExtIterator_ last, RandomNumberGenerator_ &rand, unsigned_type M, AllocStrategy_ AS=STXXL_DEFAULT_ALLOC_STRATEGY())
External equivalent of std::random_shuffle.
A model of stream that retrieves the data from an input iterator. For convenience use streamify funct...
_Self & flush()
Force flush of current block, for finishing writing within a block.
#define STXXL_DEFAULT_ALLOC_STRATEGY
Implements dynamically resizable buffered writing and prefetched reading pool.
choose_int_types< my_pointer_size >::int_type int_type
void resize_prefetch(size_type new_size)
Resizes size of the pool.
#define STXXL_BEGIN_NAMESPACE
void STXXL_UNUSED(const U &)
#define STXXL_VERBOSE1(x)
External vector iterator, model of ext_random_access_iterator concept.
#define STXXL_STATIC_ASSERT(x)
bids_container_iterator bid() const
return iterator to BID containg current element
choose_int_types< my_pointer_size >::unsigned_type unsigned_type
block_offset_type block_offset() const
return block offset of current element
Stack type generator Introduction to stack container: see STXXL Stack tutorial. Design and Internals of stack container: see Stack.
iterator2stream< InputIterator_ > streamify(InputIterator_ begin, InputIterator_ end)
Input iterator range to stream converter.
void resize_write(size_type new_size)
Resizes size of the pool.
External vector type generator.
#define STXXL_END_NAMESPACE