All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.twitter.elephantbird.mapreduce.io.ProtobufConverter Maven / Gradle / Ivy

The newest version!
package com.twitter.elephantbird.mapreduce.io;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.Message;
import com.google.protobuf.UninitializedMessageException;
import com.twitter.elephantbird.util.Protobufs;
import com.twitter.elephantbird.util.TypeRef;

/**
 * {@link BinaryConverter} for Protobufs
 */
public class ProtobufConverter implements BinaryConverter {
  private static final Logger LOG = LoggerFactory.getLogger(ProtobufConverter.class);

  private Message defaultInstance;
  private TypeRef typeRef;

  // limit the number of warnings in case of serialization errors.
  private static final int MAX_WARNINGS = 100;
  private static int numWarningsLogged = 0;

  private static void logWarning(String message, Throwable t) {
    // does not need to be thread safe
    if ( numWarningsLogged < MAX_WARNINGS ) {
      LOG.info(message, t);
      numWarningsLogged++;
    }
  }

  /**
   * Returns a ProtobufConverter for a given Protobuf class.
   */
  public static  ProtobufConverter newInstance(Class protoClass) {
    return new ProtobufConverter(new TypeRef(protoClass){});
  }

  public static  ProtobufConverter newInstance(TypeRef typeRef) {
    return new ProtobufConverter(typeRef);
  }

  public ProtobufConverter(TypeRef typeRef) {
    this.typeRef = typeRef;
  }

  @Override
  public M fromBytes(byte[] messageBuffer) throws DecodeException {
    try {
      return fromBytes(messageBuffer, 0, messageBuffer.length);
    } catch (InvalidProtocolBufferException ipbe) {
      throw new DecodeException(ipbe);
    } catch (UninitializedMessageException ume) {
      throw new DecodeException(ume);
    }
  }

  @SuppressWarnings("unchecked")
  public M fromBytes(byte[] messageBuffer, int offset, int len)
      throws InvalidProtocolBufferException, UninitializedMessageException {
    if (defaultInstance == null) {
      defaultInstance = Protobufs.getMessageBuilder(typeRef.getRawClass())
                                 .getDefaultInstanceForType();
    }
    return (M) defaultInstance.newBuilderForType()
                              .mergeFrom(messageBuffer, offset, len)
                              .build();
  }

  @Override
  public byte[] toBytes(M message) {
    return message.toByteArray();
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj)
      return true;
    try {
      return typeRef.getType().equals(((ProtobufConverter)obj).typeRef.getType());
    } catch (ClassCastException e) {
      return false;
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy