public virtual int SearchKNN(MetricDB db, object q, int K, IResult res, short[] A, short current_rank_A)
{
int abs_pos = 0;
int count_dist = 0;
foreach (var piv in this.Pivs) {
var pivOBJ = db [piv.objID];
var dqp = db.Dist (q, pivOBJ);
res.Push (piv.objID, dqp);
++count_dist;
// checking near ball radius
if (dqp <= piv.last_near + res.CoveringRadius) {
for (int j = 0; j < piv.num_near; ++j, ++abs_pos) {
var item = this.Items [abs_pos];
// checking covering pivot
if (A[item.ObjID] == current_rank_A && Math.Abs (item.Dist - dqp) <= res.CoveringRadius) {
++A [item.ObjID];
}
}
} else {
abs_pos += piv.num_near;
}
// checking external radius
if (dqp + res.CoveringRadius >= piv.first_far) {
for (int j = 0; j < piv.num_far; ++j, ++abs_pos) {
var item = this.Items [abs_pos];
// checking covering pivot
if (A[item.ObjID] == current_rank_A && Math.Abs (item.Dist - dqp) <= res.CoveringRadius) {
++A [item.ObjID];
}
}
} else {
abs_pos += piv.num_far;
}
if (dqp + res.CoveringRadius <= piv.last_near || piv.first_far <= dqp - res.CoveringRadius) {
break;
}
}
return count_dist;
}