Class ScyllaBitArray
Managed, fixed-capacity bit array backed by a ulong[] word array for compact
boolean storage and fast bitwise operations.
Implements
Inherited Members
Namespace: Scylla.Core.Structures
Assembly: ScyllaCore.dll
Syntax
public sealed class ScyllaBitArray : IScyllaCollection
Remarks
Bits are packed 64 per ulong word. The actual Capacity is always
rounded up to the next multiple of 64 to keep word-aligned access branchless.
All single-bit operations are O(1); bitwise combinators (And(ScyllaBitArray),
Or(ScyllaBitArray), Xor(ScyllaBitArray), Not()) are O(Capacity/64).
The class maintains an incremental set-bit counter (Count) that is
updated on every single-bit mutation and fully recalculated after bulk word operations
using math.countbits from Unity.Mathematics. PopCount() is
therefore always O(1).
Enumeration over set-bit indices is allocation-free when the concrete type is used
directly; the ScyllaBitArray.Enumerator value type uses the
math.tzcnt (trailing-zero count) trick to skip empty words in a single
hardware instruction on supported platforms.
This class is not thread-safe. For multi-threaded scenarios wrap it with AsSynchronized(object) or use the builder's Synchronized(object) option. For DOTS/Burst jobs use ScyllaBitArrayDOTS instead.
Common use cases include visited-sets in graph/BFS/DFS algorithms, component flag masks, compact slot-availability maps, and any scenario where a large number of boolean values must be stored and tested with minimal memory footprint.
// Direct construction
var bits = new ScyllaBitArray(256);
bits.Set(42);
bool isSet = bits.Get(42); // true
// Allocation-free iteration over set bit indices
foreach (var index in bits)
UnityEngine.Debug.Log(index);
// Using fluent builder
var bits = ScyllaBitArray.CreateBuilder()
.WithCapacity(1024)
.Synchronized()
.Build();
Constructors
ScyllaBitArray(int)
Initializes a new ScyllaBitArray with the specified bit capacity.
All bits are initially set to 0.
Declaration
public ScyllaBitArray(int capacity = 64)
Parameters
| Type | Name | Description |
|---|---|---|
| int | capacity | The desired number of bits. Values less than |
Properties
Capabilities
Feature/capability flags reported by this collection instance.
Declaration
public ScyllaCollectionCapabilities Capabilities { get; }
Property Value
| Type | Description |
|---|---|
| ScyllaCollectionCapabilities |
Remarks
Reports HasCapacity because the array has a fixed capacity, and SupportsContains because membership testing is provided by Get(int).
Capacity
The total number of bits this array can hold.
Declaration
public int Capacity { get; }
Property Value
| Type | Description |
|---|---|
| int | The effective bit capacity, rounded up to a multiple of 64. |
Remarks
Always a multiple of 64 because the capacity is rounded up to the nearest full
ulong word boundary during construction. Requesting a capacity of 65 bits,
for example, allocates 128 bits of actual storage.
Count
The number of bits currently set to 1.
Declaration
public int Count { get; }
Property Value
| Type | Description |
|---|---|
| int | The population count of set bits, in the range |
Remarks
Maintained as an incremental counter on single-bit mutations and recomputed after bulk word operations. Accessing this property is always O(1).
IsEmpty
Returns true when no bits are set (i.e., Count is zero).
Declaration
public bool IsEmpty { get; }
Property Value
| Type | Description |
|---|---|
| bool |
|
SyncRoot
The synchronization root for externally coordinating access to this collection.
Declaration
public object SyncRoot { get; }
Property Value
| Type | Description |
|---|---|
| object |
|
Remarks
Returns null for unsynchronized instances. When thread safety is required,
obtain a ScyllaBitArray.SynchronizedScyllaBitArray wrapper via
AsSynchronized(object), whose SyncRoot
will be non-null.
ThreadSafety
Declares the thread-safety guarantee of this collection instance.
Declaration
public ScyllaCollectionThreadSafety ThreadSafety { get; }
Property Value
| Type | Description |
|---|---|
| ScyllaCollectionThreadSafety |
Remarks
The base ScyllaBitArray is always Unsynchronized. Concurrent access requires external locking or use of the ScyllaBitArray.SynchronizedScyllaBitArray wrapper obtained via AsSynchronized(object).
Methods
And(ScyllaBitArray)
Performs an in-place bitwise AND of this array with other.
Declaration
public void And(ScyllaBitArray other)
Parameters
| Type | Name | Description |
|---|---|---|
| ScyllaBitArray | other | The bit array to AND with. Must not be |
Remarks
Only the overlapping word range (up to min(this.words, other.words)) is
ANDed. Any words in this array that extend beyond other's
capacity are cleared to 0, because ANDing with an implicitly-zero word
always yields zero.
Count is recalculated in full after the operation via Scylla.Core.Structures.ScyllaBitArray.RecalculatePopCount().
Exceptions
| Type | Condition |
|---|---|
| ArgumentNullException | Thrown when |
AsSynchronized(object)
Creates and returns a ScyllaBitArray.SynchronizedScyllaBitArray that wraps this instance and serializes all operations using a monitor lock.
Declaration
public ScyllaBitArray.SynchronizedScyllaBitArray AsSynchronized(object syncRoot = null)
Parameters
| Type | Name | Description |
|---|---|---|
| object | syncRoot | An optional external object to use as the lock. If |
Returns
| Type | Description |
|---|---|
| ScyllaBitArray.SynchronizedScyllaBitArray | A ScyllaBitArray.SynchronizedScyllaBitArray that delegates all calls to this
instance under a |
See Also
Clear()
Sets all bits to 0 and resets Count to zero.
Declaration
public void Clear()
Remarks
Uses Clear(Array, int, int) to zero the backing word array in a single
call, which is typically optimized to a memset by the runtime.
Capacity is unchanged.
CreateBuilder()
Creates and returns a new ScyllaBitArray.Builder instance for configuring and constructing a ScyllaBitArray using a fluent API.
Declaration
public static ScyllaBitArray.Builder CreateBuilder()
Returns
| Type | Description |
|---|---|
| ScyllaBitArray.Builder | A new ScyllaBitArray.Builder with default settings. |
See Also
Get(int)
Returns true if the bit at index is set to 1.
Declaration
public bool Get(int index)
Parameters
| Type | Name | Description |
|---|---|---|
| int | index | Zero-based bit index in the range |
Returns
| Type | Description |
|---|---|
| bool |
|
Exceptions
| Type | Condition |
|---|---|
| ArgumentOutOfRangeException | Thrown when |
GetEnumerator()
Returns a ScyllaBitArray.Enumerator value-type enumerator that iterates over the
zero-based indices of all bits currently set to 1, in ascending order.
Declaration
public ScyllaBitArray.Enumerator GetEnumerator()
Returns
| Type | Description |
|---|---|
| ScyllaBitArray.Enumerator | A ScyllaBitArray.Enumerator positioned before the first set-bit index. |
Remarks
Because the return type is the concrete ScyllaBitArray.Enumerator struct (not
IEnumerator<int>), a foreach loop over a
ScyllaBitArray variable will use this method directly, avoiding any
boxing allocation. The enumerator skips empty words in O(1) per word using the
math.tzcnt trailing-zero-count instruction.
Not()
Inverts every bit in-place (bitwise NOT), turning all 1s into 0s and
all 0s into 1s.
Declaration
public void Not()
Remarks
Because Capacity is always a multiple of 64, all bits in every
word are meaningful. After the operation Count equals
Capacity - Count (the complement of the previous population count).
Count is recalculated in full after the operation via
Scylla.Core.Structures.ScyllaBitArray.RecalculatePopCount().
Or(ScyllaBitArray)
Performs an in-place bitwise OR of this array with other.
Declaration
public void Or(ScyllaBitArray other)
Parameters
| Type | Name | Description |
|---|---|---|
| ScyllaBitArray | other | The bit array to OR with. Must not be |
Remarks
Only the overlapping word range is ORed. Words in this array beyond
other's capacity are left unchanged because ORing with an
implicitly-zero word has no effect.
Count is recalculated in full after the operation via Scylla.Core.Structures.ScyllaBitArray.RecalculatePopCount().
Exceptions
| Type | Condition |
|---|---|
| ArgumentNullException | Thrown when |
PopCount()
Returns the population count - the number of bits currently set to 1.
Declaration
public int PopCount()
Returns
| Type | Description |
|---|---|
| int | The number of set bits, in the range |
Remarks
This is an O(1) property read of the cached counter maintained by all mutation methods. It is equivalent to reading Count and is provided as a named method to match the nomenclature used in the DOTS counterpart PopCount().
Set(int)
Sets the bit at index to 1.
If the bit is already set this method is a no-op and Count is
not incremented twice.
Declaration
public void Set(int index)
Parameters
| Type | Name | Description |
|---|---|---|
| int | index | Zero-based bit index in the range |
Exceptions
| Type | Condition |
|---|---|
| ArgumentOutOfRangeException | Thrown when |
Set(int, bool)
Sets or clears the bit at index according to
value.
Delegates to Set(int) when value is true
and to Unset(int) when false, so all validation and count
maintenance rules of those methods apply.
Declaration
public void Set(int index, bool value)
Parameters
| Type | Name | Description |
|---|---|---|
| int | index | Zero-based bit index in the range |
| bool | value |
|
Exceptions
| Type | Condition |
|---|---|
| ArgumentOutOfRangeException | Thrown when |
SetAll()
Declaration
public void SetAll()
Remarks
Every backing word is written to ulong.MaxValue (all 64 bits set), then
Scylla.Core.Structures.ScyllaBitArray.RecalculatePopCount() recomputes the cached count. The total
set-bit count after this call equals Capacity because the capacity
is always a multiple of 64 and every word is fully saturated.
Toggle(int)
Flips the bit at index: a 0 becomes 1 and a
1 becomes 0. Count is adjusted accordingly.
Declaration
public void Toggle(int index)
Parameters
| Type | Name | Description |
|---|---|---|
| int | index | Zero-based bit index in the range |
Exceptions
| Type | Condition |
|---|---|
| ArgumentOutOfRangeException | Thrown when |
Unset(int)
Clears the bit at index to 0.
If the bit is already clear this method is a no-op and Count is
not decremented below its current value.
Declaration
public void Unset(int index)
Parameters
| Type | Name | Description |
|---|---|---|
| int | index | Zero-based bit index in the range |
Exceptions
| Type | Condition |
|---|---|
| ArgumentOutOfRangeException | Thrown when |
Xor(ScyllaBitArray)
Performs an in-place bitwise XOR of this array with other.
Declaration
public void Xor(ScyllaBitArray other)
Parameters
| Type | Name | Description |
|---|---|---|
| ScyllaBitArray | other | The bit array to XOR with. Must not be |
Remarks
Only the overlapping word range is XORed. Words beyond
other's capacity are unaffected because XORing with zero
is an identity operation.
XOR is commonly used to toggle a set of bits atomically or to compute the symmetric difference of two sets.
Count is recalculated in full after the operation via Scylla.Core.Structures.ScyllaBitArray.RecalculatePopCount().
Exceptions
| Type | Condition |
|---|---|
| ArgumentNullException | Thrown when |