[ 
https://issues.apache.org/jira/browse/HADOOP-4065?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12631913#action_12631913
 ] 

Pete Wyckoff commented on HADOOP-4065:
--------------------------------------

proposal (which does not touch any existing code):

1. extend Deserializer with an interface that requires returning the actual 
type being deserialized
{code:title=ParameterizedDeserializer.java}
public interface ParameterizedDeserializer<T> extends Deserializer<T> {
  Class<? extends T> getRealClass() ;
}
{code}
2. create a Serialization implementation which gets the Serializer/Deserializer 
from the JobConf - e.g.,
{code}
   public ParameterizedDeserializer<R> getDeserializer(Class<R> c) {            
                                                                                
                                            
     // ignore c. doesn't matter, it is coming from the configuration           
                                                                                
                                             
      Class<? extends ParameterizedDeserializer> t = 
conf.getClass("mapred.input.io.deserializer", null, 
ParameterizedDeserializer.class);                                               
                       
      return ReflectionUtils.newInstance(t, conf);                              
                                                                                
                                             
    } 
{code}
3. Parameterized deserializers will (typically) get the specific class (? 
extends T - e.g., T= Record) they are implementing from the JobConf. e.g.,
{code}
    this.recordClass = conf.getClass("mapred.input.io.record_class", null, 
Record.class);                                                                  
                                                 
{code}

4. RecordReader.getValueClass looks like:
{code}
  public R createValue() {                                                      
                                                                                
                               
    return (R)ReflectionUtils.newInstance(deserializer.getRealClass(),conf);    
                                                                                
                                                          
  }                    
{code}

5. Setting up the JobConf:
{code}
      job.setClass("mapred.input.io.deserializer", 
.serializer.RecordIOSerialization.RecordIODeserializer.class, 
serializer.ParameterizedDeserializer.class);          
                                                                                
                                                                                
                                             
      // Set this so the RecordIO Deserializer knows the specific Record class 
in the file                                                                     
                                              
      job.setClass("mapred.input.io.recordio_class", 
FlatFileDeserializerTestObj.class, record.Record.class);             
{code}

These classes could all go into a contrib directory devoted to contributing 
Serialization implementations.  Or it could be in core and mapred.

Issues - why not get the  deserialization specific class in 
Serialization.getDeserializer (and implement getRealClass in this Serialization 
implementation - no need for any new interface) and pass that in to any normal 
Deserializer?  This would make things more uniform and also mean the 
Deserializer is any old deserializer.
{code}
Class<? extends R> realClass = 
conf.getClass("mapred.input.io.deserializer.class", null, Class<R>);            
                                                                                
                       
return 
ReflectionUtils.newInstance(conf.getClass("mapred.input.deserializer",null,Deserializer.class));
{code}
And then we can construct an instance of realClass and pass that into any 
Deserializer.deserialize(T t).

I am just learning generics and it doesn't seem 
conf.getClass("mapred.input.io.deserializer.class", null, Class<R>);  is 
possible because it doesn't accept Class<R>. It wants something more like 
Record.class, forcing us into doing this in the deserizlier.



> support for reading binary data from flat files
> -----------------------------------------------
>
>                 Key: HADOOP-4065
>                 URL: https://issues.apache.org/jira/browse/HADOOP-4065
>             Project: Hadoop Core
>          Issue Type: Bug
>          Components: mapred
>            Reporter: Joydeep Sen Sarma
>         Attachments: HADOOP-4065.0.txt, HADOOP-4065.1.txt, ThriftFlatFile.java
>
>
> like textinputformat - looking for a concrete implementation to read binary 
> records from a flat file (that may be compressed).
> it's assumed that hadoop can't split such a file. so the inputformat can set 
> splittable to false.
> tricky aspects are:
> - how to know what class the file contains (has to be in a configuration 
> somewhere).
> - how to determine EOF (would be nice if hadoop can determine EOF and not 
> have the deserializer throw an exception  (which is hard to distinguish from 
> a exception due to corruptions?)). this is easy for non-compressed streams - 
> for compressed streams - DecompressorStream has a useful looking 
> getAvailable() call - except the class is marked package private.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to