001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.util; 019 020import org.apache.yetus.audience.InterfaceAudience; 021import org.slf4j.Logger; 022import org.slf4j.LoggerFactory; 023 024import com.google.protobuf.ByteString; 025import com.google.protobuf.HBaseZeroCopyByteString; 026 027/** 028 * Hack to workaround HBASE-10304 issue that keeps bubbling up when a mapreduce context. 029 */ 030@InterfaceAudience.Private 031public class ByteStringer { 032 private static final Logger LOG = LoggerFactory.getLogger(ByteStringer.class); 033 034 /** 035 * Flag set at class loading time. 036 */ 037 private static boolean USE_ZEROCOPYBYTESTRING = true; 038 039 // Can I classload HBaseZeroCopyByteString without IllegalAccessError? 040 // If we can, use it passing ByteStrings to pb else use native ByteString though more costly 041 // because it makes a copy of the passed in array. 042 static { 043 try { 044 HBaseZeroCopyByteString.wrap(new byte [0]); 045 } catch (IllegalAccessError iae) { 046 USE_ZEROCOPYBYTESTRING = false; 047 LOG.debug("Failed to classload HBaseZeroCopyByteString: " + iae.toString()); 048 } 049 } 050 051 private ByteStringer() { 052 super(); 053 } 054 055 /** 056 * Wraps a byte array in a {@link ByteString} without copying it. 057 */ 058 public static ByteString wrap(final byte[] array) { 059 return USE_ZEROCOPYBYTESTRING? HBaseZeroCopyByteString.wrap(array): ByteString.copyFrom(array); 060 } 061 062 /** 063 * Wraps a subset of a byte array in a {@link ByteString} without copying it. 064 */ 065 public static ByteString wrap(final byte[] array, int offset, int length) { 066 return USE_ZEROCOPYBYTESTRING? HBaseZeroCopyByteString.wrap(array, offset, length): 067 ByteString.copyFrom(array, offset, length); 068 } 069}