<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>db | Academic</title><link>https://loloxwg.top/tag/db/</link><atom:link href="https://loloxwg.top/tag/db/index.xml" rel="self" type="application/rss+xml"/><description>db</description><generator>Wowchemy (https://wowchemy.com)</generator><language>en-us</language><lastBuildDate>Wed, 12 Apr 2023 16:16:26 +0800</lastBuildDate><image><url>https://loloxwg.top/media/icon_hu0b7a4cb9992c9ac0e91bd28ffd38dd00_9727_512x512_fill_lanczos_center_3.png</url><title>db</title><link>https://loloxwg.top/tag/db/</link></image><item><title>ExtendibleHashing</title><link>https://loloxwg.top/posts/cmu-15445/extendible-hashing/</link><pubDate>Wed, 12 Apr 2023 16:16:26 +0800</pubDate><guid>https://loloxwg.top/posts/cmu-15445/extendible-hashing/</guid><description>&lt;h1 id="extendible-hashing">Extendible Hashing&lt;/h1>
&lt;p>&lt;a href="https://www.geeksforgeeks.org/extendible-hashing-dynamic-approach-to-dbms/" target="_blank" rel="noopener">Extendible Hashing (Dynamic approach to DBMS) - GeeksforGeeks&lt;/a>&lt;/p>
&lt;p>Extendible hashing is a dynamic hashing technique in which the hash function is modified as the size of the hash table increases. It is commonly used in database systems to implement indexing. In extendible hashing, each bucket can store multiple records and each bucket is identified by a local directory. The global directory keeps track of the local directories and is expanded as the number of buckets increases.&lt;/p>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="assets/Untitled.png" alt="Untitled" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="assets/Untitled.png" alt="Untitled" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="assets/Untitled.png" alt="Untitled" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;ul>
&lt;li>目录：存储指向桶的指针。&lt;/li>
&lt;li>桶：哈希键值对，如果局部深度小于全局深度时，一个桶可能包含不止一个指针指向它。&lt;/li>
&lt;li>全局深度：和目录相关联，也就是哈希后取的比特数。&lt;/li>
&lt;li>局部深度：和桶关联，表示桶中的数据是哈希后取低&lt;code>x&lt;/code>位得到的。&lt;/li>
&lt;/ul>
&lt;p>插入数据，流程如下：&lt;/p>
&lt;ol>
&lt;li>将&lt;code>key&lt;/code>哈希后，如果全局深度为&lt;code>n&lt;/code>，那么取低&lt;code>n&lt;/code>位比特。比如&lt;code>n = 4&lt;/code>时，哈希出来的结果为&lt;code>xxx0011&lt;/code>，表示这个&lt;code>key&lt;/code>应该存储到&lt;code>dir[0011]&lt;/code>指向的桶中。&lt;/li>
&lt;li>如果桶已经满了，那么比较全局深度和局部深度的大小。&lt;/li>
&lt;li>如果相等，&lt;code>dir&lt;/code>目录项扩容一倍，全局深度相应增加&lt;code>1&lt;/code>。新增的那些&lt;code>dir[i]&lt;/code>指向&lt;code>dir[i - Size]&lt;/code>。比如开始时全局深度为&lt;code>2&lt;/code>，那么&lt;code>dir&lt;/code>大小为&lt;code>4&lt;/code>，扩容后大小为&lt;code>8&lt;/code>，其中&lt;code>dir[5]&lt;/code>应该指向&lt;code>dir[1]&lt;/code>。因为&lt;code>5&lt;/code>中对应的&lt;code>key&lt;/code>哈希值低&lt;code>3&lt;/code>位为&lt;code>101&lt;/code>，在还没扩容之前，低&lt;code>2&lt;/code>位为&lt;code>01&lt;/code>。也就意味着，现在本该存储在&lt;code>dir[5]&lt;/code>中的&lt;code>key&lt;/code>之前存在&lt;code>dir[1]&lt;/code>中，我们直接将&lt;code>dir[5] = dir[1]&lt;/code>，共用。当全局深度比局部深度大&lt;code>n&lt;/code>时，有&lt;code>2^n&lt;/code>个&lt;code>dir&lt;/code>目录项共用这个桶。&lt;/li>
&lt;li>&lt;code>dir&lt;/code>扩容后，再次尝试插入，这个时候桶还是满的，不过局部深度比全局深度小。&lt;/li>
&lt;li>如果局部深度比全局深度小，我们将局部深度增加&lt;code>1&lt;/code>，比如原来是&lt;code>2&lt;/code>，现在变成&lt;code>3&lt;/code>，那么里面的&lt;code>key&lt;/code>哈希值低两位都是相同的，第&lt;code>3&lt;/code>位的&lt;code>0&lt;/code>和&lt;code>1&lt;/code>可以把这里面的&lt;code>key&lt;/code>分成两部分。&lt;/li>
&lt;li>分完之后，让&lt;code>dir&lt;/code>中低&lt;code>3&lt;/code>位是&lt;code>0xx&lt;/code>和&lt;code>1xx&lt;/code>的目录项分别指向拆分后的桶。&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="kt">void&lt;/span> &lt;span class="n">ExtendibleHashTable&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">K&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">V&lt;/span>&lt;span class="o">&amp;gt;::&lt;/span>&lt;span class="n">Insert&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">const&lt;/span> &lt;span class="n">K&lt;/span> &lt;span class="o">&amp;amp;&lt;/span>&lt;span class="n">key&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="k">const&lt;/span> &lt;span class="n">V&lt;/span> &lt;span class="o">&amp;amp;&lt;/span>&lt;span class="n">value&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// UNREACHABLE(&amp;#34;not implemented&amp;#34;);
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">scoped_lock&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">mutex&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">lock&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">latch_&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">auto&lt;/span> &lt;span class="n">directory_index&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">IndexOf&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">key&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">auto&lt;/span> &lt;span class="n">target_bucket&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">dir_&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">directory_index&lt;/span>&lt;span class="p">];&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">while&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="o">!&lt;/span>&lt;span class="n">target_bucket&lt;/span>&lt;span class="o">-&amp;gt;&lt;/span>&lt;span class="n">Insert&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">key&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">value&lt;/span>&lt;span class="p">))&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 1. If the local depth of the bucket is equal to the global depth,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// increment the global depth and double the size of the directory.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">LOG_DEBUG&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;stage1: dir_.size() = %ld&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">dir_&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">size&lt;/span>&lt;span class="p">());&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">GetLocalDepth&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">directory_index&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="n">GetGlobalDepth&lt;/span>&lt;span class="p">())&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">global_depth_&lt;/span>&lt;span class="o">++&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">LOG_DEBUG&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;start loop.. dir_.size() = %ld&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">dir_&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">size&lt;/span>&lt;span class="p">());&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">int&lt;/span> &lt;span class="n">length&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">dir_&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">size&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">dir_&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">resize&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">length&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="c1">// &amp;lt;&amp;lt;1 is same as *2
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">length&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="o">++&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">dir_&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">i&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">length&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">dir_&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">];&lt;/span> &lt;span class="c1">// length =4
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// dir[4]=dir[0] 100 000
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// dir[5]=dir[1] 101 001
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// dir[6]=dir[2] 110 010
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// dir[7]=dir[3] 111 011
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">LOG_DEBUG&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;stage2: Increment the local depth of the bucket.&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 2. If local depth lower than global depth , Increment the local depth of the bucket.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">target_bucket&lt;/span>&lt;span class="o">-&amp;gt;&lt;/span>&lt;span class="n">IncrementDepth&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 3. Split the bucket and redistribute
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// directory pointers &amp;amp; the kv pairs in the bucket.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="n">LOG_DEBUG&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;stage3: Split the bucket and redistribute&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">auto&lt;/span> &lt;span class="n">mask&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">1&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">target_bucket&lt;/span>&lt;span class="o">-&amp;gt;&lt;/span>&lt;span class="n">GetDepth&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">auto&lt;/span> &lt;span class="n">new_bucket&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">make_shared&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Bucket&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">bucket_size_&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">target_bucket&lt;/span>&lt;span class="o">-&amp;gt;&lt;/span>&lt;span class="n">GetDepth&lt;/span>&lt;span class="p">());&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">auto&lt;/span> &lt;span class="n">old_bucket&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">make_shared&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">Bucket&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">bucket_size_&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">target_bucket&lt;/span>&lt;span class="o">-&amp;gt;&lt;/span>&lt;span class="n">GetDepth&lt;/span>&lt;span class="p">());&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">num_buckets_&lt;/span>&lt;span class="o">++&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 3.1. Redistribute the directory pointers.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">size_t&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">dir_&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">size&lt;/span>&lt;span class="p">();&lt;/span> &lt;span class="o">++&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">dir_&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="n">target_bucket&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">((&lt;/span>&lt;span class="n">i&lt;/span> &lt;span class="o">&amp;amp;&lt;/span> &lt;span class="n">mask&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">dir_&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">new_bucket&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span> &lt;span class="k">else&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">dir_&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">old_bucket&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 3.2. Move the kv pairs from the target bucket to the new two bucket.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="k">auto&lt;/span> &lt;span class="o">&amp;amp;&lt;/span>&lt;span class="nl">item&lt;/span> &lt;span class="p">:&lt;/span> &lt;span class="n">target_bucket&lt;/span>&lt;span class="o">-&amp;gt;&lt;/span>&lt;span class="n">GetItems&lt;/span>&lt;span class="p">())&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">auto&lt;/span> &lt;span class="n">cur_directory_index&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">IndexOf&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">item&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">first&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">dir_&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">cur_directory_index&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="o">-&amp;gt;&lt;/span>&lt;span class="n">Insert&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">item&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">first&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">item&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">second&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">directory_index&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">IndexOf&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">key&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">target_bucket&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">dir_&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">directory_index&lt;/span>&lt;span class="p">];&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>LRU-K</title><link>https://loloxwg.top/posts/cmu-15445/lru-k/</link><pubDate>Wed, 12 Apr 2023 16:16:26 +0800</pubDate><guid>https://loloxwg.top/posts/cmu-15445/lru-k/</guid><description>&lt;p>&lt;strong>一、LRU-K算法&lt;/strong>&lt;/p>
&lt;p>1、算法思想&lt;/p>
&lt;p>LRU-K中的K代表最近使用的次数，因此LRU可以认为是LRU-1。LRU-K的主要目的是为了解决LRU算法“缓存污染”的问题，其核心思想是将“最近使用过1次”的判断标准扩展为“最近使用过K次”。&lt;/p>
&lt;p>2、工作原理&lt;/p>
&lt;p>相比LRU，LRU-K需要多维护一个队列，用于记录所有缓存数据被访问的历史。只有当数据的访问次数达到K次的时候，才将数据放入缓存。当需要淘汰数据时，LRU-K会淘汰第K次访问时间距当前时间最大的数据。详细实现如下&lt;/p>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="./assets/1240.png" alt="" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>(1).数据第一次被访问，加入到访问历史列表；&lt;/p>
&lt;p>(2).如果数据在访问历史列表里后没有达到K次访问，则按照一定规则（FIFO，LRU）淘汰；&lt;/p>
&lt;p>(3).当访问历史队列中的数据访问次数达到K次后，将数据索引从历史队列删除，将数据移到缓存队列中，并缓存此数据，缓存队列重新按照时间排序；&lt;/p>
&lt;p>(4).缓存数据队列中被再次访问后，重新排序；&lt;/p>
&lt;p>(5).需要淘汰数据时，淘汰缓存队列中排在末尾的数据，即：淘汰“倒数第K次访问离现在最久”的数据。&lt;/p>
&lt;p>LRU-K具有LRU的优点，同时能够避免LRU的缺点，实际应用中LRU-2是综合各种因素后最优的选择，LRU-3或者更大的K值命中率会高，但适应性差，需要大量的数据访问才能将历史访问记录清除掉。&lt;/p>
&lt;p>**二、Twoqueues（2Q）**本次LAB使用的思想&lt;/p>
&lt;p>1、算法思想&lt;/p>
&lt;p>该算法类似于LRU-2，不同点在于2Q将LRU-2算法中的访问历史队列（注意这不是缓存数据的）改为一个FIFO缓存队列，即：2Q算法有两个缓存队列，一个是FIFO队列，一个是LRU队列。&lt;/p>
&lt;p>2、工作原理&lt;/p>
&lt;p>当数据第一次访问时，2Q算法将数据缓存在FIFO队列里面，当数据第二次被访问时，则将数据从FIFO队列移到LRU队列里面，两个队列各自按照自己的方法淘汰数据。详细实现如下：&lt;/p>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="./assets/CleanShot%202023-04-11%20at%2010.46.44%402x.png" alt="CleanShot 2023-04-11 at 10.46.44@2x" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>(1).新访问的数据插入到FIFO队列；&lt;/p>
&lt;p>(2).如果数据在FIFO队列中一直没有被再次访问，则最终按照FIFO规则淘汰；&lt;/p>
&lt;p>(3).如果数据在FIFO队列中被再次访问，则将数据移到LRU队列头部；&lt;/p>
&lt;p>(4).如果数据在LRU队列再次被访问，则将数据移到LRU队列头部；&lt;/p>
&lt;p>(5).LRU队列淘汰末尾的数据。&lt;/p>
&lt;p>&lt;strong>参考资料：&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;a href="http://www.cs.cmu.edu/~christos/courses/721-resources/p297-o_neil.pdf" target="_blank" rel="noopener">The LRU-K Page Replacement Algorithm For Database Disk Buffering&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://www.vldb.org/conf/1994/P439.PDF" target="_blank" rel="noopener">2Q: A Low Overhead High Performance Buffer Management Replacement Algorithm&lt;/a>&lt;/li>
&lt;/ul></description></item></channel></rss>