jaulib v1.3.0
Jau Support Library (C++, Java, ..)
Int32Bitfield.java
Go to the documentation of this file.
1/**
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2020 Gothel Software e.K.
4 * Copyright (c) 2015 Gothel Software e.K.
5 * Copyright (c) 2015 JogAmp Community.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining
8 * a copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sublicense, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be
16 * included in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26package jau.util;
27
28import org.jau.util.BitMath;
29import org.jau.util.Bitfield;
30
31/**
32 * Simple bitfield interface for efficient storage access in O(1).
33 * <p>
34 * Implementation uses one 32bit integer field for storage.
35 * </p>
36 */
37public class Int32Bitfield implements Bitfield {
38 /** Unit size in bits, here 32 bits for one int unit. */
39 private static final int UNIT_SIZE = 32;
40 private int storage;
41
42 public Int32Bitfield() {
43 this.storage = 0;
44 }
45
46 @Override
47 public int size() {
48 return UNIT_SIZE;
49 }
50
51 @Override
52 public final void clearField(final boolean bit) {
53 if( bit ) {
55 } else {
56 storage = 0;
57 }
58 }
59
60 private static final void check(final int size, final int bitnum) throws IndexOutOfBoundsException {
61 if( 0 > bitnum || bitnum >= size ) {
62 throw new IndexOutOfBoundsException("Bitnum should be within [0.."+(size-1)+"], but is "+bitnum);
63 }
64 }
65
66 @Override
67 public final int get32(final int lowBitnum, final int length) throws IndexOutOfBoundsException {
68 if( 0 > length || length > 32 ) {
69 throw new IndexOutOfBoundsException("length should be within [0..32], but is "+length);
70 }
71 check(UNIT_SIZE-length+1, lowBitnum);
72 final int left = 32 - lowBitnum; // remaining bits of first chunk
73 if( 32 == left ) {
74 // fast path
75 final int m = BitMath.getBitMask(length);// mask of chunk
76 return m & storage;
77 } else {
78 // slow path
79 final int l = Math.min(length, left); // length of first chunk < 32
80 final int m = ( 1 << l ) - 1; // mask of first chunk
81 return m & ( storage >>> lowBitnum );
82 }
83 }
84 @Override
85 public final void put32(final int lowBitnum, final int length, final int data) throws IndexOutOfBoundsException {
86 if( 0 > length || length > 32 ) {
87 throw new IndexOutOfBoundsException("length should be within [0..32], but is "+length);
88 }
89 check(UNIT_SIZE-length+1, lowBitnum);
90 final int left = 32 - lowBitnum; // remaining bits of first chunk storage
91 if( 32 == left ) {
92 // fast path
93 final int m = BitMath.getBitMask(length);// mask of chunk
94 storage = ( ( ~m ) & storage ) // keep non-written storage bits
95 | ( m & data ); // overwrite storage w/ used data bits
96 } else {
97 // slow path
98 final int l = Math.min(length, left); // length of first chunk < 32
99 final int m = ( 1 << l ) - 1; // mask of first chunk
100 storage = ( ( ~( m << lowBitnum ) ) & storage ) // keep non-written storage bits
101 | ( ( m & data ) << lowBitnum ); // overwrite storage w/ used data bits
102 }
103 }
104 @Override
105 public final int copy32(final int srcBitnum, final int dstBitnum, final int length) throws IndexOutOfBoundsException {
106 final int data = get32(srcBitnum, length);
107 put32(dstBitnum, length, data);
108 return data;
109 }
110
111 @Override
112 public final boolean get(final int bitnum) throws IndexOutOfBoundsException {
113 check(UNIT_SIZE, bitnum);
114 return 0 != ( storage & ( 1 << bitnum ) ) ;
115 }
116 @Override
117 public final boolean put(final int bitnum, final boolean bit) throws IndexOutOfBoundsException {
118 check(UNIT_SIZE, bitnum);
119 final int m = 1 << bitnum;
120 final boolean prev = 0 != ( storage & m ) ;
121 if( prev != bit ) {
122 if( bit ) {
123 storage |= m;
124 } else {
125 storage &= ~m;
126 }
127 }
128 return prev;
129 }
130 @Override
131 public final void set(final int bitnum) throws IndexOutOfBoundsException {
132 check(UNIT_SIZE, bitnum);
133 final int m = 1 << bitnum;
134 storage |= m;
135 }
136 @Override
137 public final void clear (final int bitnum) throws IndexOutOfBoundsException {
138 check(UNIT_SIZE, bitnum);
139 final int m = 1 << bitnum;
140 storage &= ~m;
141 }
142 @Override
143 public final boolean copy(final int srcBitnum, final int dstBitnum) throws IndexOutOfBoundsException {
144 check(UNIT_SIZE, srcBitnum);
145 check(UNIT_SIZE, dstBitnum);
146 // get
147 final boolean bit = 0 != ( storage & ( 1 << srcBitnum ) ) ;
148 // put
149 final int m = 1 << dstBitnum;
150 if( bit ) {
151 storage |= m;
152 } else {
153 storage &= ~m;
154 }
155 return bit;
156 }
157
158 @Override
159 public int bitCount() {
160 return BitMath.bitCount(storage);
161 }
162}
Simple bitfield interface for efficient storage access in O(1).
int bitCount()
Returns the number of one bits within this bitfield.
final void put32(final int lowBitnum, final int length, final int data)
Puts length bits of given data into this storage, starting w/ the lowest bit to the storage position ...
final int copy32(final int srcBitnum, final int dstBitnum, final int length)
Copies length bits at position srcLowBitnum to position dstLowBitnum and returning the bits.
final boolean put(final int bitnum, final boolean bit)
Set or clear the bit at position bitnum according to bit and return the previous value.
int size()
Returns the storage size in bit units, e.g.
final int get32(final int lowBitnum, final int length)
Returns length bits from this storage, starting with the lowest bit from the storage position lowBitn...
final void clearField(final boolean bit)
Set all bits of this bitfield to the given value bit.
final void clear(final int bitnum)
Clear the bit at position bitnum according to bit.
final boolean copy(final int srcBitnum, final int dstBitnum)
Copies the bit at position srcBitnum to position dstBitnum and returning true if the bit is set,...
static final int bitCount(int n)
Returns the number of set bits within given 32bit integer in O(1) using a HAKEM 169 Bit Count inspire...
Definition: BitMath.java:68
static int getBitMask(final int n)
Returns the 32 bit mask of n-bits, i.e.
Definition: BitMath.java:45
static final int UNSIGNED_INT_MAX_VALUE
Maximum 32 bit Unsigned Integer Value: 0xffffffff == {@value}.
Definition: BitMath.java:28
Simple bitfield interface for efficient bit storage access in O(1).
Definition: Bitfield.java:34