en	:idprefix: buckets_

en	= Basics of Hash Tables
zh-hans	= 哈希表基础

en	The containers are made up of a number of _buckets_, each of which can contain any number of elements. For example, the following diagram shows a `xref:reference/unordered_set.adoc#unordered_set[boost::unordered_set]` with 7 buckets containing 5 elements, `A`, `B`, `C`, `D` and `E` (this is just for illustration, containers will typically have more buckets).
zh-hans	该容器由若干__桶__组成，每个桶可容纳任意数量的元素。例如，下图展示了一个包含7个桶的 xref:reference/unordered_set.adoc#unordered_set[boost::unordered_set]，其中存储着5个元素（ `A` 、 `B` 、 `C` 、 `D` 和 `E` ）（此示意图仅为演示用途，实际容器通常包含更多桶）。

en	image::buckets.png[]

en	In order to decide which bucket to place an element in, the container applies the hash function, `Hash`, to the element's key (for sets the key is the whole element, but is referred to as the key so that the same terminology can be used for sets and maps). This returns a value of type `std::size_t`. `std::size_t` has a much greater range of values then the number of buckets, so the container applies another transformation to that value to choose a bucket to place the element in.
zh-hans	容器通过哈希函数 `Hash` 作用于元素的键来确定其所属的桶（对于集合而言，键即元素本身，但为统一集合与映射表的术语仍称作键）。该函数返回 `std::size_t` 类型的值。由于 `std::size_t` 的取值范围远大于桶的数量，容器会对此值进行二次转换以确定元素应存入的桶。

en	Retrieving the elements for a given key is simple. The same process is applied to the key to find the correct bucket. Then the key is compared with the elements in the bucket to find any elements that match (using the equality predicate `Pred`). If the hash function has worked well the elements will be evenly distributed amongst the buckets so only a small number of elements will need to be examined.
zh-hans	根据指定键检索元素的过程非常简单：首先对键执行相同处理以定位对应桶，随后通过相等性谓词 `Pred` 将键与桶内元素进行比较以寻找匹配项。若哈希函数表现良好，元素将均匀分布于各桶中，此时仅需检查少量元素即可完成检索。

en	There is xref:hash_equality.adoc#hash_equality[more information on hash functions and equality predicates in the next section].
zh-hans	关于哈希函数与相等性谓词的详细说明请参阅 xref:hash_equality.adoc#hash_equality[后续章节] 。

en	You can see in the diagram that `A` & `D` have been placed in the same bucket. When looking for elements in this bucket up to 2 comparisons are made, making the search slower. This is known as a *collision*. To keep things fast we try to keep collisions to a minimum.
zh-hans	如图所示， `A` 与 `D` 被置于同一桶内。在此桶内查找元素时最多需要进行 2 次比对，这会降低检索效率，该现象称为**冲突**。为维持高效运作，我们需尽可能减少冲突的发生。

en	If instead of `boost::unordered_set` we had used `xref:reference/unordered_flat_set.adoc[boost::unordered_flat_set]`, the diagram would look as follows:
zh-hans	若使用 xref:reference/unordered_flat_set.adoc[boost::unordered_flat_set]替代 `boost::unordered_set` ，其结构示意图将呈现如下形式：

en	image::buckets-oa.png[]

en	In open-addressing containers, buckets can hold at most one element; if a collision happens (like is the case of `D` in the example), the element uses some other available bucket in the vicinity of the original position. Given this simpler scenario, Boost.Unordered open-addressing containers offer a very limited API for accessing buckets.
zh-hans	在开放寻址式容器中，每个桶最多只能容纳一个元素；若发生冲突（如示例中的元素 `D` 的情况），该元素将使用原始位置附近的其他可用桶。基于此简化设计，Boost.Unordered开放寻址容器仅提供极其有限的桶访问API。

en	2+^h| *All containers* h|*Method* h|*Description*
zh-hans	2+^h| *所有容器* h|*方法* h|*描述*

en	`size_type bucket_count() const`

en	The number of buckets.
zh-hans	桶的数量。

en	2+^h| *Closed-addressing containers only* h|*Method* h|*Description*
zh-hans	2+^h| *仅限闭寻址容器* h|*方法* h|*描述*

en	`size_type max_bucket_count() const`

en	An upper bound on the number of buckets.
zh-hans	桶数量的上限。

en	`size_type bucket_size(size_type n) const`

en	The number of elements in bucket `n`.
zh-hans	返回桶 `n` 中的元素数量。

en	`size_type bucket(key_type const& k) const`
zh-hans	`size_type bucket(key_type const&amp; k) const`

en	Returns the index of the bucket which would contain `k`.
zh-hans	返回键 `k` 所对应的桶的索引。

en	`local_iterator begin(size_type n)`

en	1.6+|Return begin and end iterators for bucket `n`.
zh-hans	1.6+|返回编号为 `n` 的桶的起始与末尾迭代器。

en	`local_iterator end(size_type n)`

en	`const_local_iterator begin(size_type n) const`

en	`const_local_iterator end(size_type n) const`

en	`const_local_iterator cbegin(size_type n) const`

en	`const_local_iterator cend(size_type n) const`

en	Controlling the Number of Buckets
zh-hans	桶数量控制

en	As more elements are added to an unordered associative container, the number of collisions will increase causing performance to degrade. To combat this the containers increase the bucket count as elements are inserted. You can also tell the container to change the bucket count (if required) by calling `rehash`.
zh-hans	当无序关联容器中的元素不断增加时，冲突次数会随之上升，从而导致性能下降。为解决此问题，容器会在插入元素过程中自动增加桶的数量。用户也可以通过调用 `rehash` 方法来按需调整容器的桶数量。

en	The standard leaves a lot of freedom to the implementer to decide how the number of buckets is chosen, but it does make some requirements based on the container's _load factor_, the number of elements divided by the number of buckets. Containers also have a _maximum load factor_ which they should try to keep the load factor below.
zh-hans	标准规范虽未强制规定桶数量的具体选择方式，但基于容器的__负载因子__（即元素数量与桶数量的比值）提出了若干要求。同时，容器还设有一个__最大负载因子__，其运行过程中需始终将实际负载因子维持在该阈值以下。

en	You can't control the bucket count directly but there are two ways to influence it:
zh-hans	用户无法直接控制桶的数量，但可通过以下两种方式间接调控：

en	Specify the minimum number of buckets when constructing a container or when calling `rehash`.
zh-hans	用户可在构造容器或调用 `rehash` 方法时指定桶数量的最小值。

en	Suggest a maximum load factor by calling `max_load_factor`.
zh-hans	用户可通过调用 `max_load_factor` 方法来设定最大负载因子的建议值。

en	`max_load_factor` doesn't let you set the maximum load factor yourself, it just lets you give a _hint_. And even then, the standard doesn't actually require the container to pay much attention to this value. The only time the load factor is _required_ to be less than the maximum is following a call to `rehash`. But most implementations will try to keep the number of elements below the max load factor, and set the maximum load factor to be the same as or close to the hint - unless your hint is unreasonably small or large.
zh-hans	`max_load_factor` 并不允许用户自行设定最大负载因子，该方法仅用于提供__提示__。即便如此，标准也并未强制要求容器必须严格遵守该数值。唯一强制要求负载因子必须小于最大值的场景是在调用 `rehash` 方法之后。但大多数实现会尝试将元素数量维持在最大负载因子以下，并将最大负载因子设定为与提示值相同或接近——除非用户提供的提示值过小或过大。

en	2+^h| *All containers* h|*Method* h|*Description*
zh-hans	2+^h| *所有容器* h|*方法* h|*描述*

en	`X(size_type n)`

en	Construct an empty container with at least `n` buckets (`X` is the container type).
zh-hans	构造一个至少包含 `n` 个桶的空容器（ `X` 表示容器类型）。

en	`X(InputIterator i, InputIterator j, size_type n)`

en	Construct an empty container with at least `n` buckets and insert elements from the range `[i, j)` (`X` is the container type).
zh-hans	构造一个至少包含 `n` 个桶的空容器，并插入范围 `[i, j)` 中的元素（ `X` 表示容器类型）。

en	`float load_factor() const`

en	The average number of elements per bucket.
zh-hans	返回每个桶的平均元素数量。

en	`float max_load_factor() const`

en	Returns the current maximum load factor.
zh-hans	返回当前的最大负载因子。

en	`float max_load_factor(float z)`

en	Changes the container's maximum load factor, using `z` as a hint. +
zh-hans	以 `z` 作为提示值来更改容器的最大负载因子。 +

en	**Open-addressing and concurrent containers:** this function does nothing: users are not allowed to change the maximum load factor.
zh-hans	**开放寻址与并发容器：**此函数无效，用户不允许更改最大负载因子。

en	`void rehash(size_type n)`

en	Changes the number of buckets so that there at least `n` buckets, and so that the load factor is less than the maximum load factor.
zh-hans	调整桶的数量，使其至少为 `n` ，并确保负载因子小于最大负载因子。

en	2+^h| *Open-addressing and concurrent containers only* h|*Method* h|*Description*
zh-hans	2+^h| *仅限开放寻址与并发容器* h|*方法* h|*描述*

en	`size_type max_load() const`

en	Returns the maximum number of allowed elements in the container before rehash.
zh-hans	返回容器触发重新哈希前所允许容纳的最大元素数量。

en	A note on `max_load` for open-addressing and concurrent containers: the maximum load will be (`max_load_factor() * bucket_count()`) right after `rehash` or on container creation, but may slightly decrease when erasing elements in high-load situations. For instance, if we have a `xref:reference/unordered_flat_map.adoc#unordered_flat_map[boost::unordered_flat_map]` with `size()` almost at `max_load()` level and then erase 1,000 elements, `max_load()` may decrease by around a few dozen elements. This is done internally by Boost.Unordered in order to keep its performance stable, and must be taken into account when planning for rehash-free insertions.
zh-hans	关于开放寻址与并发容器的 `max_load` 注意事项：在容器创建或执行 `rehash` 后，最大负载值将保持为 `max_load_factor() * bucket_count()` ；但在高负载场景下执行元素删除操作时，该值可能轻微下降。例如，若某个 xref:reference/unordered_flat_map.adoc#unordered_flat_map[boost::unordered_flat_map] 的 `size()` 已接近 `max_load()` 阈值，随后删除 1,000 个元素时， `max_load()` 可能减少约数十个元素。此机制是Boost.Unordered为保持性能稳定而采取的内部机制，用户在规划无重组插入操作时需予以考虑。