12 #include "AuxIndexStructures.h"
14 #include "FaissAssert.h"
26 lims =
new size_t [nq + 1];
27 memset (
lims, 0,
sizeof(*
lims) * (nq + 1));
40 for (
int i = 0; i <
nq; i++) {
50 RangeSearchResult::~RangeSearchResult () {
65 BufferList::BufferList (
size_t buffer_size):
66 buffer_size (buffer_size)
71 BufferList::~BufferList ()
73 for (
int i = 0; i < buffers.size(); i++) {
74 delete [] buffers[i].ids;
75 delete [] buffers[i].dis;
80 if (
wp == buffer_size) {
83 Buffer & buf = buffers.back();
92 Buffer buf = {
new idx_t [buffer_size],
new float [buffer_size]};
93 buffers.push_back (buf);
100 idx_t * dest_ids,
float *dest_dis)
102 size_t bno = ofs / buffer_size;
103 ofs -= bno * buffer_size;
105 size_t ncopy = ofs + n < buffer_size ? n : buffer_size - ofs;
106 Buffer buf = buffers [bno];
107 memcpy (dest_ids, buf.ids + ofs, ncopy *
sizeof(*dest_ids));
108 memcpy (dest_dis, buf.dis + ofs, ncopy *
sizeof(*dest_dis));
145 void RangeSearchPartialResult::finalize ()
161 for (
int i = 0; i <
queries.size(); i++) {
163 res->
lims[qres.qno] = qres.nres;
171 for (
int i = 0; i <
queries.size(); i++) {
178 res->
lims[qres.qno] += qres.nres;
185 partial_results,
bool do_delete)
188 int npres = partial_results.size();
189 if (npres == 0)
return;
191 size_t nx = result->
nq;
194 for (
size_t i = 0; i < nx; i++) {
195 for (
int j = 0; j < npres; j++) {
196 if (!partial_results[j])
continue;
197 result->
lims[i] += partial_results[j]->queries[i].nres;
201 for (
int j = 0; j < npres; j++) {
202 if (!partial_results[j])
continue;
203 partial_results[j]->copy_result (
true);
205 delete partial_results[j];
206 partial_results[j] =
nullptr;
211 for (
size_t i = nx; i > 0; i--) {
212 result->
lims [i] = result->
lims [i - 1];
214 result->
lims [0] = 0;
221 IDSelectorRange::IDSelectorRange (idx_t imin, idx_t imax):
222 imin (imin), imax (imax)
226 bool IDSelectorRange::is_member (idx_t
id)
const
228 return id >= imin &&
id < imax;
236 IDSelectorBatch::IDSelectorBatch (
long n,
const idx_t *indices)
239 while (n > (1L << nbits)) nbits++;
243 mask = (1L << nbits) - 1;
244 bloom.resize (1UL << (nbits - 3), 0);
245 for (
long i = 0; i < n; i++) {
246 long id = indices[i];
249 bloom[
id >> 3] |= 1 << (
id & 7);
253 bool IDSelectorBatch::is_member (idx_t i)
const
256 if(!(bloom[im>>3] & (1 << (im & 7)))) {
268 int IOReader::fileno ()
270 FAISS_THROW_MSG (
"IOReader does not support memory mapping");
273 int IOWriter::fileno ()
275 FAISS_THROW_MSG (
"IOWriter does not support memory mapping");
279 size_t VectorIOWriter::operator()(
280 const void *ptr,
size_t size,
size_t nitems)
282 size_t o = data.size();
283 data.resize(o + size * nitems);
284 memcpy (&data[o], ptr, size * nitems);
288 size_t VectorIOReader::operator()(
289 void *ptr,
size_t size,
size_t nitems)
291 if (rp >= data.size())
return 0;
292 size_t nremain = (data.size() - rp) / size;
293 if (nremain < nitems) nitems = nremain;
294 memcpy (ptr, &data[rp], size * nitems);
305 std::unique_ptr<InterruptCallback> InterruptCallback::instance;
308 if (!instance.get()) {
311 if (instance->want_interrupt ()) {
312 FAISS_THROW_MSG (
"computation interrupted");
317 if (!instance.get()) {
320 return instance->want_interrupt();
325 if (!instance.get()) {
329 return std::max((
size_t)10 * 10 * 1000 * 1000 / (flops + 1), (
size_t)1);
std::vector< RangeQueryResult > queries
query ids + nb of results per query.
result structure for a single query
void append_buffer()
create a new buffer
void copy_range(size_t ofs, size_t n, idx_t *dest_ids, float *dest_dis)
void set_lims()
called by range_search before do_allocation
RangeSearchResult(idx_t nq, bool alloc_lims=true)
lims must be allocated on input to range_search.
size_t wp
write pointer in the last buffer.
float * distances
corresponding distances (not sorted)
void add(idx_t id, float dis)
add one result, possibly appending a new buffer if needed
virtual void do_allocation()
static bool is_interrupted()
void copy_result(bool incremental=false)
called by range_search after do_allocation
static void merge(std::vector< RangeSearchPartialResult * > &partial_results, bool do_delete=true)
RangeQueryResult & new_result(idx_t qno)
begin a new result
size_t buffer_size
size of the result buffers used
static size_t get_period_hint(size_t flops)
size_t * lims
size (nq + 1)
void add(float dis, idx_t id)
called by search function to report a new result
idx_t * labels
result for query i is labels[lims[i]:lims[i+1]]
RangeSearchPartialResult(RangeSearchResult *res_in)
eventually the result will be stored in res_in