mirror of
https://github.com/boostorg/unordered.git
synced 2025-05-11 21:44:01 +00:00
Documentation tweaks.
[SVN r3340]
This commit is contained in:
parent
905a2dd28a
commit
136e2fe3ba
@ -1,11 +1,5 @@
|
|||||||
[section:comparison Comparison with Associative Containers]
|
[section:comparison Comparison with Associative Containers]
|
||||||
|
|
||||||
TODO: This page probably contains too much information. Some of the comparisons
|
|
||||||
can probably be paired down (especially the complexity stuff) and some of the
|
|
||||||
extra details belong elsewhere.
|
|
||||||
|
|
||||||
TODO: I've omitted some similarities - perhaps I should include them.
|
|
||||||
|
|
||||||
[table Interface differences.
|
[table Interface differences.
|
||||||
[[Associative Containers] [Unordered Associative Containers]]
|
[[Associative Containers] [Unordered Associative Containers]]
|
||||||
|
|
||||||
|
Binary file not shown.
@ -19,40 +19,47 @@ standard pretty much requires that the hash table uses chained addressing.
|
|||||||
|
|
||||||
It would be conceivable to write a hash table that uses another method. For
|
It would be conceivable to write a hash table that uses another method. For
|
||||||
example, an it could use open addressing, and use the lookup chain to act as a
|
example, an it could use open addressing, and use the lookup chain to act as a
|
||||||
bucket but there are a some serious problems with this. The biggest one is that
|
bucket but there are a some serious problems with this:
|
||||||
the draft standard requires that pointers to elements aren't invalidated, so
|
|
||||||
the elements couldn't be stored in one array, but instead will need a layer of
|
|
||||||
indirection - loosing the efficiency and memory gains for small types.
|
|
||||||
|
|
||||||
Local iterators would be very inefficient and may not be able to
|
* The draft standard requires that pointers to elements aren't invalidated, so
|
||||||
meet the complexity requirements. And for containers with
|
the elements can't be stored in one array, but will need a layer of
|
||||||
equivalent keys, making sure that they are adjacent would probably require a
|
indirection instead - loosing the efficiency and most of the memory gain,
|
||||||
chain of some sort anyway.
|
the main advantages of open addressing.
|
||||||
|
|
||||||
There are also the restrictions on when iterators can be invalidated. Since
|
* Local iterators would be very inefficient and may not be able to
|
||||||
open addressing degrades badly when there are a high number of collisions the
|
meet the complexity requirements.
|
||||||
restrictions could prevent rehash when it's really needed. The maximum load
|
|
||||||
factor could be set to a fairly low value to work around this - but the
|
* There are also the restrictions on when iterators can be invalidated. Since
|
||||||
standard requires that it is initially set to 1.0.
|
open addressing degrades badly when there are a high number of collisions the
|
||||||
|
restrictions could prevent a rehash when it's really needed. The maximum load
|
||||||
|
factor could be set to a fairly low value to work around this - but the
|
||||||
|
standard requires that it is initially set to 1.0.
|
||||||
|
|
||||||
And, of course, since the standard is written with a eye towards chained
|
* And since the standard is written with a eye towards chained
|
||||||
addressing, users will be suprised if the performance doesn't reflect that.
|
addressing, users will be suprised if the performance doesn't reflect that.
|
||||||
|
|
||||||
So staying with chained addressing is inevitable.
|
So chained addressing is used.
|
||||||
|
|
||||||
For containers with unique keys I use a single-linked list to store the
|
For containers with unique keys I store the buckets in a single-linked list.
|
||||||
buckets. There are other possible data structures which would allow for
|
There are other possible data structures (such as a double-linked list)
|
||||||
some operations to be faster (such as erasing and iteration) but the gains
|
that allow for some operations to be faster (such as erasing and iteration)
|
||||||
seem too small for the extra cost (in memory). The most commonly used
|
but the possible gain seems small compared to the extra memory needed.
|
||||||
operations (insertion and lookup) would not be improved.
|
The most commonly used operations (insertion and lookup) would not be improved
|
||||||
|
at all.
|
||||||
|
|
||||||
But for containers with equivalent keys, a single-linked list can degrade badly
|
But for containers with equivalent keys a single-linked list can degrade badly
|
||||||
when a large number of elements with equivalent keys are inserted. I think it's
|
when a large number of elements with equivalent keys are inserted. I think it's
|
||||||
reasonable to assume that users who chose to use `unordered_multiset` or
|
reasonable to assume that users who choose to use `unordered_multiset` or
|
||||||
`unordered_multimap`, did so because they are likely to insert elements with
|
`unordered_multimap` do so because they are likely to insert elements with
|
||||||
equivalent keys. So I have used an alternative data structure that doesn't
|
equivalent keys. So I have used an alternative data structure that doesn't
|
||||||
degrade, at the expense of an extra pointer per node.
|
degrade, at the expense of an extra pointer per node.
|
||||||
|
|
||||||
|
This works by adding storing a circular linked list for each group of equivalent
|
||||||
|
nodes in reverse order. This allows quick navigation to the end of a group (since
|
||||||
|
the first element points to the last) and can be quickly updated when elements
|
||||||
|
are inserted or erased. The main disadvantage of this approach is some hairy code
|
||||||
|
for erasing elements.
|
||||||
|
|
||||||
[h2 Number of Buckets]
|
[h2 Number of Buckets]
|
||||||
|
|
||||||
There are two popular methods for choosing the number of buckets in a hash
|
There are two popular methods for choosing the number of buckets in a hash
|
||||||
@ -119,8 +126,12 @@ some member functions are overloaded by the same type.
|
|||||||
|
|
||||||
The proposed resolution is to add a new subsection to 17.4.4:
|
The proposed resolution is to add a new subsection to 17.4.4:
|
||||||
[:An implementation shall not supply an overloaded function signature specified in any library clause if such a signature would be inherently ambiguous during overload resolution due to two library types referring to the same type.]
|
[:An implementation shall not supply an overloaded function signature specified in any library clause if such a signature would be inherently ambiguous during overload resolution due to two library types referring to the same type.]
|
||||||
So I don't supply the `iterator` overloads - although this means that the
|
So I don't supply the `iterator` overloads.
|
||||||
header and documentation are currently inconsistent.
|
|
||||||
This will be fixed before review submission.
|
[h3 [@http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#560
|
||||||
|
560. User-defined allocators without default constructor]]
|
||||||
|
|
||||||
|
This implementation should work okay for an allocator without a default
|
||||||
|
constructor, although I don't currently test for this.
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user