enum usearch_admission_t Values
usearch_reject_k | 0 | Skip the key; the walk still routes through it. |
|---|---|---|
usearch_admit_k | 1 | Report the key among the matches. |
Sometimes you may want to cross-reference search results against some external database or filter them by some criteria. In most engines, you’d have to manually perform paging requests, successively filtering the results. In USearch you can pass a predicate to the search, which is applied during graph traversal.
void admits_tenant(usearch_key_t const* keys, usearch_admission_t* admissions, size_t count, void* state) {
for (size_t i = 0; i != count; ++i)
admissions[i] = keys[i].bytes[0] == *(uint8_t const*)state ? usearch_admit_k : usearch_reject_k;
}
uint8_t tenant = 7;
usearch_dense_search(&(usearch_dense_search_t) {.index = index,
.executor = executor,
.outcome = &outcome,
.count = 1,
.queries = {query, 0, 128, usearch_scalar_f32_k},
.matches = &matches,
.arena = arena,
.wanted = 10,
.predicate = {admits_tenant, &tenant}});The predicate judges a batch of candidates per call, a quad of them at a time during a walk, so a handler backed by an external store answers each batch in one round trip.
Rejected entries still route the walk, so recall holds at low selectivity, and the predicate judges every scored candidate, concurrently on the executor’s threads, so it must be fast and tolerate that.
An exact scan asks it only about entries closer than the worst match a query already holds, which makes the scan the fallback for predicates too selective for a walk to cross.
A host predicate cannot narrow a device walk, so a VRAM search with one reports usearch_status_unsupported_k.
Long calls take a usearch_progress_t: a handler, which is also the only way to stop one, its state, and how many reports it hears:
usearch_continuation_t stop_when_asked(size_t completed, size_t total, void* state) {
return *(int const*)state ? usearch_cancel_k : usearch_continue_k;
}
int stop = 0;
usearch_dense_search(&(usearch_dense_search_t) {
.index = index, .executor = executor, .outcome = &outcome, .count = 1000000, .queries = queries,
.wanted = 10, .arena = arena, .matches = &matches, .progress = {stop_when_asked, &stop, 20}});Counts are in whatever units the verb consumes, entries for an insertion, queries for a search, shards for a checkpoint, and the handler is never called concurrently or after the call is final.
A call reports at most steps times, the last at completion, and zero steps derive to ten.
A batch verb hands its engine one slice per step, and a call without a handler runs as one slice, since every engine bounds its own scratch.
A stopped call reports usearch_status_cancelled_k and leaves its outputs NULL.
An insertion claims every entry before its first report, so its handler only reports, and all its entries publish at once.
usearch_admission_tWhether a predicate admits one candidate key or passes over it.enum usearch_admission_t usearch_reject_k | 0 | Skip the key; the walk still routes through it. |
|---|---|---|
usearch_admit_k | 1 | Report the key among the matches. |
usearch_predicate_callback_tAdmits or rejects count candidate keys at once, never zero, writing one admission per key into admissions, a buffer the library owns for the call, so a handler backed by an external store answers them in one round trip.typedef void(*) usearch_predicate_callback_t(usearch_key_t const *keys, usearch_admission_t *admissions, size_t count, void *state); Called concurrently from the executor's threads.
usearch_predicate_cost_tHow costly one predicate call is, which decides how many keys each call carries.enum usearch_predicate_cost_t usearch_predicate_cost_cheap_k | 0 | Asked as candidates arrive, at most four keys a call, with nothing buffered. |
|---|---|---|
usearch_predicate_cost_expensive_k | 1 | Asked once per traversal round or scan run about every candidate it gathered, for handlers that pay per call, such as a lookup in an external database. |
usearch_predicate_tWhich candidate keys a search may report: a handler and the state it is called with.struct usearch_predicate_t callback | usearch_predicate_callback_t | The optional handler; NULL admits every key. |
|---|---|---|
state | void * | Opaque pointer forwarded into every callback call. |
cost | usearch_predicate_cost_t | How many keys each callback call carries; zero stays cheap. |
usearch_continuation_tWhether the operation a handler is watching carries on or unwinds.enum usearch_continuation_t usearch_continue_k | 0 | Carry on to the next unit of work. |
|---|---|---|
usearch_cancel_k | 1 | Stop and report usearch_status_cancelled_k; whether finished increments stand is each verb's own contract. |
usearch_progress_callback_tPeriodic report of a long operation's advance, and the caller's chance to stop it.typedef usearch_continuation_t(*) usearch_progress_callback_t(size_t completed, size_t total, void *state); Counts are in whatever units the verb consumes - entries for an insertion, queries for a search, shards for a checkpoint - so one handler serves every one of them.
Never invoked concurrently, however many threads perform the work, so the handler needs no synchronization of its own - and never after the call it was passed to stores its final status.
Arguments, in order:
completed: units finished so far, never decreasing across one call's reports.total: units the call finishes unless cancelled.state: the opaque pointer registered alongside the handler, forwarded verbatim.usearch_progress_tHow a long call reports its advance: a handler, its state, and how many reports it hears.struct usearch_progress_t A batch verb splits its units into steps nearly equal slices, hands each to its engine whole and reports after each; a verb whose engine counts its own units, a checkpoint's shards or a refinement's nodes, forwards only the ticks that cross into the next slice. Without a handler the call runs as one slice and reports nothing.
callback | usearch_progress_callback_t | The optional handler; NULL skips every report. |
|---|---|---|
state | void * | Opaque pointer forwarded into every callback call. |
steps | size_t | Reports a call makes at most, the last at completion; zero derives to ten. |