docs: public PointerDensityHierarchyRepresentationResult run(Database db, Relation<O> relation) {
      final DistanceQuery<O> distQ = db.getDistanceQuery(relation, getDistanceFunction());
      final KNNQuery<O> knnQ = db.getKNNQuery(distQ, minPts);
      // We need array addressing later.
      final ArrayDBIDs ids = DBIDUtil.ensureArray(relation.getDBIDs());
  
      // 1. Compute the core distances
      // minPts + 1: ignore query point.
      final WritableDoubleDataStore coredists = computeCoreDists(ids, knnQ, minPts);
  
      final int numedges = ids.size() - 1;
      DoubleLongHeap heap = new DoubleLongMinHeap(numedges);
      // 2. Build spanning tree.
      FiniteProgress mprog = LOG.isVerbose() ? new FiniteProgress("Computing minimum spanning tree (n-1 edges)", numedges, LOG) : null;
      PrimsMinimumSpanningTree.processDense(ids, //
          new HDBSCANAdapter(ids, coredists, distQ), //
          new HeapMSTCollector(heap, mprog, LOG));
      LOG.ensureCompleted(mprog);
      // Storage for pointer representation:
      WritableDBIDDataStore pi = DataStoreUtil.makeDBIDStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_STATIC);
      WritableDoubleDataStore lambda = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_STATIC, Double.POSITIVE_INFINITY);
      convertToPointerRepresentation(ids, heap, pi, lambda);
  
      return new PointerDensityHierarchyRepresentationResult(ids, pi, lambda, distQ.getDistanceFunction().isSquared(), coredists);
    }