All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.proximax.core.math.SparseBitmap Maven / Gradle / Ivy

Go to download

The ProximaX Sirius Chain Java SDK is a Java library for interacting with the Sirius Blockchain.

The newest version!
/*
 * Copyright 2018 NEM
 *
 * 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 io.proximax.core.math;

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import com.googlecode.javaewah.EWAHCompressedBitmap;

/**
 * This is a wrapper for the EWAHCompressedBitmap.
 */
public class SparseBitmap implements Iterable {
    private final EWAHCompressedBitmap bitmap;

    // Private constructor
    private SparseBitmap(final EWAHCompressedBitmap bitmap) {
        this.bitmap = bitmap;
    }

    //region factories

    /**
     * Creates a new SparseBitmap that is empty.
     *
     * @return A new SparseBitmap that is empty (no bits set).
     */
    public static SparseBitmap createEmpty() {
        return new SparseBitmap(EWAHCompressedBitmap.bitmapOf());
    }

    /**
     * Creates a new SparseBitmap from data that are already sorted
     * in strictly ascending order (duplicate values are okay).
     *
     * @param bitsToSet The bits to set.
     * @return A new SparseBitmap with the given bits set.
     */
    public static SparseBitmap createFromSortedData(final int... bitsToSet) {
        return new SparseBitmap(EWAHCompressedBitmap.bitmapOf(bitsToSet));
    }

    /**
     * Creates a new SparseBitmap from unsorted data.
     *
     * @param bitsToSet The bits to set.
     * @return A new SparseBitmap with the given bits set.
     */
    public static SparseBitmap createFromUnsortedData(final int... bitsToSet) {
        Arrays.sort(bitsToSet);
        return new SparseBitmap(EWAHCompressedBitmap.bitmapOf(bitsToSet));
    }

    //endregion

    //region get / set

    /**
     * Creates a new SparseBitmap that is the logical or of all the given bitmaps.
     *
     * @param bitmaps Bitmaps to compute the logical or for
     * @return SparseBitmap that has the values set according to the or of the given bitmaps.
     */
    public static SparseBitmap batchOr(final SparseBitmap... bitmaps) {
        if (bitmaps.length < 1) {
            return SparseBitmap.createFromUnsortedData();
        }

        if (bitmaps.length < 2) {
            return bitmaps[0];
        }

        EWAHCompressedBitmap firstMap = bitmaps[0].bitmap;

        for (int index = 1; index < bitmaps.length; ++index) {
            firstMap = firstMap.or(bitmaps[index].bitmap);
        }

        return new SparseBitmap(firstMap);
    }

    /**
     * Gets the value of the bit at the given index.
     *
     * @param bitToGet The index of the bit to get.
     * @return true if the bit is set, false if the bit is not set at the given bitToGet index.
     */
    public boolean get(final int bitToGet) {
        return this.bitmap.get(bitToGet);
    }

    /**
     * For speed, this method sets bits at the given index, without checking that the bits
     * are set in strictly ascending order. If the bits are not in ascending order, performance could be adversely affected.
     *
     * @param bitToSet index of the bit to set
     */
    public void setWithoutAscendingCheck(final int bitToSet) {
        this.bitmap.set(bitToSet);
    }

    //endregion

    //region clear

    /**
     * Set the bit at the given index. Throws an exception if bits are not set in strictly ascending order.
     * For performance reasons, bits must be set in ascending order.
     *
     * @param bitToSet The index of the bit to set.
     */
    public void set(final int bitToSet) {
        // Check that we are setting bits in ascending order (equality with the last value is OK).
        if (this.bitmap.cardinality() > 0 && bitToSet < this.bitmap.toArray()[this.bitmap.cardinality() - 1]) {
            throw new IllegalArgumentException("Must set bits in strictly ascending order.");
        }

        this.bitmap.set(bitToSet);
    }

    //endregion

    //region logical operations

    /**
     * Clears all the bits in this sparse bitmap.
     */
    public void clear() {
        this.bitmap.clear();
    }

    /**
     * Computes the logical or of the context bitmap
     * (this) and the given bitmap.
     *
     * @param rhs Bitmap to compute the logical or with.
     * @return Logical or of this bitmap
     * (context object) and the given bitmap.
     */
    public SparseBitmap or(final SparseBitmap rhs) {
        return new SparseBitmap(this.bitmap.or(rhs.bitmap));
    }

    /**
     * Computes the logical and of the context bitmap
     * (this) and the given bitmap.
     *
     * @param rhs Bitmap to compute the logical and with.
     * @return Logical and of this bitmap
     * (context object) and the given bitmap.
     */
    public SparseBitmap and(final SparseBitmap rhs) {
        return new SparseBitmap(this.bitmap.and(rhs.bitmap));
    }

    /**
     * Computes the logical and not of the context bitmap
     * (this) and the given bitmap.
     *
     * @param rhs Bitmap to compute the logical and not with.
     * @return Logical and not of this bitmap
     * (context object) and the given bitmap.
     */
    public SparseBitmap andNot(final SparseBitmap rhs) {
        return new SparseBitmap(this.bitmap.andNot(rhs.bitmap));
    }

    //endregion

    //region highest bit / cardinality

    /**
     * Gets the highest bit that is set in the bitmap.
     *
     * @return The highest bit.
     */
    public int getHighestBit() {
        return this.bitmap.cardinality() > 0 ? this.bitmap.toArray()[this.bitmap.cardinality() - 1] : 0;
    }

    /**
     * Size of the intersection of this bitmap and
     * the given bitmap.
     *
     * @param rhs given sparse bitmap to compute the size of the intersection of
     * @return size of the intersection of this bitmap and the given bitmap.
     */
    public int andCardinality(final SparseBitmap rhs) {
        return this.bitmap.andCardinality(rhs.bitmap);
    }

    /**
     * The number of bits that are set.
     *
     * @return The number of bits that are set.
     */
    public int cardinality() {
        return this.bitmap.cardinality();
    }

    //endregion

    //region list / iterator

    /**
     * Creates a binary list representation of this sparse bitmap.
     *
     * @return List representation of this sparse bitmap.
     */
    public List toList() {
        return this.bitmap.toList();
    }

    @Override
    public Iterator iterator() {
        return this.bitmap.iterator();
    }

    //endregion

    //region hashCode / equals

    @Override
    public int hashCode() {
        return this.bitmap.hashCode();
    }

    @Override
    public boolean equals(final Object obj) {
        if (!(obj instanceof SparseBitmap)) {
            return false;
        }

        final SparseBitmap rhs = (SparseBitmap) obj;
        return this.bitmap.equals(rhs.bitmap);
    }

    @Override
    public String toString() {
        return this.bitmap.toString();
    }

    //endregion
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy