code: private void computeNeighborhoods(Relation<O> relation, DataStore<SetDBIDs> knns, ModifiableDBIDs pruned, WritableDataStore<ModifiableDBIDs> rNNminuskNNs) {
      FiniteProgress prog = LOG.isVerbose() ? new FiniteProgress("Finding RkNN", relation.size(), LOG) : null;
      for(DBIDIter iter = relation.iterDBIDs(); iter.valid(); iter.advance()) {
        DBIDs knn = knns.get(iter);
        int count = 1; // The point itself.
        for(DBIDIter niter = knn.iter(); niter.valid(); niter.advance()) {
          // Ignore the query point itself.
          if(DBIDUtil.equal(iter, niter)) {
            continue;
          }
          // As we did not initialize count with the rNN size, we check all
          // neighbors here.
          if(knns.get(niter).contains(iter)) {
            count++;
          }
          else {
            // In contrast to INFLO pseudocode, we only update if it is not found,
            // i.e., if it is in RkNN \setminus kNN, to save memory.
            rNNminuskNNs.get(niter).add(iter);
          }
        }
        // INFLO pruning rule
        if(count >= knn.size() * m) {
          pruned.add(iter);
        }
        LOG.incrementProcessed(prog);
      }
      LOG.ensureCompleted(prog);
    }
docs: Compute the reverse kNN minus the kNN.
  <p>
  This is based on algorithm 2 (two-way search) from the INFLO paper, but
  unfortunately this algorithm does not compute the RkNN correctly, but
  rather \( RkNN \cap kNN \), which is quite useless given that we will use
  the union of that with kNN later on. Therefore, we decided to rather follow
  what appears to be the idea of the method, not the literal pseudocode
  included.
  
  @param relation Data relation
  @param knns Stored nearest neighbors
  @param pruned Pruned objects: with too many neighbors
  @param rNNminuskNNs reverse kNN storage