<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 2198: max_load_factor(z) makes no strong guarantees, but bans useful behavior</title>
<meta property="og:title" content="Issue 2198: max_load_factor(z) makes no strong guarantees, but bans useful behavior">
<meta property="og:description" content="C++ library issue. Status: Open">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue2198.html">
<meta property="og:type" content="website">
<meta property="og:image" content="http://cplusplus.github.io/LWG/images/cpp_logo.png">
<meta property="og:image:alt" content="C++ logo">
<style>
  p {text-align:justify}
  li {text-align:justify}
  pre code.backtick::before { content: "`" }
  pre code.backtick::after { content: "`" }
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table.issues-index { border: 1px solid; border-collapse: collapse; }
  table.issues-index th { text-align: center; padding: 4px; border: 1px solid; }
  table.issues-index td { padding: 4px; border: 1px solid; }
  table.issues-index td:nth-child(1) { text-align: right; }
  table.issues-index td:nth-child(2) { text-align: left; }
  table.issues-index td:nth-child(3) { text-align: left; }
  table.issues-index td:nth-child(4) { text-align: left; }
  table.issues-index td:nth-child(5) { text-align: center; }
  table.issues-index td:nth-child(6) { text-align: center; }
  table.issues-index td:nth-child(7) { text-align: left; }
  table.issues-index td:nth-child(5) span.no-pr { color: red; }
  @media (prefers-color-scheme: dark) {
     html {
        color: #ddd;
        background-color: black;
     }
     ins {
        background-color: #225522
     }
     del {
        background-color: #662222
     }
     a {
        color: #6af
     }
     a:visited {
        color: #6af
     }
     blockquote.note
     {
        background-color: rgba(255, 255, 255, .10)
     }
  }
</style>
</head>
<body>
<hr>
<p><em>This page is a snapshot from the LWG issues list, see the <a href="lwg-active.html">Library Active Issues List</a> for more information and the meaning of <a href="lwg-active.html#Open">Open</a> status.</em></p>
<h3 id="2198"><a href="lwg-active.html#2198">2198</a>. <code>max_load_factor(z)</code> makes no strong guarantees, but bans useful behavior</h3>
<p><b>Section:</b> 23.2.8 <a href="https://wg21.link/unord.req">[unord.req]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a>
 <b>Submitter:</b> Alisdair Meredith <b>Opened:</b> 2012-10-09 <b>Last modified:</b> 2016-12-10</p>
<p><b>Priority: </b>3
</p>
<p><b>View other</b> <a href="lwg-index-open.html#unord.req">active issues</a> in [unord.req].</p>
<p><b>View all other</b> <a href="lwg-index.html#unord.req">issues</a> in [unord.req].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#Open">Open</a> status.</p>
<p><b>Discussion:</b></p>

<p>
The user cannot specify a <code>max_load_factor</code> for their unordered container
at construction, it must be supplied after the event, when the container is
potentially not empty.  The contract for this method is deliberately vague, not
guaranteeing to use the value supplied by the user, and any value actually used
will be used as a ceiling that the container will <i>attempt</i> to respect.
</p>
<p>
The only guarantee we have is that, if user requests a <code>max_load_factor</code>
that is less than the current <code>load_factor</code>, then the operation will take
constant time, thus outlawing an implementation that chooses to rehash and so
preserve as a class invariant that <code>load_factor &lt; max_load_factor</code>.
</p>
<p>
Reasonable options conforming to the standard include ignoring the user's request
if the requested value is too low, or deferring the rehash to the next <code>insert</code>
operation and allowing the container to have a strange state (wrt <code>max_load_factor</code>)
until then - and there is still the question of rehashing if the next <code>insert</code>
is for a duplicate key in a unique container.
</p>
<p>
Given the deliberate vagueness of the current wording, to support a range of reasonable
(but not <i>perfect</i>) behaviors, it is not clear why the equally reasonable rehash
to restore the constraint should be outlawed.  It is not thought that this is a performance
critical operation, where users will be repeatedly setting low load factors on populated
containers, in a tight or (less unlikely) an instant response scenario.
</p>

<p><i>[2013-03-15 Issues Teleconference]</i></p>

<p>
Moved to Open.
</p>
<p>
Alisdair to provide wording.
</p>
<p><i>[2016-11-12, Issaquah]</i></p>

<p>Sat PM: Howard to provide wording</p>

<p><i>[2016-11-17 Howard provided wording.]</i></p>


<blockquote>
<p>
The provided wording is consistent with LWG discussion in Issaquah.  An implementation
of the proposed wording would be setting <code>max_load_factor()</code> to
<code>max(z, load_factor())</code>.  This preserves the container invariant:
</p>
<blockquote><pre>
load_factor() &lt;= max_load_factor()
</pre></blockquote>
<p>
And it preserves the existing behavior that no rehash is done by this operation.
</p>
<p>
If it is desired to change the <code>max_load_factor()</code> to something smaller than
the current <code>load_factor()</code> that can be done by <i>first reducing</i> the
current <code>load_factor()</code> by either increasing <code>bucket_count()</code> (via
<code>rehash</code> or <code>reserve</code>), or decreasing <code>size()</code> (e.g.
<code>erase</code>), <i>and then</i> changing <code>max_load_factor()</code>.
</p>

<p>
This resolution reaffirms that <code>load_factor() &lt;= max_load_factor()</code> is a
container invariant which can <i>never</i> be violated.
</p>
</blockquote>

<p><i>[2016-11-27, Nico comments]</i></p>

<p>
Current implementations behave differently. 
<p/>
In regard to the sentence
<blockquote>
"The only guarantee we have is that, if user requests a <code>max_load_factor</code>
that is less than the current <code>load_factor</code>, then the operation will take
constant time, thus outlawing an implementation that chooses to rehash
and so preserve as a class invariant that <code>load_factor &lt; max_load_factor</code>."
</blockquote>
Note that the current spec says that there is constant complexity
<em>without</em> any precondition. So, rehashing to keep the invariant would
violate the spec (which is probably not be the intention).
<p/>
This issue is related to LWG <a href="lwg-closed.html#2199" title="unordered containers are required to have an initial max load factor of 1.0 (Status: NAD)">2199</a><sup><a href="https://cplusplus.github.io/LWG/issue2199" title="Latest snapshot">(i)</a></sup>.
</p>


<p id="res-2198"><b>Proposed resolution:</b></p>

<p>
Modify Table 87 as follows:
</p>

<table border="1">
<caption>Table 87 &mdash; Unordered associative container requirements</caption>

<tr>
<th>
Expression
</th>
<th>
Return type
</th>
<th>
Assertion/note pre-/post-condition
</th>
<th>
Complexity
</th>
</tr>

<tr>
<td>
<code>a.max_load_factor(z)</code>
</td>
<td>
<code>void</code>
</td>
<td>
<p>
Pre: <code>z</code> shall be positive.  May change the container's maximum
load factor, uing <code>z</code> as a hint.
</p>
<p>
<ins>Post: <code>a.load_factor() &lt;= a.max_load_factor()</code></ins>
</p>
<p>
<ins><i>Note:</i> <code>a.load_factor()</code> is not modified by this operation.</ins>
</p>
</td>
<td>
Constant
</td>
</tr>

</table>






</body>
</html>
