What is the use of the buckets interface in std :: unordered_map?

I watched this video from CppCon 2014 and

+7
c ++ c ++ 11 stl
source share
4 answers

It is often useful to look for a sentence that introduced an element, since there is often an accompanying rationale. In this case, N1443 says the following:

G. Bucket Interface

Like all standard containers, each hashed container has a member function begin () and end (). The range [c.begin (), c.end ()) contains all the elements in the container presented as a flat range. The elements inside the bucket are adjacent, but the iterator interface does not contain information about where one bucket ends and the next begins.

It is also useful to expose the bucket structure for two reasons. Firstly, it allows users to examine how well their hash function performs: it allows them to check how even elements are distributed inside the bucket, and look at the elements inside the bucket to see they have common properties. Secondly, if iterators have a basic segmented structure (as in existing singly linked lists), algorithms that use this structure with an explicit nested loop may be more efficient than algorithms that treat elements as a flat range.

The most important part of the bucket interface is overloading begin () and end (). If n is an integer, [begin (n), end (n)) is a range of iterators pointing to elements in the nth bucket. These members of the function return iterators, of course, but not of type X :: iterator or X :: const_iterator. Instead, they return iterators such as X :: local_iterator or X :: const_local_iterator. A local iterator is capable of iterating in a bucket, but not necessarily between buckets; some implementations allow X :: local_iterator to be a simpler data structure than X :: iterator. X :: iterator and X :: local_iterator are allowed to the same type; implementations that use bidirectional lists are probably freedom.

This bucket interface is not provided by SGI, Dinkumware, or Metrowerks Implementation. This is partly inspired by the Metrowerks collision detection interface, and partly by the early work (see [Austern 1998]) on algorithms for segmented containers.

+7
source share

There are a number of algorithms that require objects to be hashed into a number of buckets, and then each bucket is processed.

Say you want to find duplicates in a collection. You have all the elements in the collection, then in each bucket you compare the elements in pairs.

A slightly less trivial example is the Apriori algorithm for finding frequent sets of elements.

+1
source share

I assume that you can greatly benefit from this if you are in a high-performance situation and collisions ultimately kill you. Iterating the buckets and looking at the size of the bucket can periodically tell you if your hashing policy is sufficient.

Unordered cards are highly dependent on their hash policy when it comes to performance.

+1
source share

The only reason I ever needed an interface was to move all the objects on the map without having to hold the lock on the map or copy the map. This can be used for inaccurate expiration or other types of periodic inspections of objects on the map.

Traverse works as follows:

  • Block the card.

  • Start moving the map in bucket order, working on each object that you encounter.

  • When you decide that you held the lock for a long time, hold down the key of the object in which you last worked.

  • Wait until you want to resume work.

  • Lock the card and go to step 2, starting with or near (in bucket order) the key that you stopped. If you reach the end, start from the beginning.

+1
source share

All Articles