com.tangosol.io.DecorationOnlyDeltaCompressor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of coherence Show documentation
Show all versions of coherence Show documentation
Oracle Coherence Community Edition
/*
* Copyright (c) 2000, 2023, Oracle and/or its affiliates.
*
* Licensed under the Universal Permissive License v 1.0 as shown at
* https://oss.oracle.com/licenses/upl.
*/
package com.tangosol.io;
import com.tangosol.util.Base;
import com.tangosol.util.Binary;
import com.tangosol.util.ExternalizableHelper;
/**
* DecorationOnlyDeltaCompressor is a DeltaCompressor which optimizes for
* "decoration-only" updates. A decoration-only update is a one where the
* intrinsic value does not change, but the "decorations" may. An example of
* such an update could be generated by the ReadWriteBackingMap after successful
* write-behind operations to indicate that the store has been completed.
* Updates to the intrinsic value are not optimized/compressed at all.
*
* While this compressor does not produce any compression/optimization in the
* general case, it allows for optimizing decoration changes while avoiding the
* need to "read" the old value when applying an actual intrinsic change. This
* could be used to defer/avoid unnecessary access to a potentially expensive
* backup map.
*
* DecorationOnlyBinaryDelta:
* DecorationDelta
* Value // the new value in "whole" form (possibly decorated)
* null
*
* DecorationDelta:
* BIN_DECO_ONLY (decorated) // apply the decorations to the old value
* BIN_DECO_ONLY (undecorated) // undecorate the old value
*
*
* @author rhl 2011.08.09
* @since Coherence 3.7.1
*/
public class DecorationOnlyDeltaCompressor
extends ExternalizableHelper
implements DeltaCompressor
{
// ----- DeltaCompressor interface --------------------------------------
/**
* {@inheritDoc}
*/
public ReadBuffer extractDelta(ReadBuffer bufOld, ReadBuffer bufNew)
{
if (bufOld == null)
{
// null old value means a "replace"
return bufNew;
}
if (Base.equals(bufOld, bufNew))
{
// null means no change (see DeltaCompressor)
return null;
}
boolean fDecoNew = isDecorated(bufNew);
boolean fDecoOld = isDecorated(bufOld);
if ((fDecoNew || fDecoOld) &&
Base.equals(getUndecorated(bufNew), getUndecorated(bufOld)))
{
// we don't need to send the entire new value;
// just the DECO_ONLY token decorated with the new set of
// decorations (or undecorated for a "remove") will suffice
Binary binDecoOnly = BIN_DECO_ONLY;
if (fDecoNew)
{
ReadBuffer[] abufDeco = getDecorations(bufNew);
// null out the 0th element to avoid overriding the value
abufDeco[DECO_VALUE] = null;
bufNew = decorate(binDecoOnly, abufDeco);
}
else
{
bufNew = binDecoOnly; // "remove the decorations" token
}
}
return bufNew;
}
/**
* {@inheritDoc}
*/
public ReadBuffer applyDelta(ReadBuffer bufOld, ReadBuffer bufDelta)
{
if (bufDelta == null)
{
// null means no change (see DeltaCompressor)
return bufOld;
}
if (BIN_DECO_ONLY.equals(getUndecorated(bufDelta)))
{
// decoration-only update; transfer or remove the decorations
ReadBuffer[] abufDeco = getDecorations(bufDelta);
// we only want the 'non-value' decorations
abufDeco[DECO_VALUE] = null;
bufOld = getUndecorated(bufOld);
if (bufOld.length() == 0 && abufDeco.length > 1)
{
bufOld = AbstractReadBuffer.NO_BINARY;
}
return abufDeco.length == 1 ? bufOld : decorate(bufOld, abufDeco);
}
else
{
// the "delta" is the new value in "whole" form
return bufDelta;
}
}
// ----- constants -------------------------------------------------------
/**
* A place-holder Binary value used by the compressor to indicate a
* decoration-only update.
*/
protected static Binary BIN_DECO_ONLY = new Binary(new byte[] {(byte) 0xFF});
}