blob: c194cd66a9ba24538a5fe80290f3a5d0e228d1dc [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.datasketches.theta;
import org.apache.datasketches.Family;
import org.apache.datasketches.memory.WritableMemory;
/**
* Computes a set difference, A-AND-NOT-B, of two theta sketches.
* This class includes both stateful and stateless operations.
*
* <p>The stateful operation is as follows:</p>
* <pre><code>
* AnotB anotb = SetOperationBuilder.buildAnotB();
*
* anotb.setA(Sketch skA); //The first argument.
* anotb.notB(Sketch skB); //The second (subtraction) argument.
* anotb.notB(Sketch skC); // ...any number of additional subtractions...
* anotb.getResult(false); //Get an interim result.
* anotb.notB(Sketch skD); //Additional subtractions.
* anotb.getResult(true); //Final result and resets the AnotB operator.
* </code></pre>
*
* <p>The stateless operation is as follows:</p>
* <pre><code>
* AnotB anotb = SetOperationBuilder.buildAnotB();
*
* CompactSketch csk = anotb.aNotB(Sketch skA, Sketch skB);
* </code></pre>
*
* <p>Calling the <i>setA</i> operation a second time essentially clears the internal state and loads
* the new sketch.</p>
*
* <p>The stateless and stateful operations are independent of each other with the exception of
* sharing the same update hash seed loaded as the default seed or specified by the user as an
* argument to the builder.</p>
*
* @author Lee Rhodes
*/
public abstract class AnotB extends SetOperation {
@Override
public Family getFamily() {
return Family.A_NOT_B;
}
/**
* This is part of a multistep, stateful AnotB operation and sets the given Theta sketch as the
* first argument <i>A</i> of <i>A-AND-NOT-B</i>. This overwrites the internal state of this
* AnotB operator with the contents of the given sketch.
* This sets the stage for multiple following <i>notB</i> steps.
*
* <p>An input argument of null will throw an exception.</p>
*
* <p>Rationale: In mathematics a "null set" is a set with no members, which we call an empty set.
* That is distinctly different from the java <i>null</i>, which represents a nonexistent object.
* In most cases it is a programming error due to some object that was not properly initialized.
* With a null as the first argument, we cannot know what the user's intent is.
* Since it is very likely that a <i>null</i> is a programming error, we throw a an exception.</p>
*
* <p>An enpty input argument will set the internal state to empty.</p>
*
* <p>Rationale: An empty set is a mathematically legal concept. Although it makes any subsequent,
* valid argument for B irrelvant, we must allow this and assume the user knows what they are
* doing.</p>
*
* <p>Performing {@link #getResult(boolean)} just after this step will return a compact form of
* the given argument.</p>
*
* @param skA The incoming sketch for the first argument, <i>A</i>.
*/
public abstract void setA(Sketch skA);
/**
* This is part of a multistep, stateful AnotB operation and sets the given Theta sketch as the
* second (or <i>n+1</i>th) argument <i>B</i> of <i>A-AND-NOT-B</i>.
* Performs an <i>AND NOT</i> operation with the existing internal state of this AnotB operator.
*
* <p>An input argument of null or empty is ignored.</p>
*
* <p>Rationale: A <i>null</i> for the second or following arguments is more tollerable because
* <i>A NOT null</i> is still <i>A</i> even if we don't know exactly what the null represents. It
* clearly does not have any content that overlaps with <i>A</i>. Also, because this can be part of
* a multistep operation with multiple <i>notB</i> steps. Other following steps can still produce
* a valid result.</p>
*
* <p>Use {@link #getResult(boolean)} to obtain the result.</p>
*
* @param skB The incoming Theta sketch for the second (or following) argument <i>B</i>.
*/
public abstract void notB(Sketch skB);
/**
* Gets the result of the mutistep, stateful operation AnotB that have been executed with calls
* to {@link #setA(Sketch)} and ({@link #notB(Sketch)} or
* {@link #notB(org.apache.datasketches.theta.Sketch)}).
*
* @param reset If <i>true</i>, clears this operator to the empty state after this result is
* returned. Set this to <i>false</i> if you wish to obtain an intermediate result.
* @return the result of this operation as an ordered, on-heap {@link CompactSketch}.
*/
public abstract CompactSketch getResult(boolean reset);
/**
* Gets the result of this stateful set operation as a CompactSketch of the form based on
* the input arguments.
* The stateful input operations are {@link #setA(Sketch)} and {@link #notB(Sketch)}.
*
* @param dstOrdered If <i>true</i>, the result will be an ordered {@link CompactSketch}.
* <a href="{@docRoot}/resources/dictionary.html#dstOrdered">See Destination Ordered</a>.
*
* @param dstMem if not <i>null</i> the given Memory will be the target location of the result.
* <a href="{@docRoot}/resources/dictionary.html#dstMem">See Destination Memory</a>.
*
* @param reset If <i>true</i>, clears this operator to the empty state after this result is
* returned. Set this to <i>false</i> if you wish to obtain an intermediate result.
*
* @return the result of this operation as a {@link CompactSketch} of the chosen form.
*/
public abstract CompactSketch getResult(boolean dstOrdered, WritableMemory dstMem, boolean reset);
/**
* Perform A-and-not-B set operation on the two given sketches and return the result as an
* ordered CompactSketch on the heap.
*
* <p>This a stateless operation and has no impact on the internal state of this operator.
* Thus, this is not an accumulating update and does not interact with the {@link #setA(Sketch)},
* {@link #notB(Sketch)}, {@link #getResult(boolean)}, or
* {@link #getResult(boolean, WritableMemory, boolean)} methods.</p>
*
* <p>If either argument is null an exception is thrown.</p>
*
* <p>Rationale: In mathematics a "null set" is a set with no members, which we call an empty set.
* That is distinctly different from the java <i>null</i>, which represents a nonexistent object.
* In most cases <i>null</i> is a programming error due to a non-initialized object. </p>
*
* <p>With a null as the first argument we cannot know what the user's intent is and throw an
* exception. With a null as the second argument for this method we must return a result and
* there is no following possible viable arguments for the second argument so we thrown an
* exception.</p>
*
* @param skA The incoming sketch for the first argument. It must not be null.
* @param skB The incoming sketch for the second argument. It must not be null.
* @return an ordered CompactSketch on the heap
*/
public CompactSketch aNotB(final Sketch skA, final Sketch skB) {
return aNotB(skA, skB, true, null);
}
/**
* Perform A-and-not-B set operation on the two given sketches and return the result as a
* CompactSketch.
*
* <p>This a stateless operation and has no impact on the internal state of this operator.
* Thus, this is not an accumulating update and does not interact with the {@link #setA(Sketch)},
* {@link #notB(Sketch)}, {@link #getResult(boolean)}, or
* {@link #getResult(boolean, WritableMemory, boolean)} methods.</p>
*
* <p>If either argument is null an exception is thrown.</p>
*
* <p>Rationale: In mathematics a "null set" is a set with no members, which we call an empty set.
* That is distinctly different from the java <i>null</i>, which represents a nonexistent object.
* In most cases <i>null</i> is a programming error due to a non-initialized object. </p>
*
* <p>With a null as the first argument we cannot know what the user's intent is and throw an
* exception. With a null as the second argument for this method we must return a result and
* there is no following possible viable arguments for the second argument so we thrown an
* exception.</p>
*
* @param skA The incoming sketch for the first argument. It must not be null.
* @param skB The incoming sketch for the second argument. It must not be null.
* @param dstOrdered
* <a href="{@docRoot}/resources/dictionary.html#dstOrdered">See Destination Ordered</a>.
* @param dstMem
* <a href="{@docRoot}/resources/dictionary.html#dstMem">See Destination Memory</a>.
* @return the result as a CompactSketch.
*/
public abstract CompactSketch aNotB(Sketch skA, Sketch skB, boolean dstOrdered,
WritableMemory dstMem);
//Deprecated methods
/**
* @see #aNotB(Sketch, Sketch)
*
* @param skA The incoming sketch for the first argument
* @param skB The incoming sketch for the second argument
* @deprecated v2.0.0. Instead use {@link #aNotB(Sketch, Sketch)}.
*/
@Deprecated
public abstract void update(Sketch skA, Sketch skB);
/**
* Gets the result of the stateful operations, {@link #setA(Sketch)} and {@link #notB(Sketch)},
* as an ordered CompactSketch on the Java heap.
* This clears the state of this operator after the result is returned.
* @return the result of the stateful operations as an ordered CompactSketch on the Java heap.
* @deprecated v2.0.0. Instead use {@link #getResult(boolean)} or
* {@link #getResult(boolean, WritableMemory, boolean)}.
*/
@Deprecated
public CompactSketch getResult() {
return getResult(true, null, true);
}
/**
* Gets the result of the stateful operations {@link #setA(Sketch)} and {@link #notB(Sketch)}.
* This clears the state of this operator after the result is returned.
* @param dstOrdered
* <a href="{@docRoot}/resources/dictionary.html#dstOrdered">See Destination Ordered</a>.
*
* @param dstMem
* <a href="{@docRoot}/resources/dictionary.html#dstMem">See Destination Memory</a>.
*
* @return the result of this set operation as a CompactSketch of the chosen form.
* @deprecated v2.0.0. Instead use {@link #getResult(boolean)} or
* {@link #getResult(boolean, WritableMemory, boolean)}.
*/
@Deprecated
public CompactSketch getResult(final boolean dstOrdered, final WritableMemory dstMem) {
return getResult(dstOrdered, dstMem, true);
}
}