/* * Copyright 2014-2016 CyberVision, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.kaaproject.kaa.server.common.core.algorithms.delta; import static org.kaaproject.kaa.server.common.core.algorithms.CommonConstants.DELTA; import org.apache.avro.Schema; import org.apache.avro.generic.GenericArray; import org.apache.avro.generic.GenericData; import org.apache.avro.generic.GenericRecord; import org.kaaproject.kaa.common.avro.GenericAvroConverter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.Arrays; import java.util.LinkedList; import java.util.Queue; /** * The Class AvroBinaryDelta. * * @author Yaroslav Zeygerman */ public final class AvroBinaryDelta implements RawBinaryDelta { /** * The Constant LOG. */ private static final Logger LOG = LoggerFactory.getLogger(AvroBinaryDelta.class); /** * The Constant serialVersionUID. */ private static final long serialVersionUID = 4311409282997230034L; /** * The schema. */ private transient Schema schema; /** * The delta queue. */ private transient Queue<GenericRecord> deltaQueue; /** * The serialized data. */ private byte[] serializedData; /** * Instantiates a new avro binary delta during deserialization. */ public AvroBinaryDelta() { super(); this.deltaQueue = new LinkedList<GenericRecord>(); } /** * Instantiates a new avro binary delta. * * @param schema the schema */ public AvroBinaryDelta(Schema schema) { this(); this.schema = schema; } /** * Adds the delta. * * @param delta the delta */ public synchronized void addDelta(GenericRecord delta) { deltaQueue.offer(delta); } /* * (non-Javadoc) * * @see * org.kaaproject.kaa.server.operations.service.delta.RawBinaryDelta#getData() */ @Override public synchronized byte[] getData() throws IOException { if (deltaQueue != null && !deltaQueue.isEmpty()) { GenericArray deltaArray = new GenericData.Array(deltaQueue.size(), schema); while (!deltaQueue.isEmpty()) { GenericRecord deltaT = new GenericData.Record( schema.getElementType()); deltaT.put(DELTA, deltaQueue.poll()); deltaArray.add(deltaT); } GenericAvroConverter<GenericArray> converter = new GenericAvroConverter<>(schema); serializedData = converter.encode(deltaArray); if (LOG.isTraceEnabled()) { LOG.trace("Delta array: {}", deltaArray.toString()); } } return serializedData != null ? Arrays.copyOf(serializedData, serializedData.length) : null; } /* * (non-Javadoc) * * @see * org.kaaproject.kaa.server.operations.service.delta.RawBinaryDelta#hasChanges * () */ @Override public synchronized boolean hasChanges() { return serializedData != null || !(deltaQueue == null || deltaQueue.isEmpty()); } /* * (non-Javadoc) * * @see java.lang.Object#hashCode() */ @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + Arrays.hashCode(serializedData); return result; } /* * (non-Javadoc) * * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } AvroBinaryDelta other = (AvroBinaryDelta) obj; if (!Arrays.equals(serializedData, other.serializedData)) { return false; } return true; } }