Figure out the best diffs to use to reach all our required volumes.

def _analyzeDontMeasure(self, chunkSize, willMeasureLater, *sinks):
        """  Figure out the best diffs to use to reach all our required volumes. """
        nodes = [None]
        height = 1

        def sortKey(node):
            if node is None:
                return None
            return (node.intermediate, self._totalSize(node))

        while len(nodes) > 0:
            logger.debug("Analyzing %d nodes for height %d...", len(nodes), height)

            nodes.sort(key=sortKey)

            for fromNode in nodes:
                if self._height(fromNode) >= height:
                    continue

                if fromNode is not None and fromNode.diffSize is None:
                    continue

                fromVol = fromNode.volume if fromNode else None

                logger.debug("Following edges from %s", fromVol)

                for sink in sinks:
                    # logger.debug(
                    #     "Listing edges in %s",
                    #     sink
                    # )

                    for edge in sink.getEdges(fromVol):
                        toVol = edge.toVol

                        # logger.debug("Edge: %s", edge)

                        # Skip any edges already in the destination
                        if sink != self.dest and self.dest.hasEdge(edge):
                            continue

                        if toVol in self.nodes:
                            toNode = self.nodes[toVol]
                        # Don't transfer any edges we won't need in the destination
                        # elif sink != self.dest:
                        #     logger.debug("Won't transfer unnecessary %s", edge)
                        #     continue
                        else:
                            toNode = _Node(toVol, True)
                            self.nodes[toVol] = toNode

                        logger.debug("Considering %s", edge)

                        edgeSize = edge.size
                        if edge.sizeIsEstimated:
                            if willMeasureLater:
                                # Slight preference for accurate sizes
                                edgeSize *= 1.2
                            else:
                                # Large preference for accurate sizes
                                edgeSize *= 2

                        newCost = self._cost(sink, edgeSize, fromNode, height)

                        if toNode.diff is None:
                            oldCost = None
                        else:
                            oldCost = self._cost(
                                toNode.sink,
                                toNode.diffSize,
                                self._getNode(toNode.previous),
                                self._height(toNode)
                            )

                        # Don't use a more-expensive path
                        if oldCost is not None and oldCost <= newCost:
                            continue

                        # Don't create circular paths
                        if self._wouldLoop(fromVol, toVol):
                            # logger.debug("Ignoring looping edge: %s", toVol.display(sink))
                            continue

                        # if measureSize and sink != self.dest and edge.sizeIsEstimated:
                        #     sink.measureSize(edge, chunkSize)
                        #     newCost = self._cost(sink, edge.size, fromSize, height)
                        #     if oldCost is not None and oldCost <= newCost:
                        #         continue

                        logger.debug(
                            "Replacing edge (%s -> %s cost)\n%s",
                            humanize(oldCost),
                            humanize(newCost),
                            toNode.display(sink)
                        )
                        # logger.debug("Cost elements: %s", dict(
                        #     sink=str(sink),
                        #     edgeSize=humanize(edgeSize),
                        #     fromSize=humanize(fromSize),
                        #     height=height,
                        # ))

                        toNode.diff = edge

            nodes = [node for node in self.nodes.values() if self._height(node) == height]
            height += 1

        self._prune()

        for node in self.nodes.values():
            node.height = self._height(node)
            if node.diff is None:
                logger.error(
                    "No source diffs for %s",
                    node.volume.display(sinks[-1], detail="line"),
                )