[SPARK-3250] Implement Gap Sampling optimization for random sampling

More efficient sampling, based on Gap Sampling optimization:
http://erikerlandson.github.io/blog/2014/09/11/faster-random-samples-with-gap-sampling/

I think you might be referring to a comment I made on the dev email list.  It turns out that  for `rdd.randomSplit(), it needs to check for random number inside the particular range [lb, ub), because that is how it consistently partitions data across multiple RDDs.  It does this in combination with setting the random seed the same, so each split RDD gets a particular partitioned subset of the input data.

If you are simply doing random sampling with some bernoulli probability, then you