<divclass="line"><aname="l00002"></a><spanclass="lineno"> 2</span> <spanclass="comment"> * Copyright (c) Facebook, Inc. and its affiliates.</span></div>
<divclass="line"><aname="l00004"></a><spanclass="lineno"> 4</span> <spanclass="comment"> * This source code is licensed under the MIT license found in the</span></div>
<divclass="line"><aname="l00005"></a><spanclass="lineno"> 5</span> <spanclass="comment"> * LICENSE file in the root directory of this source tree.</span></div>
<divclass="line"><aname="l00026"></a><spanclass="lineno"> 26</span> <spanclass="comment">/** Implementation of the Hierarchical Navigable Small World</span></div>
<divclass="line"><aname="l00030"></a><spanclass="lineno"> 30</span> <spanclass="comment"> * Hierarchical Navigable Small World graphs</span></div>
<divclass="line"><aname="l00032"></a><spanclass="lineno"> 32</span> <spanclass="comment"> * Yu. A. Malkov, D. A. Yashunin, arXiv 2017</span></div>
<divclass="line"><aname="l00034"></a><spanclass="lineno"> 34</span> <spanclass="comment"> * This implmentation is heavily influenced by the NMSlib</span></div>
<divclass="line"><aname="l00035"></a><spanclass="lineno"> 35</span> <spanclass="comment"> * implementation by Yury Malkov and Leonid Boystov</span></div>
<divclass="line"><aname="l00038"></a><spanclass="lineno"> 38</span> <spanclass="comment"> * The HNSW object stores only the neighbor link structure, see</span></div>
<divclass="line"><aname="l00039"></a><spanclass="lineno"> 39</span> <spanclass="comment"> * IndexHNSW.h for the full index object.</span></div>
<divclass="line"><aname="l00047"></a><spanclass="lineno"> 47</span> <spanclass="comment"> /// internal storage of vectors (32 bits: this is expensive)</span></div>
<divclass="line"><aname="l00082"></a><spanclass="lineno"> 82</span> <spanclass="comment"> /// to sort pairs of (id, distance) from nearest to fathest or the reverse</span></div>
<divclass="line"><aname="l00098"></a><spanclass="lineno"> 98</span> <spanclass="comment"> /// assignment probability to each layer (sum=1)</span></div>
<divclass="line"><aname="l00101"></a><spanclass="lineno"> 101</span> <spanclass="comment"> /// number of neighbors stored per layer (cumulative), should not</span></div>
<divclass="line"><aname="l00102"></a><spanclass="lineno"> 102</span> <spanclass="comment"> /// be changed after first add</span></div>
<divclass="line"><aname="l00108"></a><spanclass="lineno"> 108</span> <spanclass="comment"> /// offsets[i] is the offset in the neighbors array where vector i is stored</span></div>
<divclass="line"><aname="l00112"></a><spanclass="lineno"> 112</span> <spanclass="comment"> /// neighbors[offsets[i]:offsets[i+1]] is the list of neighbors of vector i</span></div>
<divclass="line"><aname="l00113"></a><spanclass="lineno"> 113</span> <spanclass="comment"> /// for all levels. this is where all storage goes.</span></div>
<divclass="line"><aname="l00116"></a><spanclass="lineno"> 116</span> <spanclass="comment"> /// entry point in the search structure (one of the points with maximum level</span></div>
<divclass="line"><aname="l00130"></a><spanclass="lineno"> 130</span> <spanclass="comment"> /// during search: do we check whether the next best distance is good enough?</span></div>
<divclass="line"><aname="l00133"></a><spanclass="lineno"> 133</span> <spanclass="comment"> /// number of entry points in levels > 0.</span></div>
<divclass="line"><aname="l00141"></a><spanclass="lineno"> 141</span> <spanclass="comment"> /// initialize the assign_probas and cum_nneighbor_per_level to</span></div>
<divclass="line"><aname="l00142"></a><spanclass="lineno"> 142</span> <spanclass="comment"> /// have 2*M links on level 0 and M links on levels > 0</span></div>
<divclass="line"><aname="l00143"></a><spanclass="lineno"> 143</span> <spanclass="comment"></span><spanclass="keywordtype">void</span><aclass="code"href="structfaiss_1_1HNSW.html#ae7d955690da5d6376c203e81e124ba94">set_default_probas</a>(<spanclass="keywordtype">int</span> M, <spanclass="keywordtype">float</span> levelMult);</div>
<divclass="line"><aname="l00145"></a><spanclass="lineno"> 145</span> <spanclass="comment"> /// set nb of neighbors for this level (before adding anything)</span></div>
<divclass="line"><aname="l00153"></a><spanclass="lineno"> 153</span> <spanclass="comment"> /// cumumlative nb up to (and excluding) this level</span></div>
<divclass="line"><aname="l00156"></a><spanclass="lineno"> 156</span> <spanclass="comment"> /// range of entries in the neighbors table of vertex no at layer_no</span></div>
<divclass="line"><aname="l00157"></a><spanclass="lineno"> 157</span> <spanclass="comment"></span><spanclass="keywordtype">void</span><aclass="code"href="structfaiss_1_1HNSW.html#aa3ae6a80d358e59e3af23f918253f61d">neighbor_range</a>(<aclass="code"href="structfaiss_1_1HNSW.html#a84f912f99bda1a827a74cdf8793af160">idx_t</a> no, <spanclass="keywordtype">int</span> layer_no,</div>
<divclass="line"><aname="l00160"></a><spanclass="lineno"> 160</span> <spanclass="comment"> /// only mandatory parameter: nb of neighbors</span></div>
<divclass="line"><aname="l00161"></a><spanclass="lineno"> 161</span> <spanclass="comment"></span><spanclass="keyword">explicit</span><aclass="code"href="structfaiss_1_1HNSW.html#a1fc852810a2497a8eb2c41635ec05520">HNSW</a>(<spanclass="keywordtype">int</span> M = 32);</div>
<divclass="line"><aname="l00166"></a><spanclass="lineno"> 166</span> <spanclass="comment"> /// add n random levels to table (for debugging...)</span></div>
<divclass="line"><aname="l00178"></a><spanclass="lineno"> 178</span> <spanclass="comment"> /** add point pt_id on all levels <= pt_level and build the link</span></div>
<divclass="line"><aname="l00179"></a><spanclass="lineno"> 179</span> <spanclass="comment"> * structure for them. */</span></div>
<divclass="line"><aname="l00222"></a><spanclass="lineno"> 222</span> <spanclass="comment">/// set implementation optimized for fast access.</span></div>
<divclass="line"><aname="l00244"></a><spanclass="lineno"> 244</span> <spanclass="comment">// 250 rather than 255 because sometimes we use visno and visno+1</span></div>
<divclass="ttc"id="structfaiss_1_1RandomGenerator_html"><divclass="ttname"><ahref="structfaiss_1_1RandomGenerator.html">faiss::RandomGenerator</a></div><divclass="ttdoc">random generator that can be used in multithreaded contexts </div><divclass="ttdef"><b>Definition:</b><ahref="utils_8h_source.html#l00047">utils.h:47</a></div></div>
<divclass="ttc"id="structfaiss_1_1HNSW_html_a314b809de6f329662ab09f258b49afb3"><divclass="ttname"><ahref="structfaiss_1_1HNSW.html#a314b809de6f329662ab09f258b49afb3">faiss::HNSW::add_with_locks</a></div><divclass="ttdeci">void add_with_locks(DistanceComputer &ptdis, int pt_level, int pt_id, std::vector< omp_lock_t >&locks, VisitedTable &vt)</div><divclass="ttdef"><b>Definition:</b><ahref="HNSW_8cpp_source.html#l00477">HNSW.cpp:477</a></div></div>
<divclass="ttc"id="structfaiss_1_1HNSW_html_aa3ae6a80d358e59e3af23f918253f61d"><divclass="ttname"><ahref="structfaiss_1_1HNSW.html#aa3ae6a80d358e59e3af23f918253f61d">faiss::HNSW::neighbor_range</a></div><divclass="ttdeci">void neighbor_range(idx_t no, int layer_no, size_t *begin, size_t *end) const </div><divclass="ttdoc">range of entries in the neighbors table of vertex no at layer_no </div><divclass="ttdef"><b>Definition:</b><ahref="HNSW_8cpp_source.html#l00041">HNSW.cpp:41</a></div></div>
<divclass="ttc"id="structfaiss_1_1HNSW_html_ad497ea80f352c33242ba7835370c2dba"><divclass="ttname"><ahref="structfaiss_1_1HNSW.html#ad497ea80f352c33242ba7835370c2dba">faiss::HNSW::nb_neighbors</a></div><divclass="ttdeci">int nb_neighbors(int layer_no) const </div><divclass="ttdoc">nb of neighbors for this level </div><divclass="ttdef"><b>Definition:</b><ahref="HNSW_8cpp_source.html#l00021">HNSW.cpp:21</a></div></div>
<divclass="ttc"id="structfaiss_1_1HNSW_html_a95547d97c90b361a040bae0fb0d892b4"><divclass="ttname"><ahref="structfaiss_1_1HNSW.html#a95547d97c90b361a040bae0fb0d892b4">faiss::HNSW::entry_point</a></div><divclass="ttdeci">storage_idx_t entry_point</div><divclass="ttdoc">entry point in the search structure (one of the points with maximum level </div><divclass="ttdef"><b>Definition:</b><ahref="HNSW_8h_source.html#l00117">HNSW.h:117</a></div></div>
<divclass="ttc"id="structfaiss_1_1HNSW_html_a49b512eaaa54ead77b564cad8e3e6ebd"><divclass="ttname"><ahref="structfaiss_1_1HNSW.html#a49b512eaaa54ead77b564cad8e3e6ebd">faiss::HNSW::cum_nb_neighbors</a></div><divclass="ttdeci">int cum_nb_neighbors(int layer_no) const </div><divclass="ttdoc">cumumlative nb up to (and excluding) this level </div><divclass="ttdef"><b>Definition:</b><ahref="HNSW_8cpp_source.html#l00036">HNSW.cpp:36</a></div></div>
<divclass="ttc"id="structfaiss_1_1HNSW_html_a84f912f99bda1a827a74cdf8793af160"><divclass="ttname"><ahref="structfaiss_1_1HNSW.html#a84f912f99bda1a827a74cdf8793af160">faiss::HNSW::idx_t</a></div><divclass="ttdeci">Index::idx_t idx_t</div><divclass="ttdoc">Faiss results are 64-bit. </div><divclass="ttdef"><b>Definition:</b><ahref="HNSW_8h_source.html#l00051">HNSW.h:51</a></div></div>
<divclass="ttc"id="structfaiss_1_1HNSW_html_a907c94e0eca5200af1dc8d0aea482665"><divclass="ttname"><ahref="structfaiss_1_1HNSW.html#a907c94e0eca5200af1dc8d0aea482665">faiss::HNSW::assign_probas</a></div><divclass="ttdeci">std::vector< double > assign_probas</div><divclass="ttdoc">assignment probability to each layer (sum=1) </div><divclass="ttdef"><b>Definition:</b><ahref="HNSW_8h_source.html#l00099">HNSW.h:99</a></div></div>
<divclass="ttc"id="structfaiss_1_1HNSW_html_a683738e8ab8e67fcabd823510c30b074"><divclass="ttname"><ahref="structfaiss_1_1HNSW.html#a683738e8ab8e67fcabd823510c30b074">faiss::HNSW::search_bounded_queue</a></div><divclass="ttdeci">bool search_bounded_queue</div><divclass="ttdoc">use bounded queue during exploration </div><divclass="ttdef"><b>Definition:</b><ahref="HNSW_8h_source.html#l00137">HNSW.h:137</a></div></div>
<divclass="ttc"id="structfaiss_1_1HNSW_html_a1c258bb88aae9b1a754ab4690d85ed41"><divclass="ttname"><ahref="structfaiss_1_1HNSW.html#a1c258bb88aae9b1a754ab4690d85ed41">faiss::HNSW::cum_nneighbor_per_level</a></div><divclass="ttdeci">std::vector< int > cum_nneighbor_per_level</div><divclass="ttdef"><b>Definition:</b><ahref="HNSW_8h_source.html#l00103">HNSW.h:103</a></div></div>
<divclass="ttc"id="structfaiss_1_1VisitedTable_html_a76223893c8c3a577473092b3bb8a2446"><divclass="ttname"><ahref="structfaiss_1_1VisitedTable.html#a76223893c8c3a577473092b3bb8a2446">faiss::VisitedTable::advance</a></div><divclass="ttdeci">void advance()</div><divclass="ttdoc">reset all flags to false </div><divclass="ttdef"><b>Definition:</b><ahref="HNSW_8h_source.html#l00241">HNSW.h:241</a></div></div>
<divclass="ttc"id="structfaiss_1_1Index_html_ad3f0d3071f987baabbdd3da4500c87ea"><divclass="ttname"><ahref="structfaiss_1_1Index.html#ad3f0d3071f987baabbdd3da4500c87ea">faiss::Index::idx_t</a></div><divclass="ttdeci">long idx_t</div><divclass="ttdoc">all indices are this type </div><divclass="ttdef"><b>Definition:</b><ahref="Index_8h_source.html#l00062">Index.h:62</a></div></div>
<divclass="ttc"id="structfaiss_1_1VisitedTable_html"><divclass="ttname"><ahref="structfaiss_1_1VisitedTable.html">faiss::VisitedTable</a></div><divclass="ttdoc">set implementation optimized for fast access. </div><divclass="ttdef"><b>Definition:</b><ahref="HNSW_8h_source.html#l00223">HNSW.h:223</a></div></div>
<divclass="ttc"id="structfaiss_1_1HNSW_html_a6d1cb35c4220bf554af90133c71ae04f"><divclass="ttname"><ahref="structfaiss_1_1HNSW.html#a6d1cb35c4220bf554af90133c71ae04f">faiss::HNSW::efSearch</a></div><divclass="ttdeci">int efSearch</div><divclass="ttdoc">expansion factor at search time </div><divclass="ttdef"><b>Definition:</b><ahref="HNSW_8h_source.html#l00128">HNSW.h:128</a></div></div>
<divclass="ttc"id="structfaiss_1_1HNSW_html_adbf81f0b21102b942182c904892e0858"><divclass="ttname"><ahref="structfaiss_1_1HNSW.html#adbf81f0b21102b942182c904892e0858">faiss::HNSW::check_relative_distance</a></div><divclass="ttdeci">bool check_relative_distance</div><divclass="ttdoc">during search: do we check whether the next best distance is good enough? </div><divclass="ttdef"><b>Definition:</b><ahref="HNSW_8h_source.html#l00131">HNSW.h:131</a></div></div>
<divclass="ttc"id="structfaiss_1_1HNSW_html_a1fc852810a2497a8eb2c41635ec05520"><divclass="ttname"><ahref="structfaiss_1_1HNSW.html#a1fc852810a2497a8eb2c41635ec05520">faiss::HNSW::HNSW</a></div><divclass="ttdeci">HNSW(int M=32)</div><divclass="ttdoc">only mandatory parameter: nb of neighbors </div><divclass="ttdef"><b>Definition:</b><ahref="HNSW_8cpp_source.html#l00051">HNSW.cpp:51</a></div></div>
<divclass="ttc"id="structfaiss_1_1HNSW_1_1NodeDistCloser_html"><divclass="ttname"><ahref="structfaiss_1_1HNSW_1_1NodeDistCloser.html">faiss::HNSW::NodeDistCloser</a></div><divclass="ttdoc">to sort pairs of (id, distance) from nearest to fathest or the reverse </div><divclass="ttdef"><b>Definition:</b><ahref="HNSW_8h_source.html#l00083">HNSW.h:83</a></div></div>
<divclass="ttc"id="structfaiss_1_1HNSW_html_a857bef0db2dc0000f312cc8a95f857b2"><divclass="ttname"><ahref="structfaiss_1_1HNSW.html#a857bef0db2dc0000f312cc8a95f857b2">faiss::HNSW::upper_beam</a></div><divclass="ttdeci">int upper_beam</div><divclass="ttdoc">number of entry points in levels &gt; 0. </div><divclass="ttdef"><b>Definition:</b><ahref="HNSW_8h_source.html#l00134">HNSW.h:134</a></div></div>
<divclass="ttc"id="structfaiss_1_1HNSW_html_afdb5a17487296267efaaa94e6a08996d"><divclass="ttname"><ahref="structfaiss_1_1HNSW.html#afdb5a17487296267efaaa94e6a08996d">faiss::HNSW::set_nb_neighbors</a></div><divclass="ttdeci">void set_nb_neighbors(int level_no, int n)</div><divclass="ttdoc">set nb of neighbors for this level (before adding anything) </div><divclass="ttdef"><b>Definition:</b><ahref="HNSW_8cpp_source.html#l00027">HNSW.cpp:27</a></div></div>
<divclass="ttc"id="structfaiss_1_1HNSW_html_ad91ac2e25c896dab7fb9d32f94b60a6a"><divclass="ttname"><ahref="structfaiss_1_1HNSW.html#ad91ac2e25c896dab7fb9d32f94b60a6a">faiss::HNSW::search_from_candidates</a></div><divclass="ttdeci">int search_from_candidates(DistanceComputer &qdis, int k, idx_t *I, float *D, MinimaxHeap &candidates, VisitedTable &vt, int level, int nres_in=0) const </div><divclass="ttdef"><b>Definition:</b><ahref="HNSW_8cpp_source.html#l00523">HNSW.cpp:523</a></div></div>
<divclass="ttc"id="structfaiss_1_1HNSW_html_aa6dfdaed7bc0ad895774315166fcb197"><divclass="ttname"><ahref="structfaiss_1_1HNSW.html#aa6dfdaed7bc0ad895774315166fcb197">faiss::HNSW::random_level</a></div><divclass="ttdeci">int random_level()</div><divclass="ttdoc">pick a random level for a new point </div><divclass="ttdef"><b>Definition:</b><ahref="HNSW_8cpp_source.html#l00062">HNSW.cpp:62</a></div></div>
<divclass="ttc"id="structfaiss_1_1HNSW_html_ae7d955690da5d6376c203e81e124ba94"><divclass="ttname"><ahref="structfaiss_1_1HNSW.html#ae7d955690da5d6376c203e81e124ba94">faiss::HNSW::set_default_probas</a></div><divclass="ttdeci">void set_default_probas(int M, float levelMult)</div><divclass="ttdef"><b>Definition:</b><ahref="HNSW_8cpp_source.html#l00076">HNSW.cpp:76</a></div></div>
<divclass="ttc"id="structfaiss_1_1HNSW_html_a26710980aaca3c1c8729e5e055a42ebe"><divclass="ttname"><ahref="structfaiss_1_1HNSW.html#a26710980aaca3c1c8729e5e055a42ebe">faiss::HNSW::fill_with_random_links</a></div><divclass="ttdeci">void fill_with_random_links(size_t n)</div><divclass="ttdoc">add n random levels to table (for debugging...) </div><divclass="ttdef"><b>Definition:</b><ahref="HNSW_8cpp_source.html#l00170">HNSW.cpp:170</a></div></div>
<divclass="ttc"id="structfaiss_1_1HNSW_html_aa7309dd7826761def38233c8bbbc0c63"><divclass="ttname"><ahref="structfaiss_1_1HNSW.html#aa7309dd7826761def38233c8bbbc0c63">faiss::HNSW::efConstruction</a></div><divclass="ttdeci">int efConstruction</div><divclass="ttdoc">expansion factor at construction time </div><divclass="ttdef"><b>Definition:</b><ahref="HNSW_8h_source.html#l00125">HNSW.h:125</a></div></div>
<divclass="ttc"id="structfaiss_1_1HNSW_html_ae1342fc2f07c325598a73b733e88ee74"><divclass="ttname"><ahref="structfaiss_1_1HNSW.html#ae1342fc2f07c325598a73b733e88ee74">faiss::HNSW::storage_idx_t</a></div><divclass="ttdeci">int storage_idx_t</div><divclass="ttdoc">internal storage of vectors (32 bits: this is expensive) </div><divclass="ttdef"><b>Definition:</b><ahref="HNSW_8h_source.html#l00048">HNSW.h:48</a></div></div>
<divclass="ttc"id="structfaiss_1_1VisitedTable_html_a387b6428f4bfa44495c70a5f1f45f853"><divclass="ttname"><ahref="structfaiss_1_1VisitedTable.html#a387b6428f4bfa44495c70a5f1f45f853">faiss::VisitedTable::set</a></div><divclass="ttdeci">void set(int no)</div><divclass="ttdoc">set flog #no to true </div><divclass="ttdef"><b>Definition:</b><ahref="HNSW_8h_source.html#l00231">HNSW.h:231</a></div></div>
<divclass="ttc"id="structfaiss_1_1HNSW_html_a44847954c98957404829182c7db1b8af"><divclass="ttname"><ahref="structfaiss_1_1HNSW.html#a44847954c98957404829182c7db1b8af">faiss::HNSW::levels</a></div><divclass="ttdeci">std::vector< int > levels</div><divclass="ttdoc">level of each vector (base level = 1), size = ntotal </div><divclass="ttdef"><b>Definition:</b><ahref="HNSW_8h_source.html#l00106">HNSW.h:106</a></div></div>