Add a TableReader trait and implementations for scanning tables stored in Hadoop, Tachyon, and Spark's block manager.

Mostly refactoring, the TableReader implementations decouple main table scan execution paths from TableScanOperator. However, pruning RDDs is still dependent on operator-specific executions, so that hasn't been ported.

The main benefit is that TableReaders can be reused for other scenarios, such as SharkLoadTask or TableToRDD execution.