mu/html/069hash.cc.html
Kartik Agaram 08a0eed699 4891
Couple more tweaks to html rendering:
a) SubX definitions no longer link redundantly to themselves. This long-standing
issue turns out to be tractable to solve for SubX files since the syntax
is so simple.
b) Fix links to SubX definitions in other directories. I forgot that I
have to always generate tags from the directory of the file being linkified.
c) Fix link colors. Before we lost all syntax highlighting for functions
and Globals. Now they maintain their colors, just add an underline.
2018-12-30 00:02:42 -08:00

429 lines
59 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Mu - 069hash.cc</title>
<meta name="Generator" content="Vim/8.0">
<meta name="plugin-version" content="vim7.4_v2">
<meta name="syntax" content="cpp">
<meta name="settings" content="number_lines,use_css,pre_wrap,no_foldcolumn,expand_tabs,line_ids,prevent_copy=">
<meta name="colorscheme" content="minimal-light">
<style type="text/css">
<!--
pre { white-space: pre-wrap; font-family: monospace; color: #000000; background-color: #c6c6c6; }
body { font-size:12pt; font-family: monospace; color: #000000; background-color: #c6c6c6; }
a { color:inherit; }
* { font-size:12pt; font-size: 1em; }
.CommentedCode { color: #8a8a8a; }
.muRecipe { color: #ff8700; }
.LineNr { }
.muData { color: #ffff00; }
.Constant { color: #008787; }
.Delimiter { color: #c000c0; }
.Special { color: #d70000; }
.Identifier { color: #af5f00; }
.Normal { color: #000000; background-color: #c6c6c6; padding-bottom: 1px; }
.Comment { color: #005faf; }
.traceContains { color: #005f00; }
-->
</style>
<script type='text/javascript'>
<!--
/* function to open any folds containing a jumped-to line before jumping to it */
function JumpToLine()
{
var lineNum;
lineNum = window.location.hash;
lineNum = lineNum.substr(1); /* strip off '#' */
if (lineNum.indexOf('L') == -1) {
lineNum = 'L'+lineNum;
}
lineElem = document.getElementById(lineNum);
/* Always jump to new location even if the line was hidden inside a fold, or
* we corrected the raw number to a line ID.
*/
if (lineElem) {
lineElem.scrollIntoView(true);
}
return true;
}
if ('onhashchange' in window) {
window.onhashchange = JumpToLine;
}
-->
</script>
</head>
<body onload='JumpToLine();'>
<a href='https://github.com/akkartik/mu/blob/master/069hash.cc'>https://github.com/akkartik/mu/blob/master/069hash.cc</a>
<pre id='vimCodeElement'>
<span id="L1" class="LineNr"> 1 </span><span class="Comment">// Compute a hash for objects of any type.</span>
<span id="L2" class="LineNr"> 2 </span><span class="Comment">//</span>
<span id="L3" class="LineNr"> 3 </span><span class="Comment">// The way it's currently implemented, two objects will have the same hash if</span>
<span id="L4" class="LineNr"> 4 </span><span class="Comment">// all their non-address fields (all the way down) expand to the same sequence</span>
<span id="L5" class="LineNr"> 5 </span><span class="Comment">// of scalar values. In particular, a container with all zero addresses hashes</span>
<span id="L6" class="LineNr"> 6 </span><span class="Comment">// to 0. Hopefully this won't be an issue because we are usually hashing</span>
<span id="L7" class="LineNr"> 7 </span><span class="Comment">// objects of a single type in any given hash table.</span>
<span id="L8" class="LineNr"> 8 </span><span class="Comment">//</span>
<span id="L9" class="LineNr"> 9 </span><span class="Comment">// Based on <a href="http://burtleburtle.net/bob/hash/hashfaq.html">http://burtleburtle.net/bob/hash/hashfaq.html</a></span>
<span id="L10" class="LineNr"> 10 </span>
<span id="L11" class="LineNr"> 11 </span><span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span>
<span id="L12" class="LineNr"> 12 </span>HASH<span class="Delimiter">,</span>
<span id="L13" class="LineNr"> 13 </span><span class="Delimiter">:(before &quot;End Primitive Recipe Numbers&quot;)</span>
<span id="L14" class="LineNr"> 14 </span><a href='001help.cc.html#L221'>put</a><span class="Delimiter">(</span><span class="Special">Recipe_ordinal</span><span class="Delimiter">,</span> <span class="Constant">&quot;hash&quot;</span><span class="Delimiter">,</span> HASH<span class="Delimiter">);</span>
<span id="L15" class="LineNr"> 15 </span><span class="Delimiter">:(before &quot;End Primitive Recipe Checks&quot;)</span>
<span id="L16" class="LineNr"> 16 </span><span class="Normal">case</span> HASH: <span class="Delimiter">{</span>
<span id="L17" class="LineNr"> 17 </span> <span class="Normal">if</span> <span class="Delimiter">(</span><a href='001help.cc.html#L141'>SIZE</a><span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span id="L18" class="LineNr"> 18 </span> <a href='003trace.cc.html#L196'>raise</a> &lt;&lt; <a href='013update_operation.cc.html#L25'>maybe</a><span class="Delimiter">(</span>get<span class="Delimiter">(</span><span class="Special">Recipe</span><span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'hash' takes exactly one ingredient rather than '&quot;</span> &lt;&lt; to_original_string<span class="Delimiter">(</span>inst<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'\n&quot;</span> &lt;&lt; <a href='003trace.cc.html#L225'>end</a><span class="Delimiter">();</span>
<span id="L19" class="LineNr"> 19 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L20" class="LineNr"> 20 </span> <span class="Delimiter">}</span>
<span id="L21" class="LineNr"> 21 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L22" class="LineNr"> 22 </span><span class="Delimiter">}</span>
<span id="L23" class="LineNr"> 23 </span><span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span>
<span id="L24" class="LineNr"> 24 </span><span class="Normal">case</span> HASH: <span class="Delimiter">{</span>
<span id="L25" class="LineNr"> 25 </span> <span class="Normal">const</span> reagent&amp; input = <a href='026call.cc.html#L89'>current_instruction</a><span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
<span id="L26" class="LineNr"> 26 </span> products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
<span id="L27" class="LineNr"> 27 </span> products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><a href='069hash.cc.html#L34'>hash</a><span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">,</span> input<span class="Delimiter">));</span>
<span id="L28" class="LineNr"> 28 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L29" class="LineNr"> 29 </span><span class="Delimiter">}</span>
<span id="L30" class="LineNr"> 30 </span>
<span id="L31" class="LineNr"> 31 </span><span class="Comment">//: in all the code below, the intermediate results of hashing are threaded through 'h'</span>
<span id="L32" class="LineNr"> 32 </span>
<span id="L33" class="LineNr"> 33 </span><span class="Delimiter">:(code)</span>
<span id="L34" class="LineNr"> 34 </span><span class="Normal">size_t</span> <a href='069hash.cc.html#L34'>hash</a><span class="Delimiter">(</span><span class="Normal">size_t</span> h<span class="Delimiter">,</span> reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span id="L35" class="LineNr"> 35 </span> <a href='035lookup.cc.html#L66'>canonize</a><span class="Delimiter">(</span>r<span class="Delimiter">);</span>
<span id="L36" class="LineNr"> 36 </span> <span class="Normal">if</span> <span class="Delimiter">(</span><a href='027call_ingredient.cc.html#L179'>is_mu_text</a><span class="Delimiter">(</span>r<span class="Delimiter">))</span> <span class="Comment">// optimization</span>
<span id="L37" class="LineNr"> 37 </span> <span class="Identifier">return</span> <a href='069hash.cc.html#L64'>hash_mu_text</a><span class="Delimiter">(</span>h<span class="Delimiter">,</span> r<span class="Delimiter">);</span>
<span id="L38" class="LineNr"> 38 </span> <span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_mu_address<span class="Delimiter">(</span>r<span class="Delimiter">))</span>
<span id="L39" class="LineNr"> 39 </span> <span class="Identifier">return</span> <a href='069hash.cc.html#L56'>hash_mu_address</a><span class="Delimiter">(</span>h<span class="Delimiter">,</span> r<span class="Delimiter">);</span>
<span id="L40" class="LineNr"> 40 </span> <span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_mu_scalar<span class="Delimiter">(</span>r<span class="Delimiter">))</span>
<span id="L41" class="LineNr"> 41 </span> <span class="Identifier">return</span> <a href='069hash.cc.html#L51'>hash_mu_scalar</a><span class="Delimiter">(</span>h<span class="Delimiter">,</span> r<span class="Delimiter">);</span>
<span id="L42" class="LineNr"> 42 </span> <span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_mu_array<span class="Delimiter">(</span>r<span class="Delimiter">))</span>
<span id="L43" class="LineNr"> 43 </span> <span class="Identifier">return</span> <a href='069hash.cc.html#L73'>hash_mu_array</a><span class="Delimiter">(</span>h<span class="Delimiter">,</span> r<span class="Delimiter">);</span>
<span id="L44" class="LineNr"> 44 </span> <span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_mu_container<span class="Delimiter">(</span>r<span class="Delimiter">))</span>
<span id="L45" class="LineNr"> 45 </span> <span class="Identifier">return</span> <a href='069hash.cc.html#L87'>hash_mu_container</a><span class="Delimiter">(</span>h<span class="Delimiter">,</span> r<span class="Delimiter">);</span>
<span id="L46" class="LineNr"> 46 </span> <span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_mu_exclusive_container<span class="Delimiter">(</span>r<span class="Delimiter">))</span>
<span id="L47" class="LineNr"> 47 </span> <span class="Identifier">return</span> <a href='069hash.cc.html#L102'>hash_mu_exclusive_container</a><span class="Delimiter">(</span>h<span class="Delimiter">,</span> r<span class="Delimiter">);</span>
<span id="L48" class="LineNr"> 48 </span> assert<span class="Delimiter">(</span><span class="Constant">false</span><span class="Delimiter">);</span>
<span id="L49" class="LineNr"> 49 </span><span class="Delimiter">}</span>
<span id="L50" class="LineNr"> 50 </span>
<span id="L51" class="LineNr"> 51 </span><span class="Normal">size_t</span> <a href='069hash.cc.html#L51'>hash_mu_scalar</a><span class="Delimiter">(</span><span class="Normal">size_t</span> h<span class="Delimiter">,</span> <span class="Normal">const</span> reagent&amp; r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span id="L52" class="LineNr"> 52 </span> <span class="Normal">double</span> input = is_literal<span class="Delimiter">(</span>r<span class="Delimiter">)</span> ? r<span class="Delimiter">.</span>value : <a href='001help.cc.html#L229'>get_or_insert</a><span class="Delimiter">(</span><span class="Special">Memory</span><span class="Delimiter">,</span> r<span class="Delimiter">.</span>value<span class="Delimiter">);</span>
<span id="L53" class="LineNr"> 53 </span> <span class="Identifier">return</span> <a href='069hash.cc.html#L115'>hash_iter</a><span class="Delimiter">(</span>h<span class="Delimiter">,</span> <span class="Normal">static_cast</span>&lt;<span class="Normal">size_t</span>&gt;<span class="Delimiter">(</span>input<span class="Delimiter">));</span>
<span id="L54" class="LineNr"> 54 </span><span class="Delimiter">}</span>
<span id="L55" class="LineNr"> 55 </span>
<span id="L56" class="LineNr"> 56 </span><span class="Normal">size_t</span> <a href='069hash.cc.html#L56'>hash_mu_address</a><span class="Delimiter">(</span><span class="Normal">size_t</span> h<span class="Delimiter">,</span> reagent&amp; r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span id="L57" class="LineNr"> 57 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>r<span class="Delimiter">.</span>value == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span>
<span id="L58" class="LineNr"> 58 </span> <a href='003trace.cc.html#L189'>trace</a><span class="Delimiter">(</span><span class="Constant">&quot;mem&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;location &quot;</span> &lt;&lt; r<span class="Delimiter">.</span>value &lt;&lt; <span class="Constant">&quot; is &quot;</span> &lt;&lt; no_scientific<span class="Delimiter">(</span><a href='001help.cc.html#L229'>get_or_insert</a><span class="Delimiter">(</span><span class="Special">Memory</span><span class="Delimiter">,</span> r<span class="Delimiter">.</span>value<span class="Delimiter">))</span> &lt;&lt; <a href='003trace.cc.html#L225'>end</a><span class="Delimiter">();</span>
<span id="L59" class="LineNr"> 59 </span> r<span class="Delimiter">.</span><a href='010vm.cc.html#L67'>set_value</a><span class="Delimiter">(</span><a href='001help.cc.html#L229'>get_or_insert</a><span class="Delimiter">(</span><span class="Special">Memory</span><span class="Delimiter">,</span> r<span class="Delimiter">.</span>value<span class="Delimiter">));</span>
<span id="L60" class="LineNr"> 60 </span> drop_from_type<span class="Delimiter">(</span>r<span class="Delimiter">,</span> <span class="Constant">&quot;address&quot;</span><span class="Delimiter">);</span>
<span id="L61" class="LineNr"> 61 </span> <span class="Identifier">return</span> <a href='069hash.cc.html#L34'>hash</a><span class="Delimiter">(</span>h<span class="Delimiter">,</span> r<span class="Delimiter">);</span>
<span id="L62" class="LineNr"> 62 </span><span class="Delimiter">}</span>
<span id="L63" class="LineNr"> 63 </span>
<span id="L64" class="LineNr"> 64 </span><span class="Normal">size_t</span> <a href='069hash.cc.html#L64'>hash_mu_text</a><span class="Delimiter">(</span><span class="Normal">size_t</span> h<span class="Delimiter">,</span> <span class="Normal">const</span> reagent&amp; r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span id="L65" class="LineNr"> 65 </span> string input = <a href='038new_text.cc.html#L142'>read_mu_text</a><span class="Delimiter">(</span><a href='001help.cc.html#L229'>get_or_insert</a><span class="Delimiter">(</span><span class="Special">Memory</span><span class="Delimiter">,</span> r<span class="Delimiter">.</span>value+<span class="Comment">/*</span><span class="Comment">skip alloc id</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">));</span>
<span id="L66" class="LineNr"> 66 </span> <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; <a href='001help.cc.html#L141'>SIZE</a><span class="Delimiter">(</span>input<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span id="L67" class="LineNr"> 67 </span> h = <a href='069hash.cc.html#L115'>hash_iter</a><span class="Delimiter">(</span>h<span class="Delimiter">,</span> <span class="Normal">static_cast</span>&lt;<span class="Normal">size_t</span>&gt;<span class="Delimiter">(</span>input<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)));</span>
<span id="L68" class="LineNr"> 68 </span><span class="CommentedCode">//? cerr &lt;&lt; i &lt;&lt; &quot;: &quot; &lt;&lt; h &lt;&lt; '\n';</span>
<span id="L69" class="LineNr"> 69 </span> <span class="Delimiter">}</span>
<span id="L70" class="LineNr"> 70 </span> <span class="Identifier">return</span> h<span class="Delimiter">;</span>
<span id="L71" class="LineNr"> 71 </span><span class="Delimiter">}</span>
<span id="L72" class="LineNr"> 72 </span>
<span id="L73" class="LineNr"> 73 </span><span class="Normal">size_t</span> <a href='069hash.cc.html#L73'>hash_mu_array</a><span class="Delimiter">(</span><span class="Normal">size_t</span> h<span class="Delimiter">,</span> <span class="Normal">const</span> reagent&amp; r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span id="L74" class="LineNr"> 74 </span> <span class="Normal">int</span> size = <a href='001help.cc.html#L229'>get_or_insert</a><span class="Delimiter">(</span><span class="Special">Memory</span><span class="Delimiter">,</span> r<span class="Delimiter">.</span>value<span class="Delimiter">);</span>
<span id="L75" class="LineNr"> 75 </span> reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> elem = r<span class="Delimiter">;</span>
<span id="L76" class="LineNr"> 76 </span> <span class="Normal">delete</span> elem<span class="Delimiter">.</span>type<span class="Delimiter">;</span>
<span id="L77" class="LineNr"> 77 </span> elem<span class="Delimiter">.</span>type = <a href='032array.cc.html#L299'>copy_array_element</a><span class="Delimiter">(</span>r<span class="Delimiter">.</span>type<span class="Delimiter">);</span>
<span id="L78" class="LineNr"> 78 </span> <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i=<span class="Constant">0</span><span class="Delimiter">,</span> <a href='043space.cc.html#L101'>address</a> = r<span class="Delimiter">.</span>value+<span class="Constant">1</span><span class="Delimiter">;</span> i &lt; size<span class="Delimiter">;</span> ++i<span class="Delimiter">,</span> <a href='043space.cc.html#L101'>address</a> += size_of<span class="Delimiter">(</span>elem<span class="Delimiter">))</span> <span class="Delimiter">{</span>
<span id="L79" class="LineNr"> 79 </span> reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> tmp = elem<span class="Delimiter">;</span>
<span id="L80" class="LineNr"> 80 </span> tmp<span class="Delimiter">.</span><a href='010vm.cc.html#L67'>set_value</a><span class="Delimiter">(</span><a href='043space.cc.html#L101'>address</a><span class="Delimiter">);</span>
<span id="L81" class="LineNr"> 81 </span> h = <a href='069hash.cc.html#L34'>hash</a><span class="Delimiter">(</span>h<span class="Delimiter">,</span> tmp<span class="Delimiter">);</span>
<span id="L82" class="LineNr"> 82 </span><span class="CommentedCode">//? cerr &lt;&lt; i &lt;&lt; &quot; (&quot; &lt;&lt; address &lt;&lt; &quot;): &quot; &lt;&lt; h &lt;&lt; '\n';</span>
<span id="L83" class="LineNr"> 83 </span> <span class="Delimiter">}</span>
<span id="L84" class="LineNr"> 84 </span> <span class="Identifier">return</span> h<span class="Delimiter">;</span>
<span id="L85" class="LineNr"> 85 </span><span class="Delimiter">}</span>
<span id="L86" class="LineNr"> 86 </span>
<span id="L87" class="LineNr"> 87 </span><span class="Normal">size_t</span> <a href='069hash.cc.html#L87'>hash_mu_container</a><span class="Delimiter">(</span><span class="Normal">size_t</span> h<span class="Delimiter">,</span> <span class="Normal">const</span> reagent&amp; r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span id="L88" class="LineNr"> 88 </span> type_info&amp; info = get<span class="Delimiter">(</span><span class="Special">Type</span><span class="Delimiter">,</span> get_base_type<span class="Delimiter">(</span>r<span class="Delimiter">.</span>type<span class="Delimiter">)-&gt;</span>value<span class="Delimiter">);</span>
<span id="L89" class="LineNr"> 89 </span> <span class="Normal">int</span> <a href='043space.cc.html#L101'>address</a> = r<span class="Delimiter">.</span>value<span class="Delimiter">;</span>
<span id="L90" class="LineNr"> 90 </span> <span class="Normal">int</span> offset = <span class="Constant">0</span><span class="Delimiter">;</span>
<span id="L91" class="LineNr"> 91 </span> <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; <a href='001help.cc.html#L141'>SIZE</a><span class="Delimiter">(</span>info<span class="Delimiter">.</span>elements<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span id="L92" class="LineNr"> 92 </span> reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> element = <a href='030container.cc.html#L212'>element_type</a><span class="Delimiter">(</span>r<span class="Delimiter">.</span>type<span class="Delimiter">,</span> i<span class="Delimiter">);</span>
<span id="L93" class="LineNr"> 93 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>has_property<span class="Delimiter">(</span>element<span class="Delimiter">,</span> <span class="Constant">&quot;ignore-for-hash&quot;</span><span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
<span id="L94" class="LineNr"> 94 </span> element<span class="Delimiter">.</span><a href='010vm.cc.html#L67'>set_value</a><span class="Delimiter">(</span>address+offset<span class="Delimiter">);</span>
<span id="L95" class="LineNr"> 95 </span> h = <a href='069hash.cc.html#L34'>hash</a><span class="Delimiter">(</span>h<span class="Delimiter">,</span> element<span class="Delimiter">);</span>
<span id="L96" class="LineNr"> 96 </span><span class="CommentedCode">//? cerr &lt;&lt; i &lt;&lt; &quot;: &quot; &lt;&lt; h &lt;&lt; '\n';</span>
<span id="L97" class="LineNr"> 97 </span> offset += size_of<span class="Delimiter">(</span>info<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type<span class="Delimiter">);</span>
<span id="L98" class="LineNr"> 98 </span> <span class="Delimiter">}</span>
<span id="L99" class="LineNr"> 99 </span> <span class="Identifier">return</span> h<span class="Delimiter">;</span>
<span id="L100" class="LineNr">100 </span><span class="Delimiter">}</span>
<span id="L101" class="LineNr">101 </span>
<span id="L102" class="LineNr">102 </span><span class="Normal">size_t</span> <a href='069hash.cc.html#L102'>hash_mu_exclusive_container</a><span class="Delimiter">(</span><span class="Normal">size_t</span> h<span class="Delimiter">,</span> <span class="Normal">const</span> reagent&amp; r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span id="L103" class="LineNr">103 </span> <span class="Normal">const</span> type_tree* type = get_base_type<span class="Delimiter">(</span>r<span class="Delimiter">.</span>type<span class="Delimiter">);</span>
<span id="L104" class="LineNr">104 </span> assert<span class="Delimiter">(</span>type<span class="Delimiter">-&gt;</span>value<span class="Delimiter">);</span>
<span id="L105" class="LineNr">105 </span> <span class="Normal">int</span> tag = get<span class="Delimiter">(</span><span class="Special">Memory</span><span class="Delimiter">,</span> r<span class="Delimiter">.</span>value<span class="Delimiter">);</span>
<span id="L106" class="LineNr">106 </span> reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> variant = variant_type<span class="Delimiter">(</span>r<span class="Delimiter">,</span> tag<span class="Delimiter">);</span>
<span id="L107" class="LineNr">107 </span> <span class="Comment">// todo: move this error to container definition time</span>
<span id="L108" class="LineNr">108 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>has_property<span class="Delimiter">(</span>variant<span class="Delimiter">,</span> <span class="Constant">&quot;ignore-for-hash&quot;</span><span class="Delimiter">))</span>
<span id="L109" class="LineNr">109 </span> <a href='003trace.cc.html#L196'>raise</a> &lt;&lt; get<span class="Delimiter">(</span><span class="Special">Type</span><span class="Delimiter">,</span> type<span class="Delimiter">-&gt;</span>value<span class="Delimiter">).</span>name &lt;&lt; <span class="Constant">&quot;: /ignore-for-hash won't work in exclusive containers\n&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
<span id="L110" class="LineNr">110 </span> variant<span class="Delimiter">.</span><a href='010vm.cc.html#L67'>set_value</a><span class="Delimiter">(</span>r<span class="Delimiter">.</span>value + <span class="Comment">/*</span><span class="Comment">skip tag</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">);</span>
<span id="L111" class="LineNr">111 </span> h = <a href='069hash.cc.html#L34'>hash</a><span class="Delimiter">(</span>h<span class="Delimiter">,</span> variant<span class="Delimiter">);</span>
<span id="L112" class="LineNr">112 </span> <span class="Identifier">return</span> h<span class="Delimiter">;</span>
<span id="L113" class="LineNr">113 </span><span class="Delimiter">}</span>
<span id="L114" class="LineNr">114 </span>
<span id="L115" class="LineNr">115 </span><span class="Normal">size_t</span> <a href='069hash.cc.html#L115'>hash_iter</a><span class="Delimiter">(</span><span class="Normal">size_t</span> h<span class="Delimiter">,</span> <span class="Normal">size_t</span> input<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span id="L116" class="LineNr">116 </span> h += input<span class="Delimiter">;</span>
<span id="L117" class="LineNr">117 </span> h += <span class="Delimiter">(</span>h&lt;&lt;<span class="Constant">10</span><span class="Delimiter">);</span>
<span id="L118" class="LineNr">118 </span> h ^= <span class="Delimiter">(</span>h&gt;&gt;<span class="Constant">6</span><span class="Delimiter">);</span>
<span id="L119" class="LineNr">119 </span>
<span id="L120" class="LineNr">120 </span> h += <span class="Delimiter">(</span>h&lt;&lt;<span class="Constant">3</span><span class="Delimiter">);</span>
<span id="L121" class="LineNr">121 </span> h ^= <span class="Delimiter">(</span>h&gt;&gt;<span class="Constant">11</span><span class="Delimiter">);</span>
<span id="L122" class="LineNr">122 </span> h += <span class="Delimiter">(</span>h&lt;&lt;<span class="Constant">15</span><span class="Delimiter">);</span>
<span id="L123" class="LineNr">123 </span> <span class="Identifier">return</span> h<span class="Delimiter">;</span>
<span id="L124" class="LineNr">124 </span><span class="Delimiter">}</span>
<span id="L125" class="LineNr">125 </span>
<span id="L126" class="LineNr">126 </span><span class="Delimiter">:(scenario hash_container_checks_all_elements)</span>
<span id="L127" class="LineNr">127 </span><span class="muData">container</span> foo [
<span id="L128" class="LineNr">128 </span> <span class="Normal">x</span>:num
<span id="L129" class="LineNr">129 </span> <span class="Normal">y</span>:<span class="Normal">char</span>
<span id="L130" class="LineNr">130 </span>]
<span id="L131" class="LineNr">131 </span><span class="muRecipe">def</span> <a href='000organization.cc.html#L113'>main</a> [
<span id="L132" class="LineNr">132 </span> <span class="Constant">1</span>:foo<span class="Special"> &lt;- </span>merge <span class="Constant">34</span><span class="Delimiter">,</span> <span class="Constant">97</span>/a
<span id="L133" class="LineNr">133 </span> <span class="Constant">3</span>:num<span class="Special"> &lt;- </span><a href='069hash.cc.html#L34'>hash</a> <span class="Constant">1</span>:foo
<span id="L134" class="LineNr">134 </span> <span class="Identifier">return</span>-unless <span class="Constant">3</span>:num
<span id="L135" class="LineNr">135 </span> <span class="Constant">4</span>:foo<span class="Special"> &lt;- </span>merge <span class="Constant">34</span><span class="Delimiter">,</span> <span class="Constant">98</span>/a
<span id="L136" class="LineNr">136 </span> <span class="Constant">6</span>:num<span class="Special"> &lt;- </span><a href='069hash.cc.html#L34'>hash</a> <span class="Constant">4</span>:foo
<span id="L137" class="LineNr">137 </span> <span class="Identifier">return</span>-unless <span class="Constant">6</span>:num
<span id="L138" class="LineNr">138 </span> <span class="Constant">7</span>:<span class="Normal">bool</span><span class="Special"> &lt;- </span>equal <span class="Constant">3</span>:num<span class="Delimiter">,</span> <span class="Constant">6</span>:num
<span id="L139" class="LineNr">139 </span>]
<span id="L140" class="LineNr">140 </span><span class="Comment"># hash on containers includes all elements</span>
<span id="L141" class="LineNr">141 </span><span class="traceContains">+mem: storing 0 in location 7</span>
<span id="L142" class="LineNr">142 </span>
<span id="L143" class="LineNr">143 </span><span class="Delimiter">:(scenario hash_exclusive_container_checks_all_elements)</span>
<span id="L144" class="LineNr">144 </span><span class="muData">exclusive-container</span> foo [
<span id="L145" class="LineNr">145 </span> <span class="Normal">x</span>:bar
<span id="L146" class="LineNr">146 </span> <span class="Normal">y</span>:num
<span id="L147" class="LineNr">147 </span>]
<span id="L148" class="LineNr">148 </span><span class="muData">container</span> bar [
<span id="L149" class="LineNr">149 </span> <span class="Normal">a</span>:num
<span id="L150" class="LineNr">150 </span> <span class="Normal">b</span>:num
<span id="L151" class="LineNr">151 </span>]
<span id="L152" class="LineNr">152 </span><span class="muRecipe">def</span> <a href='000organization.cc.html#L113'>main</a> [
<span id="L153" class="LineNr">153 </span> <span class="Constant">1</span>:foo<span class="Special"> &lt;- </span>merge <span class="Constant">0</span>/x<span class="Delimiter">,</span> <span class="Constant">34</span><span class="Delimiter">,</span> <span class="Constant">35</span>
<span id="L154" class="LineNr">154 </span> <span class="Constant">4</span>:num<span class="Special"> &lt;- </span><a href='069hash.cc.html#L34'>hash</a> <span class="Constant">1</span>:foo
<span id="L155" class="LineNr">155 </span> <span class="Identifier">return</span>-unless <span class="Constant">4</span>:num
<span id="L156" class="LineNr">156 </span> <span class="Constant">5</span>:foo<span class="Special"> &lt;- </span>merge <span class="Constant">0</span>/x<span class="Delimiter">,</span> <span class="Constant">34</span><span class="Delimiter">,</span> <span class="Constant">36</span>
<span id="L157" class="LineNr">157 </span> <span class="Constant">8</span>:num<span class="Special"> &lt;- </span><a href='069hash.cc.html#L34'>hash</a> <span class="Constant">5</span>:foo
<span id="L158" class="LineNr">158 </span> <span class="Identifier">return</span>-unless <span class="Constant">8</span>:num
<span id="L159" class="LineNr">159 </span> <span class="Constant">9</span>:<span class="Normal">bool</span><span class="Special"> &lt;- </span>equal <span class="Constant">4</span>:num<span class="Delimiter">,</span> <span class="Constant">8</span>:num
<span id="L160" class="LineNr">160 </span>]
<span id="L161" class="LineNr">161 </span><span class="Comment"># hash on containers includes all elements</span>
<span id="L162" class="LineNr">162 </span><span class="traceContains">+mem: storing 0 in location 9</span>
<span id="L163" class="LineNr">163 </span>
<span id="L164" class="LineNr">164 </span><span class="Delimiter">:(scenario hash_can_ignore_container_elements)</span>
<span id="L165" class="LineNr">165 </span><span class="muData">container</span> foo [
<span id="L166" class="LineNr">166 </span> <span class="Normal">x</span>:num
<span id="L167" class="LineNr">167 </span> <span class="Normal">y</span>:<span class="Normal">char</span>/ignore-<span class="Normal">for</span>-hash
<span id="L168" class="LineNr">168 </span>]
<span id="L169" class="LineNr">169 </span><span class="muRecipe">def</span> <a href='000organization.cc.html#L113'>main</a> [
<span id="L170" class="LineNr">170 </span> <span class="Constant">1</span>:foo<span class="Special"> &lt;- </span>merge <span class="Constant">34</span><span class="Delimiter">,</span> <span class="Constant">97</span>/a
<span id="L171" class="LineNr">171 </span> <span class="Constant">3</span>:num<span class="Special"> &lt;- </span><a href='069hash.cc.html#L34'>hash</a> <span class="Constant">1</span>:foo
<span id="L172" class="LineNr">172 </span> <span class="Identifier">return</span>-unless <span class="Constant">3</span>:num
<span id="L173" class="LineNr">173 </span> <span class="Constant">4</span>:foo<span class="Special"> &lt;- </span>merge <span class="Constant">34</span><span class="Delimiter">,</span> <span class="Constant">98</span>/a
<span id="L174" class="LineNr">174 </span> <span class="Constant">6</span>:num<span class="Special"> &lt;- </span><a href='069hash.cc.html#L34'>hash</a> <span class="Constant">4</span>:foo
<span id="L175" class="LineNr">175 </span> <span class="Identifier">return</span>-unless <span class="Constant">6</span>:num
<span id="L176" class="LineNr">176 </span> <span class="Constant">7</span>:<span class="Normal">bool</span><span class="Special"> &lt;- </span>equal <span class="Constant">3</span>:num<span class="Delimiter">,</span> <span class="Constant">6</span>:num
<span id="L177" class="LineNr">177 </span>]
<span id="L178" class="LineNr">178 </span><span class="Comment"># hashes match even though y is different</span>
<span id="L179" class="LineNr">179 </span><span class="traceContains">+mem: storing 1 in location 7</span>
<span id="L180" class="LineNr">180 </span>
<span id="L181" class="LineNr">181 </span><span class="Comment">//: These properties aren't necessary for hash, they just test that the</span>
<span id="L182" class="LineNr">182 </span><span class="Comment">//: current implementation works like we think it does.</span>
<span id="L183" class="LineNr">183 </span>
<span id="L184" class="LineNr">184 </span><span class="Delimiter">:(scenario hash_of_zero_address)</span>
<span id="L185" class="LineNr">185 </span><span class="muRecipe">def</span> <a href='000organization.cc.html#L113'>main</a> [
<span id="L186" class="LineNr">186 </span> <span class="Constant">1</span>:&amp;:num<span class="Special"> &lt;- </span>copy<span class="Constant"> null</span>
<span id="L187" class="LineNr">187 </span> <span class="Constant">2</span>:num<span class="Special"> &lt;- </span><a href='069hash.cc.html#L34'>hash</a> <span class="Constant">1</span>:&amp;:num
<span id="L188" class="LineNr">188 </span>]
<span id="L189" class="LineNr">189 </span><span class="traceContains">+mem: storing 0 in location 2</span>
<span id="L190" class="LineNr">190 </span>
<span id="L191" class="LineNr">191 </span><span class="Comment">//: This is probably too aggressive, but we need some way to avoid depending</span>
<span id="L192" class="LineNr">192 </span><span class="Comment">//: on the precise bit pattern of a floating-point number.</span>
<span id="L193" class="LineNr">193 </span><span class="Delimiter">:(scenario hash_of_numbers_ignores_fractional_part)</span>
<span id="L194" class="LineNr">194 </span><span class="muRecipe">def</span> <a href='000organization.cc.html#L113'>main</a> [
<span id="L195" class="LineNr">195 </span> <span class="Constant">1</span>:num<span class="Special"> &lt;- </span><a href='069hash.cc.html#L34'>hash</a> <span class="Constant">1.5</span>
<span id="L196" class="LineNr">196 </span> <span class="Constant">2</span>:num<span class="Special"> &lt;- </span><a href='069hash.cc.html#L34'>hash</a> <span class="Constant">1</span>
<span id="L197" class="LineNr">197 </span> <span class="Constant">3</span>:<span class="Normal">bool</span><span class="Special"> &lt;- </span>equal <span class="Constant">1</span>:num<span class="Delimiter">,</span> <span class="Constant">2</span>:num
<span id="L198" class="LineNr">198 </span>]
<span id="L199" class="LineNr">199 </span><span class="traceContains">+mem: storing 1 in location 3</span>
<span id="L200" class="LineNr">200 </span>
<span id="L201" class="LineNr">201 </span><span class="Delimiter">:(scenario hash_of_array_same_as_string)</span>
<span id="L202" class="LineNr">202 </span><span class="muRecipe">def</span> <a href='000organization.cc.html#L113'>main</a> [
<span id="L203" class="LineNr">203 </span> <span class="Constant">10</span>:num<span class="Special"> &lt;- </span>copy <span class="Constant">3</span>
<span id="L204" class="LineNr">204 </span> <span class="Constant">11</span>:num<span class="Special"> &lt;- </span>copy <span class="Constant">97</span>
<span id="L205" class="LineNr">205 </span> <span class="Constant">12</span>:num<span class="Special"> &lt;- </span>copy <span class="Constant">98</span>
<span id="L206" class="LineNr">206 </span> <span class="Constant">13</span>:num<span class="Special"> &lt;- </span>copy <span class="Constant">99</span>
<span id="L207" class="LineNr">207 </span> <span class="Constant">2</span>:num<span class="Special"> &lt;- </span><a href='069hash.cc.html#L34'>hash</a> <span class="Constant">10</span>:@:num/unsafe
<span id="L208" class="LineNr">208 </span> <span class="Identifier">return</span>-unless <span class="Constant">2</span>:num
<span id="L209" class="LineNr">209 </span> <span class="Constant">3</span>:text<span class="Special"> &lt;- </span><span class="Normal">new</span> [abc]
<span id="L210" class="LineNr">210 </span> <span class="Constant">4</span>:num<span class="Special"> &lt;- </span><a href='069hash.cc.html#L34'>hash</a> <span class="Constant">3</span>:text
<span id="L211" class="LineNr">211 </span> <span class="Identifier">return</span>-unless <span class="Constant">4</span>:num
<span id="L212" class="LineNr">212 </span> <span class="Constant">5</span>:<span class="Normal">bool</span><span class="Special"> &lt;- </span>equal <span class="Constant">2</span>:num<span class="Delimiter">,</span> <span class="Constant">4</span>:num
<span id="L213" class="LineNr">213 </span>]
<span id="L214" class="LineNr">214 </span><span class="traceContains">+mem: storing 1 in location 5</span>
<span id="L215" class="LineNr">215 </span>
<span id="L216" class="LineNr">216 </span><span class="Delimiter">:(scenario hash_ignores_address_value)</span>
<span id="L217" class="LineNr">217 </span><span class="muRecipe">def</span> <a href='000organization.cc.html#L113'>main</a> [
<span id="L218" class="LineNr">218 </span> <span class="Constant">1</span>:&amp;:num<span class="Special"> &lt;- </span><span class="Normal">new</span> <span class="Constant">number:type</span>
<span id="L219" class="LineNr">219 </span> *<span class="Constant">1</span>:&amp;:num<span class="Special"> &lt;- </span>copy <span class="Constant">34</span>
<span id="L220" class="LineNr">220 </span> <span class="Constant">2</span>:num<span class="Special"> &lt;- </span><a href='069hash.cc.html#L34'>hash</a> <span class="Constant">1</span>:&amp;:num
<span id="L221" class="LineNr">221 </span> <span class="Constant">3</span>:&amp;:num<span class="Special"> &lt;- </span><span class="Normal">new</span> <span class="Constant">number:type</span>
<span id="L222" class="LineNr">222 </span> *<span class="Constant">3</span>:&amp;:num<span class="Special"> &lt;- </span>copy <span class="Constant">34</span>
<span id="L223" class="LineNr">223 </span> <span class="Constant">4</span>:num<span class="Special"> &lt;- </span><a href='069hash.cc.html#L34'>hash</a> <span class="Constant">3</span>:&amp;:num
<span id="L224" class="LineNr">224 </span> <span class="Constant">5</span>:<span class="Normal">bool</span><span class="Special"> &lt;- </span>equal <span class="Constant">2</span>:num<span class="Delimiter">,</span> <span class="Constant">4</span>:num
<span id="L225" class="LineNr">225 </span>]
<span id="L226" class="LineNr">226 </span><span class="Comment"># different addresses hash to the same result as long as the values the point to do so</span>
<span id="L227" class="LineNr">227 </span><span class="traceContains">+mem: storing 1 in location 5</span>
<span id="L228" class="LineNr">228 </span>
<span id="L229" class="LineNr">229 </span><span class="Delimiter">:(scenario hash_container_depends_only_on_elements)</span>
<span id="L230" class="LineNr">230 </span><span class="muData">container</span> foo [
<span id="L231" class="LineNr">231 </span> <span class="Normal">x</span>:num
<span id="L232" class="LineNr">232 </span> <span class="Normal">y</span>:<span class="Normal">char</span>
<span id="L233" class="LineNr">233 </span>]
<span id="L234" class="LineNr">234 </span><span class="muData">container</span> bar [
<span id="L235" class="LineNr">235 </span> <span class="Normal">x</span>:num
<span id="L236" class="LineNr">236 </span> <span class="Normal">y</span>:<span class="Normal">char</span>
<span id="L237" class="LineNr">237 </span>]
<span id="L238" class="LineNr">238 </span><span class="muRecipe">def</span> <a href='000organization.cc.html#L113'>main</a> [
<span id="L239" class="LineNr">239 </span> <span class="Constant">1</span>:foo<span class="Special"> &lt;- </span>merge <span class="Constant">34</span><span class="Delimiter">,</span> <span class="Constant">97</span>/a
<span id="L240" class="LineNr">240 </span> <span class="Constant">3</span>:num<span class="Special"> &lt;- </span><a href='069hash.cc.html#L34'>hash</a> <span class="Constant">1</span>:foo
<span id="L241" class="LineNr">241 </span> <span class="Identifier">return</span>-unless <span class="Constant">3</span>:num
<span id="L242" class="LineNr">242 </span> <span class="Constant">4</span>:bar<span class="Special"> &lt;- </span>merge <span class="Constant">34</span><span class="Delimiter">,</span> <span class="Constant">97</span>/a
<span id="L243" class="LineNr">243 </span> <span class="Constant">6</span>:num<span class="Special"> &lt;- </span><a href='069hash.cc.html#L34'>hash</a> <span class="Constant">4</span>:bar
<span id="L244" class="LineNr">244 </span> <span class="Identifier">return</span>-unless <span class="Constant">6</span>:num
<span id="L245" class="LineNr">245 </span> <span class="Constant">7</span>:<span class="Normal">bool</span><span class="Special"> &lt;- </span>equal <span class="Constant">3</span>:num<span class="Delimiter">,</span> <span class="Constant">6</span>:num
<span id="L246" class="LineNr">246 </span>]
<span id="L247" class="LineNr">247 </span><span class="Comment"># containers with identical elements return identical hashes</span>
<span id="L248" class="LineNr">248 </span><span class="traceContains">+mem: storing 1 in location 7</span>
<span id="L249" class="LineNr">249 </span>
<span id="L250" class="LineNr">250 </span><span class="Delimiter">:(scenario hash_container_depends_only_on_elements_2)</span>
<span id="L251" class="LineNr">251 </span><span class="muData">container</span> foo [
<span id="L252" class="LineNr">252 </span> <span class="Normal">x</span>:num
<span id="L253" class="LineNr">253 </span> <span class="Normal">y</span>:<span class="Normal">char</span>
<span id="L254" class="LineNr">254 </span> <span class="Normal">z</span>:&amp;:num
<span id="L255" class="LineNr">255 </span>]
<span id="L256" class="LineNr">256 </span><span class="muRecipe">def</span> <a href='000organization.cc.html#L113'>main</a> [
<span id="L257" class="LineNr">257 </span> <span class="Constant">1</span>:&amp;:num<span class="Special"> &lt;- </span><span class="Normal">new</span> <span class="Constant">number:type</span>
<span id="L258" class="LineNr">258 </span> *<span class="Constant">1</span>:&amp;:num<span class="Special"> &lt;- </span>copy <span class="Constant">34</span>
<span id="L259" class="LineNr">259 </span> <span class="Constant">2</span>:foo<span class="Special"> &lt;- </span>merge <span class="Constant">34</span><span class="Delimiter">,</span> <span class="Constant">97</span>/a<span class="Delimiter">,</span> <span class="Constant">1</span>:&amp;:num
<span id="L260" class="LineNr">260 </span> <span class="Constant">5</span>:num<span class="Special"> &lt;- </span><a href='069hash.cc.html#L34'>hash</a> <span class="Constant">2</span>:foo
<span id="L261" class="LineNr">261 </span> <span class="Identifier">return</span>-unless <span class="Constant">5</span>:num
<span id="L262" class="LineNr">262 </span> <span class="Constant">6</span>:&amp;:num<span class="Special"> &lt;- </span><span class="Normal">new</span> <span class="Constant">number:type</span>
<span id="L263" class="LineNr">263 </span> *<span class="Constant">6</span>:&amp;:num<span class="Special"> &lt;- </span>copy <span class="Constant">34</span>
<span id="L264" class="LineNr">264 </span> <span class="Constant">7</span>:foo<span class="Special"> &lt;- </span>merge <span class="Constant">34</span><span class="Delimiter">,</span> <span class="Constant">97</span>/a<span class="Delimiter">,</span> <span class="Constant">6</span>:&amp;:num
<span id="L265" class="LineNr">265 </span> <span class="Constant">10</span>:num<span class="Special"> &lt;- </span><a href='069hash.cc.html#L34'>hash</a> <span class="Constant">7</span>:foo
<span id="L266" class="LineNr">266 </span> <span class="Identifier">return</span>-unless <span class="Constant">10</span>:num
<span id="L267" class="LineNr">267 </span> <span class="Constant">11</span>:<span class="Normal">bool</span><span class="Special"> &lt;- </span>equal <span class="Constant">5</span>:num<span class="Delimiter">,</span> <span class="Constant">10</span>:num
<span id="L268" class="LineNr">268 </span>]
<span id="L269" class="LineNr">269 </span><span class="Comment"># containers with identical 'leaf' elements return identical hashes</span>
<span id="L270" class="LineNr">270 </span><span class="traceContains">+mem: storing 1 in location 11</span>
<span id="L271" class="LineNr">271 </span>
<span id="L272" class="LineNr">272 </span><span class="Delimiter">:(scenario hash_container_depends_only_on_elements_3)</span>
<span id="L273" class="LineNr">273 </span><span class="muData">container</span> foo [
<span id="L274" class="LineNr">274 </span> <span class="Normal">x</span>:num
<span id="L275" class="LineNr">275 </span> <span class="Normal">y</span>:<span class="Normal">char</span>
<span id="L276" class="LineNr">276 </span> <span class="Normal">z</span>:bar
<span id="L277" class="LineNr">277 </span>]
<span id="L278" class="LineNr">278 </span><span class="muData">container</span> bar [
<span id="L279" class="LineNr">279 </span> <span class="Normal">x</span>:num
<span id="L280" class="LineNr">280 </span> <span class="Normal">y</span>:num
<span id="L281" class="LineNr">281 </span>]
<span id="L282" class="LineNr">282 </span><span class="muRecipe">def</span> <a href='000organization.cc.html#L113'>main</a> [
<span id="L283" class="LineNr">283 </span> <span class="Constant">1</span>:foo<span class="Special"> &lt;- </span>merge <span class="Constant">34</span><span class="Delimiter">,</span> <span class="Constant">97</span>/a<span class="Delimiter">,</span> <span class="Constant">47</span><span class="Delimiter">,</span> <span class="Constant">48</span>
<span id="L284" class="LineNr">284 </span> <span class="Constant">6</span>:num<span class="Special"> &lt;- </span><a href='069hash.cc.html#L34'>hash</a> <span class="Constant">1</span>:foo
<span id="L285" class="LineNr">285 </span> <span class="Identifier">return</span>-unless <span class="Constant">6</span>:num
<span id="L286" class="LineNr">286 </span> <span class="Constant">7</span>:foo<span class="Special"> &lt;- </span>merge <span class="Constant">34</span><span class="Delimiter">,</span> <span class="Constant">97</span>/a<span class="Delimiter">,</span> <span class="Constant">47</span><span class="Delimiter">,</span> <span class="Constant">48</span>
<span id="L287" class="LineNr">287 </span> <span class="Constant">12</span>:num<span class="Special"> &lt;- </span><a href='069hash.cc.html#L34'>hash</a> <span class="Constant">7</span>:foo
<span id="L288" class="LineNr">288 </span> <span class="Identifier">return</span>-unless <span class="Constant">12</span>:num
<span id="L289" class="LineNr">289 </span> <span class="Constant">13</span>:<span class="Normal">bool</span><span class="Special"> &lt;- </span>equal <span class="Constant">6</span>:num<span class="Delimiter">,</span> <span class="Constant">12</span>:num
<span id="L290" class="LineNr">290 </span>]
<span id="L291" class="LineNr">291 </span><span class="Comment"># containers with identical 'leaf' elements return identical hashes</span>
<span id="L292" class="LineNr">292 </span><span class="traceContains">+mem: storing 1 in location 13</span>
<span id="L293" class="LineNr">293 </span>
<span id="L294" class="LineNr">294 </span><span class="Delimiter">:(scenario hash_exclusive_container_ignores_tag)</span>
<span id="L295" class="LineNr">295 </span><span class="muData">exclusive-container</span> foo [
<span id="L296" class="LineNr">296 </span> <span class="Normal">x</span>:bar
<span id="L297" class="LineNr">297 </span> <span class="Normal">y</span>:num
<span id="L298" class="LineNr">298 </span>]
<span id="L299" class="LineNr">299 </span><span class="muData">container</span> bar [
<span id="L300" class="LineNr">300 </span> <span class="Normal">a</span>:num
<span id="L301" class="LineNr">301 </span> <span class="Normal">b</span>:num
<span id="L302" class="LineNr">302 </span>]
<span id="L303" class="LineNr">303 </span><span class="muRecipe">def</span> <a href='000organization.cc.html#L113'>main</a> [
<span id="L304" class="LineNr">304 </span> <span class="Constant">1</span>:foo<span class="Special"> &lt;- </span>merge <span class="Constant">0</span>/x<span class="Delimiter">,</span> <span class="Constant">34</span><span class="Delimiter">,</span> <span class="Constant">35</span>
<span id="L305" class="LineNr">305 </span> <span class="Constant">4</span>:num<span class="Special"> &lt;- </span><a href='069hash.cc.html#L34'>hash</a> <span class="Constant">1</span>:foo
<span id="L306" class="LineNr">306 </span> <span class="Identifier">return</span>-unless <span class="Constant">4</span>:num
<span id="L307" class="LineNr">307 </span> <span class="Constant">5</span>:bar<span class="Special"> &lt;- </span>merge <span class="Constant">34</span><span class="Delimiter">,</span> <span class="Constant">35</span>
<span id="L308" class="LineNr">308 </span> <span class="Constant">7</span>:num<span class="Special"> &lt;- </span><a href='069hash.cc.html#L34'>hash</a> <span class="Constant">5</span>:bar
<span id="L309" class="LineNr">309 </span> <span class="Identifier">return</span>-unless <span class="Constant">7</span>:num
<span id="L310" class="LineNr">310 </span> <span class="Constant">8</span>:<span class="Normal">bool</span><span class="Special"> &lt;- </span>equal <span class="Constant">4</span>:num<span class="Delimiter">,</span> <span class="Constant">7</span>:num
<span id="L311" class="LineNr">311 </span>]
<span id="L312" class="LineNr">312 </span><span class="Comment"># hash on containers includes all elements</span>
<span id="L313" class="LineNr">313 </span><span class="traceContains">+mem: storing 1 in location 8</span>
<span id="L314" class="LineNr">314 </span>
<span id="L315" class="LineNr">315 </span><span class="Comment">//: An older version that supported only strings.</span>
<span id="L316" class="LineNr">316 </span><span class="Comment">//: Hash functions are subtle and easy to get wrong, so we keep the old</span>
<span id="L317" class="LineNr">317 </span><span class="Comment">//: version around and check that the new one is consistent with it.</span>
<span id="L318" class="LineNr">318 </span>
<span id="L319" class="LineNr">319 </span><span class="Delimiter">:(scenario hash_matches_old_version)</span>
<span id="L320" class="LineNr">320 </span><span class="muRecipe">def</span> <a href='000organization.cc.html#L113'>main</a> [
<span id="L321" class="LineNr">321 </span> <span class="Constant">1</span>:text<span class="Special"> &lt;- </span><span class="Normal">new</span> [abc]
<span id="L322" class="LineNr">322 </span> <span class="Constant">3</span>:num<span class="Special"> &lt;- </span><a href='069hash.cc.html#L34'>hash</a> <span class="Constant">1</span>:text
<span id="L323" class="LineNr">323 </span> <span class="Constant">4</span>:num<span class="Special"> &lt;- </span>hash_old <span class="Constant">1</span>:text
<span id="L324" class="LineNr">324 </span> <span class="Constant">5</span>:<span class="Normal">bool</span><span class="Special"> &lt;- </span>equal <span class="Constant">3</span>:num<span class="Delimiter">,</span> <span class="Constant">4</span>:num
<span id="L325" class="LineNr">325 </span>]
<span id="L326" class="LineNr">326 </span><span class="traceContains">+mem: storing 1 in location 5</span>
<span id="L327" class="LineNr">327 </span>
<span id="L328" class="LineNr">328 </span><span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span>
<span id="L329" class="LineNr">329 </span>HASH_OLD<span class="Delimiter">,</span>
<span id="L330" class="LineNr">330 </span><span class="Delimiter">:(before &quot;End Primitive Recipe Numbers&quot;)</span>
<span id="L331" class="LineNr">331 </span><a href='001help.cc.html#L221'>put</a><span class="Delimiter">(</span><span class="Special">Recipe_ordinal</span><span class="Delimiter">,</span> <span class="Constant">&quot;hash_old&quot;</span><span class="Delimiter">,</span> HASH_OLD<span class="Delimiter">);</span>
<span id="L332" class="LineNr">332 </span><span class="Delimiter">:(before &quot;End Primitive Recipe Checks&quot;)</span>
<span id="L333" class="LineNr">333 </span><span class="Normal">case</span> HASH_OLD: <span class="Delimiter">{</span>
<span id="L334" class="LineNr">334 </span> <span class="Normal">if</span> <span class="Delimiter">(</span><a href='001help.cc.html#L141'>SIZE</a><span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span id="L335" class="LineNr">335 </span> <a href='003trace.cc.html#L196'>raise</a> &lt;&lt; <a href='013update_operation.cc.html#L25'>maybe</a><span class="Delimiter">(</span>get<span class="Delimiter">(</span><span class="Special">Recipe</span><span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'hash_old' takes exactly one ingredient rather than '&quot;</span> &lt;&lt; to_original_string<span class="Delimiter">(</span>inst<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'\n&quot;</span> &lt;&lt; <a href='003trace.cc.html#L225'>end</a><span class="Delimiter">();</span>
<span id="L336" class="LineNr">336 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L337" class="LineNr">337 </span> <span class="Delimiter">}</span>
<span id="L338" class="LineNr">338 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>!is_mu_text<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
<span id="L339" class="LineNr">339 </span> <a href='003trace.cc.html#L196'>raise</a> &lt;&lt; <a href='013update_operation.cc.html#L25'>maybe</a><span class="Delimiter">(</span>get<span class="Delimiter">(</span><span class="Special">Recipe</span><span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'hash_old' currently only supports texts (address array character), but got '&quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string &lt;&lt; <span class="Constant">&quot;'\n&quot;</span> &lt;&lt; <a href='003trace.cc.html#L225'>end</a><span class="Delimiter">();</span>
<span id="L340" class="LineNr">340 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L341" class="LineNr">341 </span> <span class="Delimiter">}</span>
<span id="L342" class="LineNr">342 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L343" class="LineNr">343 </span><span class="Delimiter">}</span>
<span id="L344" class="LineNr">344 </span><span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span>
<span id="L345" class="LineNr">345 </span><span class="Normal">case</span> HASH_OLD: <span class="Delimiter">{</span>
<span id="L346" class="LineNr">346 </span> string input = <a href='038new_text.cc.html#L142'>read_mu_text</a><span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">skip alloc id</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">));</span>
<span id="L347" class="LineNr">347 </span> <span class="Normal">size_t</span> h = <span class="Constant">0</span> <span class="Delimiter">;</span>
<span id="L348" class="LineNr">348 </span>
<span id="L349" class="LineNr">349 </span> <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; <a href='001help.cc.html#L141'>SIZE</a><span class="Delimiter">(</span>input<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span id="L350" class="LineNr">350 </span> h += <span class="Normal">static_cast</span>&lt;<span class="Normal">size_t</span>&gt;<span class="Delimiter">(</span>input<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
<span id="L351" class="LineNr">351 </span> h += <span class="Delimiter">(</span>h&lt;&lt;<span class="Constant">10</span><span class="Delimiter">);</span>
<span id="L352" class="LineNr">352 </span> h ^= <span class="Delimiter">(</span>h&gt;&gt;<span class="Constant">6</span><span class="Delimiter">);</span>
<span id="L353" class="LineNr">353 </span>
<span id="L354" class="LineNr">354 </span> h += <span class="Delimiter">(</span>h&lt;&lt;<span class="Constant">3</span><span class="Delimiter">);</span>
<span id="L355" class="LineNr">355 </span> h ^= <span class="Delimiter">(</span>h&gt;&gt;<span class="Constant">11</span><span class="Delimiter">);</span>
<span id="L356" class="LineNr">356 </span> h += <span class="Delimiter">(</span>h&lt;&lt;<span class="Constant">15</span><span class="Delimiter">);</span>
<span id="L357" class="LineNr">357 </span> <span class="Delimiter">}</span>
<span id="L358" class="LineNr">358 </span>
<span id="L359" class="LineNr">359 </span> products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
<span id="L360" class="LineNr">360 </span> products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>h<span class="Delimiter">);</span>
<span id="L361" class="LineNr">361 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L362" class="LineNr">362 </span><span class="Delimiter">}</span>
</pre>
</body>
</html>
<!-- vim: set foldmethod=manual : -->