index/gamma_hnsw.cc
void add_link(GammaHNSW& hnsw,
              DistanceComputer& qdis,
              storage_idx_t src, storage_idx_t dest,
              int level)
{
  size_t begin, end;
  hnsw.neighbor_range(src, level, &begin, &end);
  if (hnsw.neighbors[end - 1] == -1) {
    // there is enough room, find a slot to add it
    size_t i = end;
    while(i > begin) {
      if (hnsw.neighbors[i - 1] != -1) break;
      i--;
    }
    hnsw.neighbors[i] = dest;
    return;
  }

  // otherwise we let them fight out which to keep

  // copy to resultSet...
  std::priority_queue<NodeDistCloser> resultSet;
  resultSet.emplace(qdis.symmetric_dis(src, dest), dest);
  for (size_t i = begin; i < end; i++) { // HERE WAS THE BUG
    storage_idx_t neigh = hnsw.neighbors[i];
    resultSet.emplace(qdis.symmetric_dis(src, neigh), neigh);
  }

  shrink_neighbor_list(qdis, resultSet, end - begin);

  // ...and back
  size_t i = begin;
  while (resultSet.size()) {
    hnsw.neighbors[i++] = resultSet.top().id;
    resultSet.pop();
  }
  // they may have shrunk more than just by 1 element
  while(i < end) {
    hnsw.neighbors[i++] = -1;
  }
}
/// add a link between two elements, possibly shrinking the list
/// of links to make room for it.
add a link between two elements, possibly shrinking the list
of links to make room for it.
add a link between two elements possibly shrinking the list of links to make room for it .
void add_link(GammaHNSW& hnsw,
              DistanceComputer& qdis,
              storage_idx_t src, storage_idx_t dest,
              int level)
{
  size_t begin, end;
  hnsw.neighbor_range(src, level, &begin, &end);
  if (hnsw.neighbors[end - 1] == -1) {
    size_t i = end;
    while(i > begin) {
      if (hnsw.neighbors[i - 1] != -1) break;
      i--;
    }
    hnsw.neighbors[i] = dest;
    return;
  }
  std::priority_queue<NodeDistCloser> resultSet;
  resultSet.emplace(qdis.symmetric_dis(src, dest), dest);
  for (size_t i = begin; i < end; i++) { 
    storage_idx_t neigh = hnsw.neighbors[i];
    resultSet.emplace(qdis.symmetric_dis(src, neigh), neigh);
  }
  shrink_neighbor_list(qdis, resultSet, end - begin);
  size_t i = begin;
  while (resultSet.size()) {
    hnsw.neighbors[i++] = resultSet.top().id;
    resultSet.pop();
  }
  while(i < end) {
    hnsw.neighbors[i++] = -1;
  }
}
void add_link ( GammaHNSW & hnsw , DistanceComputer & qdis , storage_idx_t src , storage_idx_t dest , int level ) { size_t begin , end ; hnsw . neighbor_range ( src , level , & begin , & end ) ; if ( hnsw . neighbors [ end - 1 ] == -1 ) { size_t i = end ; while ( i > begin ) { if ( hnsw . neighbors [ i - 1 ] != -1 ) break ; i -- ; } hnsw . neighbors [ i ] = dest ; return ; } std :: priority_queue < NodeDistCloser > resultSet ; resultSet . emplace ( qdis . symmetric_dis ( src , dest ) , dest ) ; for ( size_t i = begin ; i < end ; i ++ ) { storage_idx_t neigh = hnsw . neighbors [ i ] ; resultSet . emplace ( qdis . symmetric_dis ( src , neigh ) , neigh ) ; } shrink_neighbor_list ( qdis , resultSet , end - begin ) ; size_t i = begin ; while ( resultSet . size ( ) ) { hnsw . neighbors [ i ++ ] = resultSet . top ( ) . id ; resultSet . pop ( ) ; } while ( i < end ) { hnsw . neighbors [ i ++ ] = -1 ; } }
add a link between two elements, possibly shrinking the list
of links to make room for it.
add a link between two elements possibly shrinking the list of links to make room for it .
// there is enough room, find a slot to add it // otherwise we let them fight out which to keep // copy to resultSet... // HERE WAS THE BUG // ...and back // they may have shrunk more than just by 1 element