14 #ifndef STXXL_CONTAINERS_HASH_MAP_UTIL_HEADER
15 #define STXXL_CONTAINERS_HASH_MAP_UTIL_HEADER
16 #define STXXL_CONTAINERS_HASHMAP__UTIL_H
30 template <
class ValueType>
39 return ((
int_type)next_and_del_ & 0x01) == 1;
61 template <
class NodeType>
87 n_external_(n_external),
89 i_subblock_(i_subblock)
94 template <
class CacheType,
class B
idIterator>
105 typedef typename bid_iterator::value_type
bid_type;
107 enum { block_size = block_type::size, subblock_size = subblock_type::size };
147 begin_bid_(seq_begin),
148 curr_bid_(seq_begin),
152 page_size_(
tuning::get_instance()->prefetch_page_size),
153 prefetch_pages_(
tuning::get_instance()->prefetch_pages),
157 if (seq_begin == seq_end)
161 enable_prefetching();
164 skip_to(seq_begin, i_subblock);
169 if (curr_bid_ != end_bid_)
170 cache_.release_block(*curr_bid_);
179 pref_bid_ = curr_bid_;
181 for (
unsigned_type i = 0; i < page_size_ * prefetch_pages_; i++)
183 if (pref_bid_ == end_bid_)
186 cache_.prefetch_block(*pref_bid_);
194 return (*subblock_)[i_value_ % subblock_size];
202 cache_.make_dirty(*curr_bid_);
206 return (*subblock_)[i_value_ % subblock_size];
213 if (curr_bid_ == end_bid_)
217 if (i_value_ + 1 < block_size * subblock_size)
224 cache_.release_block(*curr_bid_);
230 if (curr_bid_ == end_bid_)
233 cache_.retain_block(*curr_bid_);
236 if (prefetch_ && (curr_bid_ - begin_bid_) % page_size_ == 0)
238 for (
unsigned i = 0; i < page_size_; i++)
240 if (pref_bid_ == end_bid_)
242 cache_.prefetch_block(*pref_bid_);
249 if (i_value_ % subblock_size == 0)
251 subblock_ = cache_.get_subblock(*curr_bid_, i_value_ / subblock_size);
260 i_value_ = (i_value_ / subblock_size + 1) * subblock_size - 1;
267 if (curr_bid_ == end_bid_)
270 if (bid != curr_bid_)
273 cache_.release_block(*curr_bid_);
279 while (curr_bid_ != bid) {
282 if (prefetch_ && (curr_bid_ - begin_bid_) % page_size_ == 0)
284 for (
unsigned i = 0; i < page_size_; i++)
286 if (pref_bid_ == end_bid_)
288 cache_.prefetch_block(*pref_bid_);
294 i_value_ = i_subblock * subblock_size;
295 subblock_ = cache_.get_subblock(*curr_bid_, i_subblock);
296 cache_.retain_block(*curr_bid_);
301 template <
class BlockType,
class B
idContainer>
314 block_size = block_type::size,
315 subblock_size = subblock_type::size
341 : writer_(buffer_size, batch_size),
345 increase_(
config::get_instance()->disks_number() * 3)
347 block_ = writer_.get_free_block();
356 template <
class StreamType>
359 while (!stream.empty())
370 (*block_)[i_subblock][i_value_ % subblock_size] = value;
372 if (i_value_ + 1 < block_size * subblock_size)
380 if (i_block_ == bids_->size())
382 bids_->resize(bids_->size() + increase_);
387 block_ = writer_.write(block_, (*bids_)[i_block_]);
397 i_value_ = (i_value_ / subblock_size + 1) * subblock_size - 1;
405 if (i_block_ == bids_->size())
407 bids_->resize(bids_->size() + increase_);
411 block_ = writer_.write(block_, (*bids_)[i_block_]);
431 template <
class HashMap>
458 i_external_(i_external)
469 template <
class HashMap,
class Reader>
476 typedef typename hash_map_type::bid_container_type::iterator
bid_iterator;
497 curr_bucket_(begin_bucket),
498 end_bucket_(end_bucket),
499 begin_bid_(begin_bid),
501 node_(curr_bucket_ != end_bucket_ ? curr_bucket_->list_ : NULL),
505 value_ = find_next();
510 bool empty()
const {
return curr_bucket_ == end_bucket_; }
514 if (value_.source_ == hash_map_type::src_internal)
515 node_ = node_->next();
521 value_ = find_next();
529 while (node_ && i_external_ < curr_bucket_->n_external_)
531 if (map_._leq(node_->value_.first, reader_.const_value().first))
533 if (map_._eq(node_->value_.first, reader_.const_value().first))
539 if (!node_->deleted())
540 return value_type(node_->value_, i_bucket_, hash_map_type::src_internal, node_, i_external_);
542 node_ = node_->next();
545 return value_type(reader_.const_value(), i_bucket_, hash_map_type::src_external, node_, i_external_);
550 if (!node_->deleted())
551 return value_type(node_->value_, i_bucket_, hash_map_type::src_internal, node_, i_external_);
553 node_ = node_->next();
556 while (i_external_ < curr_bucket_->n_external_)
557 return value_type(reader_.const_value(), i_bucket_, hash_map_type::src_external, node_, i_external_);
563 if (curr_bucket_ == end_bucket_)
566 node_ = curr_bucket_->list_;
568 reader_.skip_to(begin_bid_ + curr_bucket_->i_block_, curr_bucket_->i_subblock_);
577 #endif // !STXXL_CONTAINERS_HASH_MAP_UTIL_HEADER
BidContainer bid_container_type
hash_map_type::internal_size_type internal_size_type
const value_type & const_value()
Get const-reference to current value.
void append_from_stream(StreamType &stream)
Write all values from given stream.
hash_map_type::buckets_container_type::iterator bucket_iterator
Additional information about a stored value:
HashedValue(const value_type &value, internal_size_type i_bucket, source_type src, node_type *node, external_size_type i_external)
bucket_iterator curr_bucket_
hash_map_type::node_type node_type
bid_container_type * bids_
sequence of allocated blocks (to be expanded as needed)
hash_map_type::internal_size_type internal_size_type
void append(const value_type &value)
Write given value.
bid_iterator::value_type bid_type
cache_type::block_type block_type
external_size_type i_external_
hash_map_type::external_size_type external_size_type
bool deleted()
check if the next node is deleted.
bool dirty_
current block dirty ?
unsigned_type page_size_
pages, which are read at once from disk, consist of this many blocks
hash_map_type::external_size_type external_size_type
internal_size_type i_subblock()
Index of current subblock.
unsigned_type i_block_
current block's index
buffered_writer(bid_container_type *c, int_type buffer_size, int_type batch_size)
Create a new buffered writer.
hash_map_type::bid_container_type::iterator bid_iterator
bid_iterator end_bid_
points to the end of the block-sequence
block_type::value_type subblock_type
internal_size_type i_bucket_
uint_pair & operator++()
prefix increment operator (directly manipulates the integer parts)
external_size_type i_external_
cache_type & cache_
shared block-cache
HashedValuesStream(bucket_iterator begin_bucket, bucket_iterator end_bucket, Reader &reader, bid_iterator begin_bid, hash_map_type &map)
subblock_type * subblock_
current subblock
internal_size_type i_subblock_
index of first subblock
subblock_type::value_type value_type
Tuning parameters for external memory hash map.
void finish_subblock()
Continue writing at the beginning of the next subblock. TODO more efficient.
bool prefetch_
true if prefetching enabled
void next_subblock()
Skip remaining values of the current subblock.
choose_int_types< my_pointer_size >::int_type int_type
block_type::value_type subblock_type
static instance_pointer get_instance()
unsigned_type internal_size_type
buffered_reader(bid_iterator seq_begin, bid_iterator seq_end, cache_type &cache, internal_size_type i_subblock=0, bool prefetch=true)
Create a new buffered reader to read the blocks in [seq_begin, seq_end)
node< ValueType > * next_and_del_
Striping disk allocation scheme functor.
bucket_iterator end_bucket_
internal_size_type i_block_
index of first block's bid (to be used as index for hash_map's bids_-array
#define STXXL_BEGIN_NAMESPACE
external_size_type n_external_
number of elements in external memory
hash_map_type::node_type node_type
stxxl::buffered_writer< block_type > writer_type
internal_size_type i_bucket_
unsigned_type increase_
number of blocks to allocate in a row
Stream interface for all value-pairs currently stored in the map.
bool set_deleted(bool d)
change deleted flag on the next node
NodeType * list_
entry point to the chain in internal memory
hash_map_type::value_type value_type
void new_blocks(const DiskAssignFunctor &functor, BIDIteratorClass bidbegin, BIDIteratorClass bidend, unsigned_type offset=0)
Allocates new blocks.
uint64 external_size_type
choose_int_types< my_pointer_size >::unsigned_type unsigned_type
void enable_prefetching()
Used to scan external memory with prefetching.
Access point to disks properties. Since 1.4.0: no config files are read automatically! ...
block_type * block_
current buffer-block
subblock_type::value_type value_type
writer_type writer_
buffered writer
unsigned_type i_value_
index within current block
hash_map_type::source_type source_type
External associative container (map). Introduction to map container: see STXXL Map (B+-tree) tutor...
bid_iterator begin_bid_
points to the beginning of the block-sequence
internal_size_type i_block()
Index of current block.
node< ValueType > * set_next(node< ValueType > *n)
change the "next" value of next node pointer
HashedValue< HashMap > value_type
Buffered writing of values. New Blocks are allocated as needed.
void flush()
Flushes not yet written blocks.
bid_iterator pref_bid_
points to the next block to prefetch
unsigned_type prefetch_pages_
number of pages to prefetch
bid_iterator curr_bid_
points to the current block
unsigned_type i_value_
current value's index in the range of [0..#values per block[
#define STXXL_END_NAMESPACE
node< ValueType > * next()
return the next node, without the "next" flag.
bucket(NodeType *list, external_size_type n_external, internal_size_type i_block, internal_size_type i_subblock)
value_type & value()
Get reference to current value. The current value's block's dirty flag will be set.
void skip_to(bid_iterator bid, internal_size_type i_subblock)
Continue reading at given block and subblock.