@@ -20,6 +20,8 @@ package org.apache.spark.rdd
2020import java .text .SimpleDateFormat
2121import java .util .Date
2222
23+ import scala .reflect .ClassTag
24+
2325import org .apache .hadoop .conf .{Configurable , Configuration }
2426import org .apache .hadoop .io .Writable
2527import org .apache .hadoop .mapreduce ._
@@ -28,18 +30,17 @@ import org.apache.spark.broadcast.Broadcast
2830import org .apache .spark .deploy .SparkHadoopUtil
2931import org .apache .spark .executor .DataReadMethod
3032import org .apache .spark .mapreduce .SparkHadoopMapReduceUtil
33+ import org .apache .spark .sql .{SQLConf , SQLContext }
34+ import org .apache .spark .sql .execution .datasources .parquet .UnsafeRowParquetRecordReader
3135import org .apache .spark .storage .StorageLevel
32- import org .apache .spark .unsafe .types .UTF8String
33- import org .apache .spark .util .{Utils , SerializableConfiguration , ShutdownHookManager }
36+ import org .apache .spark .util .{SerializableConfiguration , ShutdownHookManager }
3437import org .apache .spark .{Partition => SparkPartition , _ }
3538
36- import scala .reflect .ClassTag
37-
3839
3940private [spark] class SqlNewHadoopPartition (
40- rddId : Int ,
41- val index : Int ,
42- rawSplit : InputSplit with Writable )
41+ rddId : Int ,
42+ val index : Int ,
43+ rawSplit : InputSplit with Writable )
4344 extends SparkPartition {
4445
4546 val serializableHadoopSplit = new SerializableWritable (rawSplit)
@@ -48,26 +49,26 @@ private[spark] class SqlNewHadoopPartition(
4849}
4950
5051/**
51- * An RDD that provides core functionality for reading data stored in Hadoop (e.g., files in HDFS,
52- * sources in HBase, or S3), using the new MapReduce API (`org.apache.hadoop.mapreduce`).
53- * It is based on [[org.apache.spark.rdd.NewHadoopRDD ]]. It has three additions.
54- * 1. A shared broadcast Hadoop Configuration.
55- * 2. An optional closure `initDriverSideJobFuncOpt` that set configurations at the driver side
56- * to the shared Hadoop Configuration.
57- * 3. An optional closure `initLocalJobFuncOpt` that set configurations at both the driver side
58- * and the executor side to the shared Hadoop Configuration.
59- *
60- * Note: This is RDD is basically a cloned version of [[org.apache.spark.rdd.NewHadoopRDD ]] with
61- * changes based on [[org.apache.spark.rdd.HadoopRDD ]].
62- */
52+ * An RDD that provides core functionality for reading data stored in Hadoop (e.g., files in HDFS,
53+ * sources in HBase, or S3), using the new MapReduce API (`org.apache.hadoop.mapreduce`).
54+ * It is based on [[org.apache.spark.rdd.NewHadoopRDD ]]. It has three additions.
55+ * 1. A shared broadcast Hadoop Configuration.
56+ * 2. An optional closure `initDriverSideJobFuncOpt` that set configurations at the driver side
57+ * to the shared Hadoop Configuration.
58+ * 3. An optional closure `initLocalJobFuncOpt` that set configurations at both the driver side
59+ * and the executor side to the shared Hadoop Configuration.
60+ *
61+ * Note: This is RDD is basically a cloned version of [[org.apache.spark.rdd.NewHadoopRDD ]] with
62+ * changes based on [[org.apache.spark.rdd.HadoopRDD ]].
63+ */
6364private [spark] class SqlNewHadoopRDD [V : ClassTag ](
64- sc : SparkContext ,
65- broadcastedConf : Broadcast [SerializableConfiguration ],
66- @ transient private val initDriverSideJobFuncOpt : Option [Job => Unit ],
67- initLocalJobFuncOpt : Option [Job => Unit ],
68- inputFormatClass : Class [_ <: InputFormat [Void , V ]],
69- valueClass : Class [V ])
70- extends RDD [V ](sc , Nil )
65+ sqlContext : SQLContext ,
66+ broadcastedConf : Broadcast [SerializableConfiguration ],
67+ @ transient private val initDriverSideJobFuncOpt : Option [Job => Unit ],
68+ initLocalJobFuncOpt : Option [Job => Unit ],
69+ inputFormatClass : Class [_ <: InputFormat [Void , V ]],
70+ valueClass : Class [V ])
71+ extends RDD [V ](sqlContext.sparkContext , Nil )
7172 with SparkHadoopMapReduceUtil
7273 with Logging {
7374
@@ -99,7 +100,7 @@ private[spark] class SqlNewHadoopRDD[V: ClassTag](
99100 // If true, enable using the custom RecordReader for parquet. This only works for
100101 // a subset of the types (no complex types).
101102 protected val enableUnsafeRowParquetReader : Boolean =
102- sc.conf.getBoolean( " spark.parquet.enableUnsafeRowRecordReader " , true )
103+ sqlContext.getConf( SQLConf . PARQUET_UNSAFE_ROW_RECORD_READER_ENABLED .key).toBoolean
103104
104105 override def getPartitions : Array [SparkPartition ] = {
105106 val conf = getConf(isDriverSide = true )
@@ -120,8 +121,8 @@ private[spark] class SqlNewHadoopRDD[V: ClassTag](
120121 }
121122
122123 override def compute (
123- theSplit : SparkPartition ,
124- context : TaskContext ): Iterator [V ] = {
124+ theSplit : SparkPartition ,
125+ context : TaskContext ): Iterator [V ] = {
125126 val iter = new Iterator [V ] {
126127 val split = theSplit.asInstanceOf [SqlNewHadoopPartition ]
127128 logInfo(" Input split: " + split.serializableHadoopSplit)
@@ -132,8 +133,8 @@ private[spark] class SqlNewHadoopRDD[V: ClassTag](
132133
133134 // Sets the thread local variable for the file's name
134135 split.serializableHadoopSplit.value match {
135- case fs : FileSplit => SqlNewHadoopRDD .setInputFileName(fs.getPath.toString)
136- case _ => SqlNewHadoopRDD .unsetInputFileName()
136+ case fs : FileSplit => SqlNewHadoopRDDState .setInputFileName(fs.getPath.toString)
137+ case _ => SqlNewHadoopRDDState .unsetInputFileName()
137138 }
138139
139140 // Find a function that will return the FileSystem bytes read by this thread. Do this before
@@ -163,15 +164,13 @@ private[spark] class SqlNewHadoopRDD[V: ClassTag](
163164 * TODO: plumb this through a different way?
164165 */
165166 if (enableUnsafeRowParquetReader &&
166- format.getClass.getName == " org.apache.parquet.hadoop.ParquetInputFormat" ) {
167- // TODO: move this class to sql.execution and remove this.
168- reader = Utils .classForName(
169- " org.apache.spark.sql.execution.datasources.parquet.UnsafeRowParquetRecordReader" )
170- .newInstance().asInstanceOf [RecordReader [Void , V ]]
171- try {
172- reader.initialize(split.serializableHadoopSplit.value, hadoopAttemptContext)
173- } catch {
174- case e : Exception => reader = null
167+ format.getClass.getName == " org.apache.parquet.hadoop.ParquetInputFormat" ) {
168+ val parquetReader : UnsafeRowParquetRecordReader = new UnsafeRowParquetRecordReader ()
169+ if (! parquetReader.tryInitialize(
170+ split.serializableHadoopSplit.value, hadoopAttemptContext)) {
171+ parquetReader.close()
172+ } else {
173+ reader = parquetReader.asInstanceOf [RecordReader [Void , V ]]
175174 }
176175 }
177176
@@ -217,7 +216,7 @@ private[spark] class SqlNewHadoopRDD[V: ClassTag](
217216
218217 private def close () {
219218 if (reader != null ) {
220- SqlNewHadoopRDD .unsetInputFileName()
219+ SqlNewHadoopRDDState .unsetInputFileName()
221220 // Close the reader and release it. Note: it's very important that we don't close the
222221 // reader more than once, since that exposes us to MAPREDUCE-5918 when running against
223222 // Hadoop 1.x and older Hadoop 2.x releases. That bug can lead to non-deterministic
@@ -235,7 +234,7 @@ private[spark] class SqlNewHadoopRDD[V: ClassTag](
235234 if (bytesReadCallback.isDefined) {
236235 inputMetrics.updateBytesRead()
237236 } else if (split.serializableHadoopSplit.value.isInstanceOf [FileSplit ] ||
238- split.serializableHadoopSplit.value.isInstanceOf [CombineFileSplit ]) {
237+ split.serializableHadoopSplit.value.isInstanceOf [CombineFileSplit ]) {
239238 // If we can't get the bytes read from the FS stats, fall back to the split size,
240239 // which may be inaccurate.
241240 try {
@@ -276,32 +275,15 @@ private[spark] class SqlNewHadoopRDD[V: ClassTag](
276275 }
277276 super .persist(storageLevel)
278277 }
279- }
280-
281- private [spark] object SqlNewHadoopRDD {
282-
283- /**
284- * The thread variable for the name of the current file being read. This is used by
285- * the InputFileName function in Spark SQL.
286- */
287- private [this ] val inputFileName : ThreadLocal [UTF8String ] = new ThreadLocal [UTF8String ] {
288- override protected def initialValue (): UTF8String = UTF8String .fromString(" " )
289- }
290-
291- def getInputFileName (): UTF8String = inputFileName.get()
292-
293- private [spark] def setInputFileName (file : String ) = inputFileName.set(UTF8String .fromString(file))
294-
295- private [spark] def unsetInputFileName (): Unit = inputFileName.remove()
296278
297279 /**
298- * Analogous to [[org.apache.spark.rdd.MapPartitionsRDD ]], but passes in an InputSplit to
299- * the given function rather than the index of the partition.
300- */
280+ * Analogous to [[org.apache.spark.rdd.MapPartitionsRDD ]], but passes in an InputSplit to
281+ * the given function rather than the index of the partition.
282+ */
301283 private [spark] class NewHadoopMapPartitionsWithSplitRDD [U : ClassTag , T : ClassTag ](
302- prev : RDD [T ],
303- f : (InputSplit , Iterator [T ]) => Iterator [U ],
304- preservesPartitioning : Boolean = false )
284+ prev : RDD [T ],
285+ f : (InputSplit , Iterator [T ]) => Iterator [U ],
286+ preservesPartitioning : Boolean = false )
305287 extends RDD [U ](prev) {
306288
307289 override val partitioner = if (preservesPartitioning) firstParent[T ].partitioner else None
0 commit comments