在Faiss中,IndedLSH只是具有二进制编码的Flat索引。数据库向量和查询向量被哈希为二进制,并使用汉明距离进行比较。主要是把向量转换(例如降维、根据阈值相减等),转换完之后,按照bit把每个向量的每个维度写入codes中。在查询时,同样把query对应的向量转换为codes,然后计算query和索引codes的hammings距离。
127 /*n:向量个数,x:向量,k:返回条数, distances:距离,labels:向量唯一标识*/
128 void IndexLSH::search (
129 idx_t n,
130 const float *x,
131 idx_t k,
132 float *distances,
133 idx_t *labels) const
134 {
135 FAISS_THROW_IF_NOT (is_trained);
136 const float *xt = apply_preprocess (n, x); ///转换为低维向量
137 ScopeDeleter<float> del (xt == x ? nullptr : xt);
138
139 uint8_t * qcodes = new uint8_t [n * bytes_per_vec];
140 ScopeDeleter<uint8_t> del2 (qcodes);
141
142 fvecs2bitvecs (xt, qcodes, nbits, n); ///向量转换为bit构成的数组(每个向量对应一个bit)
143
144 int * idistances = new int [n * k];
145 ScopeDeleter<int> del3 (idistances);
146 /*n:向量个数, k:每个查询向量返回条数,labels:向量的idx , idistances:距离 */
147 int_maxheap_array_t res = { size_t(n), size_t(k), labels, idistances};
148
149 hammings_knn_hc (&res, qcodes, codes.data(),
150 ntotal, bytes_per_vec, true); ///求距离
151
152
153 // convert distances to floats
154 for (int i = 0; i < k * n; i++)
155 distances[i] = idistances[i];
156
157 }