15 #ifndef STXXL_ALGO_RANDOM_SHUFFLE_HEADER
16 #define STXXL_ALGO_RANDOM_SHUFFLE_HEADER
40 template <
typename ExtIterator,
41 typename RandomNumberGenerator,
44 typename AllocStrategy>
47 RandomNumberGenerator& rand,
52 typedef typename ExtIterator::value_type value_type;
55 BlockSize, void, 0, AllocStrategy
57 typedef typename stack_type::block_type block_type;
60 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.");
62 int64 n = last - first;
65 if (M < 6 * BlockSize + PageSize * BlockSize) {
66 STXXL_ERRMSG(
"random_shuffle: insufficient memory, " << M <<
" bytes supplied,");
67 M = 6 * BlockSize + PageSize * BlockSize;
68 STXXL_ERRMSG(
"random_shuffle: increasing to " << M <<
" bytes (6 blocks + 1 page)");
75 value_type* temp_array;
77 value_type, PageSize, 4, BlockSize, AllocStrategy
78 >::result temp_vector_type;
79 temp_vector_type* temp_vector;
81 STXXL_VERBOSE1(
"random_shuffle: " << M / BlockSize - k <<
" write buffers for " << k <<
" buckets");
87 buckets =
new stack_type*[k];
88 for (j = 0; j < k; j++)
89 buckets[j] =
new stack_type(pool, 0);
97 for (i = 0; i < n; ++i) {
98 random_bucket = rand(k);
99 buckets[random_bucket]->push(*in);
109 PageSize * BlockSize;
110 ExtIterator Writer = first;
111 ExtIterator it = first;
113 for (i = 0; i < k; i++) {
114 STXXL_VERBOSE1(
"random_shuffle: bucket no " << i <<
" contains " << buckets[i]->size() <<
" elements");
118 for (i = 0; i < k; i++) {
119 buckets[i]->set_prefetch_aggr(PageSize);
120 size = buckets[i]->size();
123 if (size *
sizeof(value_type) < space_left) {
127 temp_array =
new value_type[size];
128 for (j = 0; j < size; j++) {
129 temp_array[j] = buckets[i]->top();
138 for (j = 0; j < size; j++) {
139 *Writer = temp_array[j];
150 temp_vector =
new temp_vector_type(size);
152 for (j = 0; j < size; j++) {
153 (*temp_vector)[j] = buckets[i]->top();
158 space_left += PageSize * BlockSize;
163 temp_vector->end(), rand, space_left);
168 for (j = 0; j < size; j++) {
169 *Writer = (*temp_vector)[j];
179 space_left += BlockSize;
190 template <
typename Type,
typename AllocStrategy,
typename SizeType,
typename DiffType,
191 unsigned BlockSize,
typename PageType,
unsigned PageSize,
typename RandomNumberGenerator>
194 BlockSize, PageType, PageSize> first,
196 BlockSize, PageType, PageSize> last,
197 RandomNumberGenerator& rand,
201 typedef typename ExtIterator::value_type value_type;
202 typedef typename ExtIterator::bids_container_iterator bids_container_iterator;
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 value_type, PageSize, 4, BlockSize, AllocStrategy
224 >::result temp_vector_type;
225 temp_vector_type* temp_vector;
230 stack_type** buckets;
233 buckets =
new stack_type*[k];
234 for (j = 0; j < k; j++)
235 buckets[j] =
new stack_type(pool, 0);
243 buf_istream_type in(first.bid(), last.bid() + ((last.block_offset()) ? 1 : 0), 2);
245 buf_ostream_type out(first.bid(), 2);
247 ExtIterator _cur = first - first.block_offset();
250 for ( ; _cur != first; ++_cur)
252 typename ExtIterator::value_type tmp;
261 for (i = 0; i < n; ++i, ++_cur) {
262 random_bucket = rand((
unsigned)k);
263 typename ExtIterator::value_type tmp;
265 buckets[random_bucket]->push(tmp);
274 unsigned_type space_left = M - k * BlockSize - PageSize * BlockSize;
276 for (i = 0; i < k; i++) {
277 STXXL_VERBOSE1(
"random_shuffle: bucket no " << i <<
" contains " << buckets[i]->size() <<
" elements");
281 for (i = 0; i < k; i++) {
282 buckets[i]->set_prefetch_aggr(PageSize);
283 size = buckets[i]->size();
286 if (size *
sizeof(value_type) < space_left) {
290 temp_array =
new value_type[(size_t)size];
291 for (j = 0; j < size; j++) {
292 temp_array[j] = buckets[i]->top();
301 for (j = 0; j < size; j++) {
302 typename ExtIterator::value_type tmp;
312 temp_vector =
new temp_vector_type(size);
314 for (j = 0; j < size; j++) {
315 (*temp_vector)[j] = buckets[i]->top();
320 space_left += PageSize * BlockSize;
326 temp_vector->end(), rand, space_left);
331 for (j = 0; j < size; j++) {
332 typename ExtIterator::value_type tmp;
333 tmp = (*temp_vector)[j];
343 space_left += BlockSize;
349 if (last.block_offset())
351 ExtIterator last_block_end = last + (block_type::size - last.block_offset());
352 for ( ; _cur != last_block_end; ++_cur)
354 typename ExtIterator::value_type tmp;
365 template <
typename Type,
typename AllocStrategy,
typename SizeType,
typename DiffType,
366 unsigned BlockSize,
typename PageType,
unsigned PageSize>
370 BlockSize, PageType, PageSize> first,
372 BlockSize, PageType, PageSize> last,
383 #endif // !STXXL_ALGO_RANDOM_SHUFFLE_HEADER
iterator2stream< InputIterator > streamify(InputIterator begin, InputIterator end)
Input iterator range to stream converter.
Uniform [0, N) pseudo-random generator.
A model of stream that retrieves the data from an input iterator. For convenience use streamify funct...
#define STXXL_DEFAULT_ALLOC_STRATEGY
self_type & flush()
Force flush of current block, for finishing writing within a block.
Implements dynamically resizable buffered writing and prefetched reading pool.
choose_int_types< my_pointer_size >::int_type int_type
void random_shuffle(ExtIterator first, ExtIterator last, RandomNumberGenerator &rand, unsigned_type M, AllocStrategy AS=STXXL_DEFAULT_ALLOC_STRATEGY())
External equivalent of std::random_shuffle.
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)
choose_int_types< my_pointer_size >::unsigned_type unsigned_type
Stack type generator Introduction to stack container: see STXXL Stack tutorial. Design and Internals of stack container: see Stack.
void resize_write(size_type new_size)
Resizes size of the pool.
External vector type generator.
#define STXXL_END_NAMESPACE