/** * This software is licensed to you under the Apache License, Version 2.0 (the * "Apache License"). * * LinkedIn's contributions are made under the Apache License. If you contribute * to the Software, the contributions will be deemed to have been made under the * Apache License, unless you expressly indicate otherwise. Please do not make any * contributions that would be inconsistent with the Apache License. * * You may obtain a copy of the Apache License at http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, this software * distributed under the Apache License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the Apache * License for the specific language governing permissions and limitations for the * software governed under the Apache License. * * © 2012 LinkedIn Corp. All Rights Reserved. */ package com.senseidb.search.req; import com.linkedin.norbert.network.Serializer; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; import org.apache.commons.io.IOUtils; import org.apache.log4j.Logger; import org.iq80.snappy.SnappyInputStream; import org.iq80.snappy.SnappyOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Arrays; /** * Takes any Serializer and compresses/decompresses the data. */ public class SenseiSnappySerializer<RequestType, ResponseType> implements Serializer<RequestType, ResponseType> { private final static Logger logger = Logger.getLogger(SenseiSnappySerializer.class); private final Serializer<RequestType, ResponseType> _inner; private final String requestName; private final String responseName; public SenseiSnappySerializer(Serializer<RequestType, ResponseType> inner) { _inner = inner; requestName = "SnappyRequest(" + (inner.requestName() == null ? "" : inner.requestName()) + ")"; responseName = "SnappyResponse(" + (inner.responseName() == null ? "" : inner.responseName()) + ")"; } public static <RequestType, ResponseType> SenseiSnappySerializer<RequestType, ResponseType> wrap(Serializer<RequestType, ResponseType> inner) { return new SenseiSnappySerializer<RequestType, ResponseType>(inner); } @Override public String requestName() { return requestName; } @Override public String responseName() { return responseName; } @Override public RequestType requestFromBytes(byte[] compressedBytes) { ByteArrayInputStream bais = new ByteArrayInputStream(compressedBytes); byte[] uncompressedBytes = null; try { SnappyInputStream snappyInputStream = new SnappyInputStream(bais); uncompressedBytes = IOUtils.toByteArray(snappyInputStream); } catch (IOException e) { // This should not happen logger.warn("Could not decompress sensei request", e); } RequestType request = _inner.requestFromBytes(uncompressedBytes); // // For debugging serialization // byte[] bytes2 = _inner.requestToBytes(request); // RequestType request2 = _inner.requestFromBytes(bytes2); // if(!request.equals(request2)) { // throw new IllegalArgumentException(); // } return request; } @Override public ResponseType responseFromBytes(byte[] compressedBytes) { ByteArrayInputStream bais = new ByteArrayInputStream(compressedBytes); byte[] uncompressedBytes = null; try { SnappyInputStream snappyInputStream = new SnappyInputStream(bais); uncompressedBytes = IOUtils.toByteArray(snappyInputStream); } catch (IOException e) { // This should not happen logger.warn("Could not decompress sensei request", e); } ResponseType response = _inner.responseFromBytes(uncompressedBytes); // // For debugging serialization // byte[] bytes = _inner.responseToBytes(response); // ResponseType response2 = _inner.responseFromBytes(bytes); // if(!response.equals(response2)) { // throw new IllegalArgumentException(); // } return response; } @Override public byte[] requestToBytes(RequestType request) { byte[] uncompressedBytes = _inner.requestToBytes(request); // // For debugging serialization // RequestType request2 = _inner.requestFromBytes(uncompressedBytes); // if(!request.equals(request2)) { // throw new IllegalArgumentException(); // } ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { SnappyOutputStream snappyOutputStream = new SnappyOutputStream(baos); snappyOutputStream.write(uncompressedBytes); snappyOutputStream.close(); baos.close(); } catch (IOException e) { // This should not happen logger.error("Could not compress sensei request ", e); } return baos.toByteArray(); } @Override public byte[] responseToBytes(ResponseType response) { byte[] uncompressedBytes = _inner.responseToBytes(response); // // For debugging serialization // ResponseType response2 = _inner.responseFromBytes(uncompressedBytes); // if(!response.equals(response2)) { // throw new IllegalArgumentException(); // } ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { SnappyOutputStream snappyOutputStream = new SnappyOutputStream(baos); snappyOutputStream.write(uncompressedBytes); snappyOutputStream.close(); baos.close(); } catch (IOException e) { // This should not happen logger.error("Could not compress sensei request ", e); } return baos.toByteArray(); } }