[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 believe someone else made this same comment elsewhere, but, is it not faster and maybe as clear to write `rng.nextDouble() <= ub - lb`? There is no need for conditionals.