[SPARK-4027][Streaming] HDFSBasedBlockRDD to read received either from BlockManager or WAL in HDFS

As part of the initiative of preventing data loss on streaming driver failure, this sub-task implements a BlockRDD that is backed by HDFS. This BlockRDD can either read data from the Spark's BlockManager, or read the data from file-segments in write ahead log in HDFS. 

Most of this code has been written by @harishreedharan

Alright, I agree about the lazy semantics. But then @JoshRosen  suggestion is more intuitive to me.  Something like 
```
def blockLocations = getBlockIdLocations().get(partition.blockId)
def segmentLocations = HdfsUtils.getBlockLocations(...)
blockLocations.orElse(segmentLocations).getOrElse(Array.empty)
```

All the logical alternatives are clearly in one line. And it does not have verbose, almost redundant code as `case Some(loc) => loc`