package mil.nga.giat.geowave.mapreduce; import java.util.HashMap; import java.util.Map; import mil.nga.giat.geowave.core.index.ByteArrayId; import mil.nga.giat.geowave.core.store.adapter.AdapterStore; import mil.nga.giat.geowave.core.store.adapter.DataAdapter; import org.apache.hadoop.io.ObjectWritable; import org.apache.hadoop.io.Writable; /** * Use this class to maintain a set of serializers per adapters associated with * the context of a single mapper or reducer. The intent is to support * maintaining single set of Writable instances. By the nature of holding single * instances of Writable instances by the serializers, this class and its * contents may be only accessed by one 'worker' (at a time). * * The helper methods assume all Writable instances are wrapped in an * ObjectWritable. The reason for this approach, consistent with other support * classes in this package, is to allow mappers and reducers to use the generic * ObjectWritable since entry inputs maybe be associated with different * adapters, and thus have different associated Writable instances. * Configuration of Hadoop Mappers and Reducers requires a specific type. * */ public class HadoopWritableSerializationTool { private final AdapterStore adapterStore; private final Map<ByteArrayId, HadoopWritableSerializer<Object, Writable>> serializers = new HashMap<ByteArrayId, HadoopWritableSerializer<Object, Writable>>(); private final ObjectWritable objectWritable = new ObjectWritable(); public HadoopWritableSerializationTool( final AdapterStore adapterStore ) { super(); this.adapterStore = adapterStore; } public AdapterStore getAdapterStore() { return adapterStore; } public DataAdapter<?> getAdapter( final ByteArrayId adapterId ) { return adapterStore.getAdapter(adapterId); } public HadoopWritableSerializer<Object, Writable> getHadoopWritableSerializerForAdapter( final ByteArrayId adapterID ) { HadoopWritableSerializer<Object, Writable> serializer = serializers.get(adapterID); if (serializer == null) { DataAdapter<?> adapter; if ((adapterStore != null) && ((adapter = adapterStore.getAdapter(adapterID)) != null) && (adapter instanceof HadoopDataAdapter)) { serializer = ((HadoopDataAdapter<Object, Writable>) adapter).createWritableSerializer(); serializers.put( adapterID, serializer); } else { serializer = new HadoopWritableSerializer<Object, Writable>() { final ObjectWritable writable = new ObjectWritable(); @Override public ObjectWritable toWritable( final Object entry ) { writable.set(entry); return writable; } @Override public Object fromWritable( final Writable writable ) { return ((ObjectWritable) writable).get(); } }; } } return serializer; } public ObjectWritable toWritable( final ByteArrayId adapterID, final Object entry ) { if (entry instanceof Writable) { objectWritable.set(entry); } else { objectWritable.set(getHadoopWritableSerializerForAdapter( adapterID).toWritable( entry)); } return objectWritable; } public Object fromWritable( final ByteArrayId adapterID, final ObjectWritable writable ) { final Object innerObj = writable.get(); return (innerObj instanceof Writable) ? getHadoopWritableSerializerForAdapter( adapterID).fromWritable( (Writable) innerObj) : innerObj; } }