code: func (ethash *Ethash) dataset(block uint64, async bool) *dataset {
  	// Retrieve the requested ethash dataset
  	epoch := block / epochLength
  	currentI, futureI := ethash.datasets.get(epoch)
  	current := currentI.(*dataset)
  
  	// If async is specified, generate everything in a background thread
  	if async && !current.generated() {
  		go func() {
  			current.generate(ethash.config.DatasetDir, ethash.config.DatasetsOnDisk, ethash.config.PowMode == ModeTest)
  
  			if futureI != nil {
  				future := futureI.(*dataset)
  				future.generate(ethash.config.DatasetDir, ethash.config.DatasetsOnDisk, ethash.config.PowMode == ModeTest)
  			}
  		}()
  	} else {
  		// Either blocking generation was requested, or already done
  		current.generate(ethash.config.DatasetDir, ethash.config.DatasetsOnDisk, ethash.config.PowMode == ModeTest)
  
  		if futureI != nil {
  			future := futureI.(*dataset)
  			go future.generate(ethash.config.DatasetDir, ethash.config.DatasetsOnDisk, ethash.config.PowMode == ModeTest)
  		}
  	}
  	return current
  }
docs: // dataset tries to retrieve a mining dataset for the specified block number
  // by first checking against a list of in-memory datasets, then against DAGs
  // stored on disk, and finally generating one if none can be found.
  //
  // If async is specified, not only the future but the current DAG is also
  // generates on a background thread.