帆软使用的第三方框架。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

808 lines
27 KiB

/*
* (c) the authors Licensed under the Apache License, Version 2.0.
*/
package com.fr.third.bitmap.roaringbitmap;
import com.fr.third.bitmap.roaringbitmap.buffer.MappeableContainer;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.Externalizable;
import java.io.IOException;
/**
* Base container class.
*/
public abstract class Container implements Iterable<Short>, Cloneable, Externalizable {
/**
* Name of the various possible containers
*/
public static String ContainerNames[] = {"bitmap", "array", "run"};
/**
* 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 Container rangeOfOnes(final int start, final int last) {
final int sizeAsArrayContainer = ArrayContainer.serializedSizeInBytes(last - start);
final int sizeAsRunContainer = RunContainer.serializedSizeInBytes(1);
Container answer =
sizeAsRunContainer < sizeAsArrayContainer ? new RunContainer() : new ArrayContainer();
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 Container 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 Container 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 Container and(ArrayContainer 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 Container and(BitmapContainer 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 Container and(Container x) {
if (x instanceof ArrayContainer) {
return and((ArrayContainer) x);
} else if (x instanceof BitmapContainer) {
return and((BitmapContainer) x);
}
return and((RunContainer) 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 Container and(RunContainer x);
protected abstract int andCardinality(ArrayContainer x);
protected abstract int andCardinality(BitmapContainer x);
protected abstract int andCardinality(RunContainer 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 int andCardinality(Container x) {
if (this.getCardinality() == 0) {
return 0;
} else if (x.getCardinality() == 0) {
return 0;
} else {
if (x instanceof ArrayContainer) {
return andCardinality((ArrayContainer) x);
} else if (x instanceof BitmapContainer) {
return andCardinality((BitmapContainer) x);
}
return andCardinality((RunContainer) 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 Container andNot(ArrayContainer 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 Container andNot(BitmapContainer 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 Container andNot(Container x) {
if (x instanceof ArrayContainer) {
return andNot((ArrayContainer) x);
} else if (x instanceof BitmapContainer) {
return andNot((BitmapContainer) x);
}
return andNot((RunContainer) 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 Container andNot(RunContainer x);
/**
* Empties the container
*/
public abstract void clear();
@Override
public abstract Container 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);
/**
* Deserialize (recover) the container.
*
* @param in the DataInput stream
* @throws IOException Signals that an I/O exception has occurred.
*/
public abstract void deserialize(DataInput in) throws IOException;
/**
* Fill the least significant 16 bits of the integer array, starting at index i, 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 Container 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 BitmapContainer) {
return ContainerNames[0];
} else if (this instanceof ArrayContainer) {
return ContainerNames[1];
} else {
return ContainerNames[2];
}
}
/**
* 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);
/**
* 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();
/**
* 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 Container 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 Container iand(ArrayContainer 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 Container iand(BitmapContainer 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 Container iand(Container x) {
if (x instanceof ArrayContainer) {
return iand((ArrayContainer) x);
} else if (x instanceof BitmapContainer) {
return iand((BitmapContainer) x);
}
return iand((RunContainer) 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 Container iand(RunContainer 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 Container iandNot(ArrayContainer 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 Container iandNot(BitmapContainer 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 Container iandNot(Container x) {
if (x instanceof ArrayContainer) {
return iandNot((ArrayContainer) x);
} else if (x instanceof BitmapContainer) {
return iandNot((BitmapContainer) x);
}
return iandNot((RunContainer) 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 Container iandNot(RunContainer 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) complemented container
*/
public abstract Container 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(ArrayContainer x);
/**
* Returns true if the current container intersects the other container.
*
* @param x other container
* @return whether they intersect
*/
public abstract boolean intersects(BitmapContainer x);
/**
* Returns true if the current container intersects the other container.
*
* @param x other container
* @return whether they intersect
*/
public boolean intersects(Container x) {
if (x instanceof ArrayContainer) {
return intersects((ArrayContainer) x);
} else if (x instanceof BitmapContainer) {
return intersects((BitmapContainer) x);
}
return intersects((RunContainer) x);
}
/**
* Returns true if the current container intersects the other container.
*
* @param x other container
* @return whether they intersect
*/
public abstract boolean intersects(RunContainer 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 Container ior(ArrayContainer 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 Container ior(BitmapContainer 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 Container ior(Container x) {
if (x instanceof ArrayContainer) {
return ior((ArrayContainer) x);
} else if (x instanceof BitmapContainer) {
return ior((BitmapContainer) x);
}
return ior((RunContainer) 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 Container ior(RunContainer 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 Container iremove(int begin, int end);
/**
* 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 Container ixor(ArrayContainer 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 Container ixor(BitmapContainer 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 Container ixor(Container x) {
if (x instanceof ArrayContainer) {
return ixor((ArrayContainer) x);
} else if (x instanceof BitmapContainer) {
return ixor((BitmapContainer) x);
}
return ixor((RunContainer) 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 Container ixor(RunContainer 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()&lt;0) ((BitmapContainer)c).computeCardinality();
*
* @param x other container
* @return aggregated container
*/
public Container lazyIOR(Container x) {
if (this instanceof ArrayContainer) {
if (x instanceof ArrayContainer) {
return ((ArrayContainer) this).lazyor((ArrayContainer) x);
} else if (x instanceof BitmapContainer) {
return ior((BitmapContainer) x);
}
return ((RunContainer) x).lazyor((ArrayContainer) this);
} else if (this instanceof RunContainer) {
if (x instanceof ArrayContainer) {
return ((RunContainer) this).ilazyor((ArrayContainer) x);
} else if (x instanceof BitmapContainer) {
return ior((BitmapContainer) x);
}
return ior((RunContainer) x);
} else {
if (x instanceof ArrayContainer) {
return ((BitmapContainer) this).ilazyor((ArrayContainer) x);
} else if (x instanceof BitmapContainer) {
return ((BitmapContainer) this).ilazyor((BitmapContainer) x);
}
return ((BitmapContainer) this).ilazyor((RunContainer) 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()&lt;0)
* ((BitmapContainer)c).computeCardinality();
*
* @param x other container
* @return aggregated container
*/
public Container lazyOR(Container x) {
if (this instanceof ArrayContainer) {
if (x instanceof ArrayContainer) {
return ((ArrayContainer) this).lazyor((ArrayContainer) x);
} else if (x instanceof BitmapContainer) {
return ((BitmapContainer) x).lazyor((ArrayContainer) this);
}
return ((RunContainer) x).lazyor((ArrayContainer) this);
} else if (this instanceof RunContainer) {
if (x instanceof ArrayContainer) {
return ((RunContainer) this).lazyor((ArrayContainer) x);
} else if (x instanceof BitmapContainer) {
return ((BitmapContainer) x).lazyor((RunContainer) this);
}
return or((RunContainer) x);
} else {
if (x instanceof ArrayContainer) {
return ((BitmapContainer) this).lazyor((ArrayContainer) x);
} else if (x instanceof BitmapContainer) {
return ((BitmapContainer) this).lazyor((BitmapContainer) x);
}
return ((BitmapContainer) this).lazyor((RunContainer) x);
}
}
/**
* Create a new Container containing at most maxcardinality integers.
*
* @param maxcardinality maximal cardinality
* @return a new bitmap with cardinality no more than maxcardinality
*/
public abstract Container 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) complemented container
*/
public abstract Container not(int rangeStart, int rangeEnd);
abstract int numberOfRuns(); // exact
/**
* 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 Container or(ArrayContainer 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 Container or(BitmapContainer 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 Container or(Container x) {
if (x instanceof ArrayContainer) {
return or((ArrayContainer) x);
} else if (x instanceof BitmapContainer) {
return or((BitmapContainer) x);
}
return or((RunContainer) 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 Container or(RunContainer 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 Container 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 Container 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 Container repairAfterLazy();
/**
* Convert to RunContainers, when the result is smaller. Overridden by RunContainer to possibility
* switch from RunContainer to a smaller alternative. Overridden by BitmapContainer with a more
* efficient approach.
*
* @return the new container
*/
public abstract Container runOptimize();
/**
* Return the jth value
*
* @param j index of the value
* @return the value
*/
public abstract short select(int j);
/**
* Serialize the container.
*
* @param out the DataOutput stream
* @throws IOException Signals that an I/O exception has occurred.
*/
public abstract void serialize(DataOutput out) throws IOException;
/**
* Report the number of bytes required to serialize this container.
*
* @return the size in bytes
*/
public abstract int serializedSizeInBytes();
/**
* Convert to a mappeable container.
*
* @return the mappeable container
*/
public abstract MappeableContainer toMappeableContainer();
/**
* 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 Container xor(ArrayContainer 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 Container xor(BitmapContainer x);
/**
* Computes the bitwise OR 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 Container xor(Container x) {
if (x instanceof ArrayContainer) {
return xor((ArrayContainer) x);
} else if (x instanceof BitmapContainer) {
return xor((BitmapContainer) x);
}
return xor((RunContainer) 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 Container xor(RunContainer 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 BitmapContainer toBitmapContainer();
}