net.algart.arrays.UpdatableBitArray Maven / Gradle / Ivy
Show all versions of algart Show documentation
/*
* The MIT License (MIT)
*
* Copyright (c) 2007-2024 Daniel Alievsky, AlgART Laboratory (http://algart.net)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package net.algart.arrays;
/*Repeat(INCLUDE_FROM_FILE, UpdatableFloatArray.java, all)
PFloating ==> PFixed ;;
Float(Array|Copies) ==> Bit$1 ;;
setFloat ==> setBit ;;
Float(?!ing) ==> Boolean ;;
float ==> boolean
!! Auto-generated: NOT EDIT !! */
/**
* AlgART array of boolean
values, read/write access, no resizing.
*
* @author Daniel Alievsky
*/
public interface UpdatableBitArray extends BitArray, UpdatablePFixedArray {
/**
* Sets the element #index
to the specified value
.
*
* @param index index of the element to replace.
* @param value element to be stored at the specified position.
* @throws IndexOutOfBoundsException if index
is out of range 0..length()-1
.
*/
void setBit(long index, boolean value);
/**
* Fills all the elements of this array by the specified value. Equivalent to
* {@link #fill(long, long, boolean) fill}(0, thisArray.length(), value)
.
*
* @param value the value to be stored in all elements of the array.
* @return a reference to this array.
* @see #fill(long, long, boolean)
* @see Arrays#zeroFill(UpdatableArray)
*/
UpdatableBitArray fill(boolean value);
/**
* Fills count
elements of this array, starting from position
index,
* by the specified value. Equivalent to the following loop:
* for (long k = 0; k < count; k++) {
* {@link #setBit(long, boolean) setBit}(position + k, value);
* }
* but works much faster and checks indexes
* (and throws possible IndexOutOfBoundsException
) in the very beginning.
*
* @param position start index (inclusive) to be filled.
* @param count number of filled elements.
* @param value the value to be stored in the elements of the array.
* @return a reference to this array.
* @throws IndexOutOfBoundsException for illegal position
and count
* (position < 0 || count < 0 || position + count > length()
).
* @see #fill(boolean)
* @see Arrays#zeroFill(UpdatableArray)
*/
UpdatableBitArray fill(long position, long count, boolean value);
UpdatableBitArray subArray(long fromIndex, long toIndex);
UpdatableBitArray subArr(long position, long count);
UpdatableBitArray asUnresizable();
default Matrix matrix(long... dim) {
return Matrices.matrix(this, dim);
}
/*Repeat.IncludeEnd*/
/**
* Equivalent to {@link #setBit(long, boolean) setBit}(index, true)
.
*
* @param index index of the element to replace.
* @throws IndexOutOfBoundsException if index out of range 0..length()-1
.
*/
void setBit(long index);
/**
* Equivalent to {@link #setBit(long, boolean) setBit}(index, false)
.
*
* @param index index of the element to replace.
* @throws IndexOutOfBoundsException if index out of range 0..length()-1
.
*/
void clearBit(long index);
/**
* Sets the element #index
to the specified value
in a non-thread-safe manner:
* without a strict requirement for internal synchronization.
* This means that when calling this method from different threads for the same instance,
* it can cause modification (corruption) of some bits "around" the bit #index
,
* namely the bits inside the same 64-bit block with indexes 64k...64k+63
,
* where k=index/64
.
*
* In contrast, {@link #setBit(long, boolean)} method guarantees that setting a bit at index
* i will never affect to any bit with other index j≠i.
* This allows you to split bit array into several blocks and process each block in a separate thread,
* as it is possible for a regular Java array.
*
* Note that this method is usually much faster than {@link #setBit(long, boolean)}.
* If you are not going to work with this array from different threads, you should prefer this method.
* Also you may freely use this method if you are synchronizing all access to this array via some
* form of external synchronization: in this case, no additional internal synchronization is needed.
* (But remember: such external synchronization must be used on any access to this array,
* not only when calling this method!)
*
* Note that some classes may correctly implement this interface without any synchronization
* or, vise versa, always use synchronization. In such cases this method may be equivalent
* to {@link #setBit(long, boolean)}.
*
* @param index index of the element to replace.
* @param value element to be stored at the specified position.
* @throws IndexOutOfBoundsException if index
is out of range 0..length()-1
.
*/
void setBitNoSync(long index, boolean value);
/**
* Equivalent to {@link #setBitNoSync(long, boolean) setBitNoSync}(index, true)
.
*
* @param index index of the element to replace.
* @throws IndexOutOfBoundsException if index out of range 0..length()-1
.
*/
void setBitNoSync(long index);
/**
* Equivalent to {@link #setBitNoSync(long, boolean) setBitNoSync}(index, false)
.
*
* @param index index of the element to replace.
* @throws IndexOutOfBoundsException if index out of range 0..length()-1
.
*/
void clearBitNoSync(long index);
/**
* Sets the sequence of count
bits (maximum 64 bits), starting from the bit #arrayPos
.
* This is the reverse operation of {@link #getBits64(long, int)}.
*
* This function is equivalent to the following loop (for correct count
in the range 0..64):
*
*
* for (int k = 0; k < count; k++) {
* final long bit = (bits >>> k) & 1L;
* {@link #setBit(long, boolean) setBit}(arrayPos + k, bit != 0);
* }
*
* But this method works significantly faster in basic implementations of this interface,
* if count
is greater than 1.
*
* @param arrayPos position of the first bit written in the destination array.
* @param bits sequence of new bits to be copied into the destination array.
* @param count the number of bits to be written (must be in range 0..64).
* @throws IndexOutOfBoundsException if copying would cause access of data outside this array.
* @throws IllegalArgumentException if count < 0
or count > 64
.
*/
default void setBits64(long arrayPos, long bits, int count) {
if (arrayPos < 0) {
throw new IndexOutOfBoundsException("Negative arrayPos argument: " + arrayPos);
}
if (count < 0) {
throw new IllegalArgumentException("Negative count argument: " + count);
}
if (count > 64) {
throw new IllegalArgumentException("Too large count argument: " + count +
"; we cannot set > 64 bits in setBits64 method");
}
for (int k = count - 1; k >= 0; k--) {
// - inverse loop order allows to guarantee that IndexOutOfBoundsException
// will occur before modifying anything
final long bit = (bits >>> k) & 1L;
setBit(arrayPos + k, bit != 0);
}
}
/**
* Sets the sequence of count
bits (maximum 64 bits), starting from the bit #arrayPos
* in a non-thread-safe manner:
* without a strict requirement for internal synchronization.
* This means that when calling this method from different threads for the same instance,
* it can cause modification (corruption) of some bits "around" the bit #index
,
* namely the bits inside the same 64-bit block with indexes 64k...64k+63
,
* where k=index/64
.
*
* Note that this method is usually much faster than {@link #setBits64(long, long, int)}.
* If you are not going to work with this array from different threads, you should prefer this method.
* Also you may freely use this method if you are synchronizing all access to this array via some
* form of external synchronization: in this case, no additional internal synchronization is needed.
* (But remember: such external synchronization must be used on any access to this array,
* not only when calling this method!)
*
* Note that some classes may correctly implement this interface without any synchronization
* or, vise versa, always use synchronization. In such cases this method may be equivalent
* to {@link #setBits64(long, long, int)}.
*
* @param arrayPos position of the first bit written in the destination array.
* @param bits sequence of new bits to be copied into the destination array.
* @param count the number of bits to be written (must be in range 0..64).
* @throws IndexOutOfBoundsException if copying would cause access of data outside this array.
* @throws IllegalArgumentException if count < 0
or count > 64
.
*/
default void setBits64NoSync(long arrayPos, long bits, int count) {
if (arrayPos < 0) {
throw new IndexOutOfBoundsException("Negative arrayPos argument: " + arrayPos);
}
if (count < 0) {
throw new IllegalArgumentException("Negative count argument: " + count);
}
if (count > 64) {
throw new IllegalArgumentException("Too large count argument: " + count +
"; we cannot set > 64 bits in setBits64NoSync method");
}
for (int k = count - 1; k >= 0; k--) {
// - inverse loop order allows to guarantee that IndexOutOfBoundsException
// will occur before modifying anything
final long bit = (bits >>> k) & 1L;
setBitNoSync(arrayPos + k, bit != 0);
}
}
/**
* Copies count
bits from the specified packed bit array,
* starting from srcArrayOffset
index,
* into this array, starting from arrayPos
index.
*
* This method is equivalent to the following loop:
* for (long k = 0; k < count; k++)
* thisArray.{@link #setBit(long, boolean)
* setBit}(arrayPos + k, {@link PackedBitArrays#getBit(long[], long)
* PackedBitArrays.getBit}(srcArray, srcArrayOffset + k));
*
* but usually works much faster.
*
* Note: if IndexOutOfBoundsException
occurs due to attempt to read data outside the passed
* Java array, this AlgART array can be partially filled.
* In other words, this method can be non-atomic regarding this failure.
* All other possible exceptions are checked in the very beginning of this method
* before any other actions (the standard way for checking exceptions).
*
* @param arrayPos starting position in this AlgART array.
* @param srcArray the source packed bit array.
* @param srcArrayOffset starting position in the source packed bit array.
* @param count the number of bits to be copied.
* @return a reference to this AlgART array.
* @throws NullPointerException if srcArray
argument is {@code null}.
* @throws IndexOutOfBoundsException if copying would cause access of data outside this array or source Java array.
* @throws IllegalArgumentException if count < 0
.
* @see #getData(long, Object, int, int)
* @see #getBits(long, long[], long, long)
* @see PackedBitArrays
*/
UpdatableBitArray setBits(long arrayPos, long[] srcArray, long srcArrayOffset, long count);
}