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

org.gridkit.jvmtool.util.PagedBitMap Maven / Gradle / Ivy

There is a newer version: 0.16
Show newest version
package org.gridkit.jvmtool.util;
/**
 * Copyright 2014 Alexey Ragozin
 *
 * 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.
 */


import java.util.Iterator;
import java.util.NoSuchElementException;

/**
 * Simple bit map using paged long array for storage.
 * Untouched pages are not allocated, so it is reasonably efficient
 * for bitmaps with large gaps.
 *
 * @author Alexey Ragozin ([email protected])
 */
public class PagedBitMap {

    private LongArray array;
    
    public PagedBitMap() {
        this(false);
    }

    public PagedBitMap(boolean sparse) {
        if (sparse) {
            array = new SparsePagedLongArray();
        }
        else {
            array = new PagedLongArray();
        }
    }

    public boolean get(long index) {
        long lindex = index / 64;
        long bit = 1l << (index % 64);
        return (0 != (bit & array.get(lindex))); // Long.toBinaryString(array.get(lindex))
    }

    public long seekOne(long start) {
        long n = start;
        while(true) {
            long lindex = n / 64;
            long bit = 1l << (n % 64);

            long word = array.get(lindex);
            if (word == 0) {
                long nn = array.seekNext(lindex);
                if (nn < 0) {
                    return -1;
                }
                n = 64 * nn;
                continue;
            }
            while(bit != 0) {
                if (0 != (bit & word)) {
                    return n;
                }
                ++n;
                bit <<= 1;
            }
        }
    }

    public void set(long index, boolean value) {
        long lindex = index / 64;
        long bit = 1l << (index % 64);
        if (value) {
            array.set(lindex, bit | array.get(lindex));
        }
        else {
            array.set(lindex, (~bit) & array.get(lindex));
        }
    }

    public boolean getAndSet(long index, boolean value) {
        long lindex = index / 64;
        long bit = 1l << (index % 64);
        long ov = array.get(lindex);
        if (value) {
        array.set(lindex, bit | ov);
        }
        else {
            array.set(lindex, (~bit) & ov);
        }
        return 0 != (bit & ov);
    }

    /**
     * Bitwise 
* this = this | that */ public void add(PagedBitMap that) { LongArray ta = that.array; long n = 0; while(true) { n = ta.seekNext(n); if (n < 0) { break; } long v = array.get(n) | ta.get(n); array.set(n, v); ++n; } } /** * Bitwise
* overflow = this & that *
* this = this | that */ public void addWithOverflow(PagedBitMap that, PagedBitMap overflow) { LongArray ta = that.array; LongArray of = overflow.array; long n = 0; while(true) { n = ta.seekNext(n); if (n < 0) { break; } long o = array.get(n) & ta.get(n); long v = array.get(n) | ta.get(n); array.set(n, v); if (o != 0) { o |= of.get(n); of.set(n, o); } ++n; } } /** * Bitwise
* this = this & (~that) */ public void sub(PagedBitMap that) { LongArray ta = that.array; long n = 0; while(true) { n = ta.seekNext(n); if (n < 0) { break; } long v = array.get(n) & ~ta.get(n); array.set(n, v); ++n; } } /** * Bitwise
* this = this & that */ public void mult(PagedBitMap that) { LongArray ta = that.array; long n = 0; while(true) { n = ta.seekNext(n); if (n < 0) { break; } long v = array.get(n) & ta.get(n); array.set(n, v); ++n; } } public Iterable ones() { return new Iterable() { @Override public Iterator iterator() { return new SeekerIterator(PagedBitMap.this); } }; } @SuppressWarnings("unused") public long countOnes() { long n = 0; for(Long l: ones()) { ++n; } return n; } protected static class SeekerIterator implements Iterator { private PagedBitMap bitmap; private long next; public SeekerIterator(PagedBitMap bitmap) { this.bitmap = bitmap; this.next = bitmap.seekOne(0); } @Override public boolean hasNext() { return next != -1; } @Override public Long next() { if (next == -1) { throw new NoSuchElementException(); } long n = next; next = bitmap.seekOne(next + 1); return n; } @Override public void remove() { throw new UnsupportedOperationException(); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy