/* Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. Contact: SYSTAP, LLC DBA Blazegraph 2501 Calvert ST NW #106 Washington, DC 20008 licenses@blazegraph.com This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * Created on Aug 6, 2009 */ package com.bigdata.util; import it.unimi.dsi.bits.AbstractBitVector; import java.nio.ByteBuffer; import cern.colt.bitvector.BitVector; /** * Wraps a {@link ByteBuffer} as a read-only {@link BitVector}. * * @author <a href="mailto:thompsonbry@users.sourceforge.net">Bryan Thompson</a> * @version $Id$ */ public class ByteBufferBitVector extends AbstractBitVector { /** * The {@link ByteBuffer} containing the backing data. */ final private ByteBuffer b; /** * The #of bits in the vector. */ private final long len; /** * The bit offset into the {@link ByteBuffer} of the first bit in the * vector. */ private final long off; final public long length() { return len; } /** * Ctor assumes that all bits in the buffer are used. * * @param b * The buffer. */ public ByteBufferBitVector(final ByteBuffer b) { this(b, 0/* offset */, b == null ? 0 : b.capacity() * 8/* len */); } /** * * @param b * The buffer. * @param off * The offset from the start of the buffer for the view. * @param len * The #of bits which will be included in the view. */ public ByteBufferBitVector(final ByteBuffer b, final long off, final long len) { if (b == null) throw new IllegalArgumentException(); if (len < 0) throw new IllegalArgumentException(); if (len < 0) throw new IllegalArgumentException(); if (off + len > b.capacity() * 8L) throw new IllegalArgumentException(); this.b = b; this.len = len; this.off = off; } /** * Return the index of the byte in which the bit with the given index is * encoded. * * @param bitIndex * The bit index. * * @return The byte index. */ final protected int byteIndexForBit(final long bitIndex) { return ((int) ((bitIndex + off) / 8)); } /** * Return the offset within the byte in which the bit is coded of the bit * (this is just the remainder <code>bitIndex % 8</code>). * * @param bitIndex * The bit index into the byte[]. * * @return The offset of the bit in the appropriate byte. */ final protected int withinByteIndexForBit(final long bitIndex) { return (int) ((bitIndex + off) % 8); } /** * Extract and return a bit coded flag. * * @param offset * The offset in the buffer of the start of the byte[] sequence * in which the bit coded flags are stored. * @param index * The index of the bit. * * @return The value of the bit. */ public boolean getBoolean(final long index) { if (index < 0 || index >= len) throw new IndexOutOfBoundsException(); return (b.get(byteIndexForBit(index)) & (1 << withinByteIndexForBit(index))) != 0; } // // @todo override for mutation. // public boolean set(final long index, final boolean value) { // // throw new UnsupportedOperationException(); // // } }