search method

List<VectorSearchHit> search(
  1. Vector query,
  2. int k, {
  3. VectorMetric? metric,
})

Top-k nearest neighbors of query under ADC. The metric arg is accepted for API symmetry but ignored — PQ ranks in approximate squared-L2 always.

Implementation

List<VectorSearchHit> search(
  Vector query,
  int k, {
  VectorMetric? metric,
}) {
  if (!_pq.trained) {
    throw StateError('PqIndex.search: call train() first');
  }
  if (query.dim != dim) {
    throw StateError(
      'PqIndex.search: query dim ${query.dim} != index dim $dim',
    );
  }
  if (k <= 0 || _ids.isEmpty) return const [];
  final n = _ids.length;
  final effK = math.min(k, n);
  final lut = _pq.buildDistanceTable(query.values);
  final scores = List<double>.filled(effK, 0.0);
  final ids = List<Object?>.filled(effK, null);
  var filled = 0;
  for (var r = 0; r < n; r++) {
    final di = _pq.lookupDistance(lut, _codes, r * m);
    if (filled < effK) {
      var j = filled;
      while (j > 0 && di < scores[j - 1]) {
        scores[j] = scores[j - 1];
        ids[j] = ids[j - 1];
        j--;
      }
      scores[j] = di;
      ids[j] = _ids[r];
      filled++;
    } else if (di < scores[effK - 1]) {
      var j = effK - 1;
      while (j > 0 && di < scores[j - 1]) {
        scores[j] = scores[j - 1];
        ids[j] = ids[j - 1];
        j--;
      }
      scores[j] = di;
      ids[j] = _ids[r];
    }
  }
  return [
    for (var i = 0; i < filled; i++) VectorSearchHit(ids[i], scores[i]),
  ];
}