org.roaringbitmap.buffer.MappeableContainer Maven / Gradle / Ivy
The newest version!
/*
* (c) the authors Licensed under the Apache License, Version 2.0.
*/
package org.roaringbitmap.buffer;
import org.roaringbitmap.Container;
import org.roaringbitmap.IntConsumer;
import org.roaringbitmap.PeekableShortIterator;
import org.roaringbitmap.ShortIterator;
import java.io.DataOutput;
import java.io.Externalizable;
import java.io.IOException;
import java.util.NoSuchElementException;
/**
* Base container class. This class is similar to org.roaringbitmap.Container but meant to be used
* with memory mapping.
*/
public abstract class MappeableContainer implements Iterable, Cloneable, Externalizable {
/**
* Create a container initialized with a range of consecutive values
*
* @param start first index
* @param last last index (range is exclusive)
* @return a new container initialized with the specified values
*/
public static MappeableContainer rangeOfOnes(final int start, final int last) {
final int sizeAsArrayContainer = MappeableArrayContainer.serializedSizeInBytes(last - start);
final int sizeAsRunContainer = MappeableRunContainer.serializedSizeInBytes(1);
MappeableContainer answer = sizeAsRunContainer < sizeAsArrayContainer
? new MappeableRunContainer() : new MappeableArrayContainer();
answer = answer.iadd(start, last);
return answer;
}
/**
* Return a new container with all shorts in [begin,end) added using an unsigned interpretation.
*
* @param begin start of range (inclusive)
* @param end end of range (exclusive)
* @return the new container
*/
public abstract MappeableContainer add(int begin, int end);
/**
* Add a short to the container. May generate a new container.
*
* @param x short to be added
* @return the new container
*/
public abstract MappeableContainer add(short x);
/**
* Computes the bitwise AND of this container with another (intersection). This container as well
* as the provided container are left unaffected.
*
* @param x other container
* @return aggregated container
*/
public abstract MappeableContainer and(MappeableArrayContainer x);
/**
* Computes the bitwise AND of this container with another (intersection). This container as well
* as the provided container are left unaffected.
*
* @param x other container
* @return aggregated container
*/
public abstract MappeableContainer and(MappeableBitmapContainer x);
protected MappeableContainer and(MappeableContainer x) {
if (x instanceof MappeableArrayContainer) {
return and((MappeableArrayContainer) x);
} else if (x instanceof MappeableRunContainer) {
return and((MappeableRunContainer) x);
}
return and((MappeableBitmapContainer) x);
}
protected abstract int andCardinality(MappeableArrayContainer x);
protected abstract int andCardinality(MappeableBitmapContainer x);
protected abstract int andCardinality(MappeableRunContainer x);
/**
* Returns the cardinality of the XOR between the passed container and this
* container without materialising a temporary container.
* @param other other container
* @return the cardinality of the symmetric difference of the two containers
*/
public int xorCardinality(MappeableContainer other) {
return getCardinality() + other.getCardinality() - 2 * andCardinality(other);
}
/**
* Computes the bitwise AND of this container with another (intersection). This container as well
* as the provided container are left unaffected.
*
* @param x other container
* @return aggregated container
*/
public int andCardinality(MappeableContainer x) {
if (this.getCardinality() == 0) {
return 0;
} else if (x.getCardinality() == 0) {
return 0;
} else {
if (x instanceof MappeableArrayContainer) {
return andCardinality((MappeableArrayContainer) x);
} else if (x instanceof MappeableBitmapContainer) {
return andCardinality((MappeableBitmapContainer) x);
}
return andCardinality((MappeableRunContainer) x);
}
}
/**
* Computes the bitwise AND of this container with another (intersection). This container as well
* as the provided container are left unaffected.
*
* @param x other container
* @return aggregated container
*/
public abstract MappeableContainer and(MappeableRunContainer x);
/**
* Computes the bitwise ANDNOT of this container with another (difference). This container as well
* as the provided container are left unaffected.
*
* @param x other container
* @return aggregated container
*/
public abstract MappeableContainer andNot(MappeableArrayContainer x);
/**
* Computes the bitwise ANDNOT of this container with another (difference). This container as well
* as the provided container are left unaffected.
*
* @param x other container
* @return aggregated container
*/
public abstract MappeableContainer andNot(MappeableBitmapContainer x);
protected MappeableContainer andNot(MappeableContainer x) {
if (x instanceof MappeableArrayContainer) {
return andNot((MappeableArrayContainer) x);
} else if (x instanceof MappeableRunContainer) {
return andNot((MappeableRunContainer) x);
}
return andNot((MappeableBitmapContainer) x);
}
/**
* Computes the bitwise ANDNOT of this container with another (difference). This container as well
* as the provided container are left unaffected.
*
* @param x other container
* @return aggregated container
*/
public abstract MappeableContainer andNot(MappeableRunContainer x);
/**
* Empties the container
*/
public abstract void clear();
@Override
public abstract MappeableContainer clone();
/**
* Checks whether the contain contains the provided value
*
* @param x value to check
* @return whether the value is in the container
*/
public abstract boolean contains(short x);
/**
* Checks whether the container is a subset of this container or not
* @param subset the container to be tested
* @return true if the parameter is a subset of this container
*/
public boolean contains(MappeableContainer subset) {
if(subset instanceof MappeableRunContainer) {
return contains((MappeableRunContainer)subset);
} else if(subset instanceof MappeableArrayContainer) {
return contains((MappeableArrayContainer) subset);
} else if(subset instanceof MappeableBitmapContainer){
return contains((MappeableBitmapContainer)subset);
}
return false;
}
protected abstract boolean contains(MappeableRunContainer runContainer);
protected abstract boolean contains(MappeableArrayContainer arrayContainer);
protected abstract boolean contains(MappeableBitmapContainer bitmapContainer);
/**
* Fill the least significant 16 bits of the integer array, starting at index index, with the
* short values from this container. The caller is responsible to allocate enough room. The most
* significant 16 bits of each integer are given by the most significant bits of the provided
* mask.
*
* @param x provided array
* @param i starting index
* @param mask indicates most significant bits
*/
public abstract void fillLeastSignificant16bits(int[] x, int i, int mask);
/**
* Add a short to the container if it is not present, otherwise remove it. May generate a new
* container.
*
* @param x short to be added
* @return the new container
*/
public abstract MappeableContainer flip(short x);
/**
* Size of the underlying array
*
* @return size in bytes
*/
protected abstract int getArraySizeInBytes();
/**
* Computes the distinct number of short values in the container. Can be expected to run in
* constant time.
*
* @return the cardinality
*/
public abstract int getCardinality();
/**
* Get the name of this container.
*
* @return name of the container
*/
public String getContainerName() {
if (this instanceof MappeableBitmapContainer) {
return ContainerNames[0];
} else if (this instanceof MappeableArrayContainer) {
return ContainerNames[1];
} else {
return ContainerNames[2];
}
}
/**
* Name of the various possible containers
*/
public static String ContainerNames[] = {"mappeablebitmap","mappeablearray","mappeablerun"};
/**
* Iterator to visit the short values in the container in descending order.
*
* @return iterator
*/
public abstract ShortIterator getReverseShortIterator();
/**
* Iterator to visit the short values in the container in ascending order.
*
* @return iterator
*/
public abstract PeekableShortIterator getShortIterator();
/**
* Iterate through the values of this container and pass them
* along to the IntConsumer, using msb as the 16 most significant bits.
* @param msb 16 most significant bits
* @param ic consumer
*/
public abstract void forEach(short msb, IntConsumer ic);
/**
* Computes an estimate of the memory usage of this container. The estimate is not meant to be
* exact.
*
* @return estimated memory usage in bytes
*/
public abstract int getSizeInBytes();
/**
* Add all shorts in [begin,end) using an unsigned interpretation. May generate a new container.
*
* @param begin start of range (inclusive)
* @param end end of range (exclusive)
* @return the new container
*/
public abstract MappeableContainer iadd(int begin, int end);
/**
* Computes the in-place bitwise AND of this container with another (intersection). The current
* container is generally modified, whereas the provided container (x) is unaffected. May generate
* a new container.
*
* @param x other container
* @return aggregated container
*/
public abstract MappeableContainer iand(MappeableArrayContainer x);
/**
* Computes the in-place bitwise AND of this container with another (intersection). The current
* container is generally modified, whereas the provided container (x) is unaffected. May generate
* a new container.
*
* @param x other container
* @return aggregated container
*/
public abstract MappeableContainer iand(MappeableBitmapContainer x);
protected MappeableContainer iand(MappeableContainer x) {
if (x instanceof MappeableArrayContainer) {
return iand((MappeableArrayContainer) x);
} else if (x instanceof MappeableRunContainer) {
return iand((MappeableRunContainer) x);
}
return iand((MappeableBitmapContainer) x);
}
/**
* Computes the in-place bitwise AND of this container with another (intersection). The current
* container is generally modified, whereas the provided container (x) is unaffected. May generate
* a new container.
*
* @param x other container
* @return aggregated container
*/
public abstract MappeableContainer iand(MappeableRunContainer x);
/**
* Computes the in-place bitwise ANDNOT of this container with another (difference). The current
* container is generally modified, whereas the provided container (x) is unaffected. May generate
* a new container.
*
* @param x other container
* @return aggregated container
*/
public abstract MappeableContainer iandNot(MappeableArrayContainer x);
/**
* Computes the in-place bitwise ANDNOT of this container with another (difference). The current
* container is generally modified, whereas the provided container (x) is unaffected. May generate
* a new container.
*
* @param x other container
* @return aggregated container
*/
public abstract MappeableContainer iandNot(MappeableBitmapContainer x);
protected MappeableContainer iandNot(MappeableContainer x) {
if (x instanceof MappeableArrayContainer) {
return iandNot((MappeableArrayContainer) x);
} else if (x instanceof MappeableRunContainer) {
return iandNot((MappeableRunContainer) x);
}
return iandNot((MappeableBitmapContainer) x);
}
/**
* Computes the in-place bitwise ANDNOT of this container with another (difference). The current
* container is generally modified, whereas the provided container (x) is unaffected. May generate
* a new container.
*
* @param x other container
* @return aggregated container
*/
public abstract MappeableContainer iandNot(MappeableRunContainer x);
/**
* Computes the in-place bitwise NOT of this container (complement). Only those bits within the
* range are affected. The current container is generally modified. May generate a new container.
*
* @param rangeStart beginning of range (inclusive); 0 is beginning of this container.
* @param rangeEnd ending of range (exclusive)
* @return (partially) completmented container
*/
public abstract MappeableContainer inot(int rangeStart, int rangeEnd);
/**
* Returns true if the current container intersects the other container.
*
* @param x other container
* @return whether they intersect
*/
public abstract boolean intersects(MappeableArrayContainer x);
/**
* Returns true if the current container intersects the other container.
*
* @param x other container
* @return whether they intersect
*/
public abstract boolean intersects(MappeableBitmapContainer x);
/**
* Returns true if the current container intersects the other container.
*
* @param x other container
* @return whether they intersect
*/
public boolean intersects(MappeableContainer x) {
if (x instanceof MappeableArrayContainer) {
return intersects((MappeableArrayContainer) x);
} else if (x instanceof MappeableBitmapContainer) {
return intersects((MappeableBitmapContainer) x);
}
return intersects((MappeableRunContainer) x);
}
/**
* Returns true if the current container intersects the other container.
*
* @param x other container
* @return whether they intersect
*/
public abstract boolean intersects(MappeableRunContainer x);
/**
* Computes the in-place bitwise OR of this container with another (union). The current container
* is generally modified, whereas the provided container (x) is unaffected. May generate a new
* container.
*
* @param x other container
* @return aggregated container
*/
public abstract MappeableContainer ior(MappeableArrayContainer x);
/**
* Computes the in-place bitwise OR of this container with another (union). The current container
* is generally modified, whereas the provided container (x) is unaffected. May generate a new
* container.
*
* @param x other container
* @return aggregated container
*/
public abstract MappeableContainer ior(MappeableBitmapContainer x);
protected MappeableContainer ior(MappeableContainer x) {
if (x instanceof MappeableArrayContainer) {
return ior((MappeableArrayContainer) x);
} else if (x instanceof MappeableRunContainer) {
return ior((MappeableRunContainer) x);
}
return ior((MappeableBitmapContainer) x);
}
/**
* Computes the in-place bitwise OR of this container with another (union). The current container
* is generally modified, whereas the provided container (x) is unaffected. May generate a new
* container.
*
* @param x other container
* @return aggregated container
*/
public abstract MappeableContainer ior(MappeableRunContainer x);
/**
* Remove shorts in [begin,end) using an unsigned interpretation. May generate a new container.
*
* @param begin start of range (inclusive)
* @param end end of range (exclusive)
* @return the new container
*/
public abstract MappeableContainer iremove(int begin, int end);
protected abstract boolean isArrayBacked();
/**
* Computes the in-place bitwise XOR of this container with another (symmetric difference). The
* current container is generally modified, whereas the provided container (x) is unaffected. May
* generate a new container.
*
* @param x other container
* @return aggregated container
*/
public abstract MappeableContainer ixor(MappeableArrayContainer x);
/**
* Computes the in-place bitwise XOR of this container with another (symmetric difference). The
* current container is generally modified, whereas the provided container (x) is unaffected. May
* generate a new container.
*
* @param x other container
* @return aggregated container
*/
public abstract MappeableContainer ixor(MappeableBitmapContainer x);
protected MappeableContainer ixor(MappeableContainer x) {
if (x instanceof MappeableArrayContainer) {
return ixor((MappeableArrayContainer) x);
} else if (x instanceof MappeableRunContainer) {
return ixor((MappeableRunContainer) x);
}
return ixor((MappeableBitmapContainer) x);
}
/**
* Computes the in-place bitwise XOR of this container with another (symmetric difference). The
* current container is generally modified, whereas the provided container (x) is unaffected. May
* generate a new container.
*
* @param x other container
* @return aggregated container
*/
public abstract MappeableContainer ixor(MappeableRunContainer x);
/**
* Computes the in-place bitwise OR of this container with another (union). The current container
* is generally modified, whereas the provided container (x) is unaffected. May generate a new
* container. The resulting container may not track its cardinality correctly. The resulting
* container may not track its cardinality correctly. This can be fixed as follows:
* if(c.getCardinality()<0) ((MappeableBitmapContainer)c).computeCardinality();
*
* @param x other container
* @return aggregated container
*/
public MappeableContainer lazyIOR(MappeableContainer x) {
if (this instanceof MappeableArrayContainer) {
if (x instanceof MappeableArrayContainer) {
return ((MappeableArrayContainer) this).lazyor((MappeableArrayContainer) x);
} else if (x instanceof MappeableBitmapContainer) {
return ((MappeableBitmapContainer) x).lazyor((MappeableArrayContainer) this);
}
return ((MappeableRunContainer) x).lazyor((MappeableArrayContainer) this);
} else if (this instanceof MappeableRunContainer) {
if (x instanceof MappeableArrayContainer) {
return ((MappeableRunContainer) this).ilazyor((MappeableArrayContainer) x);
} else if (x instanceof MappeableBitmapContainer) {
return ((MappeableBitmapContainer) x).lazyor((MappeableRunContainer) this);
}
return ior((MappeableRunContainer) x);
} else {
if (x instanceof MappeableArrayContainer) {
return ((MappeableBitmapContainer) this).ilazyor((MappeableArrayContainer) x);
} else if (x instanceof MappeableBitmapContainer) {
return ((MappeableBitmapContainer) this).ilazyor((MappeableBitmapContainer) x);
}
return ((MappeableBitmapContainer) this).ilazyor((MappeableRunContainer) x);
}
}
/**
* Computes the bitwise OR of this container with another (union). This container as well as the
* provided container are left unaffected. The resulting container may not track its cardinality
* correctly. This can be fixed as follows: if(c.getCardinality()<0)
* ((MappeableBitmapContainer)c).computeCardinality();
*
* @param x other container
* @return aggregated container
*/
public MappeableContainer lazyOR(MappeableContainer x) {
if (this instanceof MappeableArrayContainer) {
if (x instanceof MappeableArrayContainer) {
return ((MappeableArrayContainer) this).lazyor((MappeableArrayContainer) x);
} else if (x instanceof MappeableBitmapContainer) {
return ((MappeableBitmapContainer) x).lazyor((MappeableArrayContainer) this);
}
return ((MappeableRunContainer) x).lazyor((MappeableArrayContainer) this);
} else if (this instanceof MappeableRunContainer) {
if (x instanceof MappeableArrayContainer) {
return ((MappeableRunContainer) this).lazyor((MappeableArrayContainer) x);
} else if (x instanceof MappeableBitmapContainer) {
return ((MappeableBitmapContainer) x).lazyor((MappeableRunContainer) this);
}
return or((MappeableRunContainer) x);
} else {
if (x instanceof MappeableArrayContainer) {
return ((MappeableBitmapContainer) this).lazyor((MappeableArrayContainer) x);
} else if (x instanceof MappeableBitmapContainer) {
return ((MappeableBitmapContainer) this).lazyor((MappeableBitmapContainer) x);
}
return ((MappeableBitmapContainer) this).lazyor((MappeableRunContainer) x);
}
}
/**
* Create a new MappeableContainer containing at most maxcardinality integers.
*
* @param maxcardinality maximal cardinality
* @return a new bitmap with cardinality no more than maxcardinality
*/
public abstract MappeableContainer limit(int maxcardinality);
/**
* Computes the bitwise NOT of this container (complement). Only those bits within the range are
* affected. The current container is left unaffected.
*
* @param rangeStart beginning of range (inclusive); 0 is beginning of this container.
* @param rangeEnd ending of range (exclusive)
* @return (partially) completmented container
*/
public abstract MappeableContainer not(int rangeStart, int rangeEnd);
abstract int numberOfRuns();
/**
* Computes the bitwise OR of this container with another (union). This container as well as the
* provided container are left unaffected.
*
* @param x other container
* @return aggregated container
*/
public abstract MappeableContainer or(MappeableArrayContainer x);
/**
* Computes the bitwise OR of this container with another (union). This container as well as the
* provided container are left unaffected.
*
* @param x other container
* @return aggregated container
*/
public abstract MappeableContainer or(MappeableBitmapContainer x);
protected MappeableContainer or(MappeableContainer x) {
if (x instanceof MappeableArrayContainer) {
return or((MappeableArrayContainer) x);
} else if (x instanceof MappeableRunContainer) {
return or((MappeableRunContainer) x);
}
return or((MappeableBitmapContainer) x);
}
/**
* Computes the bitwise OR of this container with another (union). This container as well as the
* provided container are left unaffected.
*
* @param x other container
* @return aggregated container
*/
public abstract MappeableContainer or(MappeableRunContainer x);
/**
* Rank returns the number of integers that are smaller or equal to x (Rank(infinity) would be
* GetCardinality()).
*
* @param lowbits upper limit
*
* @return the rank
*/
public abstract int rank(short lowbits);
/**
* Return a new container with all shorts in [begin,end) remove using an unsigned interpretation.
*
* @param begin start of range (inclusive)
* @param end end of range (exclusive)
* @return the new container
*/
public abstract MappeableContainer remove(int begin, int end);
/**
* Remove the short from this container. May create a new container.
*
* @param x to be removed
* @return New container
*/
public abstract MappeableContainer remove(short x);
/**
* The output of a lazyOR or lazyIOR might be an invalid container, this should be called on it.
*
* @return a new valid container
*/
public abstract MappeableContainer repairAfterLazy();
/**
* Convert to MappeableRunContainers, when the result is smaller. Overridden by
* MappeableRunContainer to possibly switch from MappeableRunContainer to a smaller alternative.
*
* @return the new container
*/
public abstract MappeableContainer runOptimize();
/**
* Return the jth value
*
* @param j index of the value
*
* @return the value
*/
public abstract short select(int j);
/**
* Report the number of bytes required to serialize this container.
*
* @return the size in bytes
*/
public abstract int serializedSizeInBytes();
/**
* Convert to a non-mappeable container.
*
* @return the non-mappeable container
*/
public abstract Container toContainer();
/**
* If possible, recover wasted memory.
*/
public abstract void trim();
/**
* Write just the underlying array.
*
* @param out output stream
* @throws IOException in case of failure
*/
protected abstract void writeArray(DataOutput out) throws IOException;
/**
* Computes the bitwise XOR of this container with another (symmetric difference). This container
* as well as the provided container are left unaffected.
*
* @param x other container
* @return aggregated container
*/
public abstract MappeableContainer xor(MappeableArrayContainer x);
/**
* Computes the bitwise XOR of this container with another (symmetric difference). This container
* as well as the provided container are left unaffected.
*
* @param x other container
* @return aggregated container
*/
public abstract MappeableContainer xor(MappeableBitmapContainer x);
protected MappeableContainer xor(MappeableContainer x) {
if (x instanceof MappeableArrayContainer) {
return xor((MappeableArrayContainer) x);
} else if (x instanceof MappeableRunContainer) {
return xor((MappeableRunContainer) x);
}
return xor((MappeableBitmapContainer) x);
}
/**
* Computes the bitwise XOR of this container with another (symmetric difference). This container
* as well as the provided container are left unaffected.
*
* @param x other parameter
* @return aggregated container
*/
public abstract MappeableContainer xor(MappeableRunContainer x);
/**
* Convert the current container to a BitmapContainer, if a conversion is needed.
* If the container is already a bitmap, the container is returned unchanged.
* @return a bitmap container
*/
public abstract MappeableBitmapContainer toBitmapContainer() ;
/**
* Get the first integer held in the container
* @return the first integer in the container
* @throws NoSuchElementException if empty
*/
public abstract int first();
/**
* Get the last integer held in the container
* @return the last integer in the container
* @throws NoSuchElementException if empty
*/
public abstract int last();
/**
* Throw if the container is empty
* @param condition a boolean expression
* @throws NoSuchElementException if empty
*/
protected void assertNonEmpty(boolean condition) {
if(condition) {
throw new NoSuchElementException("Empty " + getContainerName());
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy