docs(bitmap): add JSDoc for Bitmap class and helper functions
Add comprehensive JSDoc comments to src/bitmap.ts covering: - private helper functions (computeBitsArrayLength, getBitPositionIndex, getBitPosition, getMask) - the Bitmap class and all public methods (constructor, iterator, grow, set, remove, contains, count, and, andNot, or, xor, range, filter, clear, clone, min, max, minZero, maxZero) Comments describe parameters, return values and behavior (including iteration semantics). No runtime behaviour changes — this improves editor/tooling support (autocomplete/type hints) and prepares the code for TypeDoc generation.
This commit is contained in:
parent
6e845f5543
commit
5667aef80f
129
src/bitmap.ts
129
src/bitmap.ts
|
|
@ -1,15 +1,58 @@
|
|||
const computeBitsArrayLength = (x: number): number => Math.ceil(x / 8);
|
||||
/**
|
||||
* Compute the number of bytes required to store `x` bits.
|
||||
* @private
|
||||
* @param {number} x - Number of bits to accommodate.
|
||||
* @returns {number} Number of bytes required.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the byte index that contains the bit for position `x`.
|
||||
* @private
|
||||
* @param {number} x - Bit index.
|
||||
* @returns {number} Byte index in the underlying Uint8Array.
|
||||
*/
|
||||
const getBitPositionIndex = (x: number): number => Math.floor(x / 8);
|
||||
|
||||
/**
|
||||
* Get the position of the bit inside its byte for bit index `x`.
|
||||
* @private
|
||||
* @param {number} x - Bit index.
|
||||
* @returns {number} Bit position within the byte (0-7).
|
||||
*/
|
||||
const getBitPosition = (x: number): number => x % 8;
|
||||
|
||||
/**
|
||||
* Create an 8-bit mask with a 1 at `bitIdx`.
|
||||
* @private
|
||||
* @param {number} bitIdx - Bit position inside a byte (0-7).
|
||||
* @returns {number} Mask with the bit at `bitIdx` set (e.g. 0b00001000).
|
||||
*/
|
||||
const getMask = (bitIdx: number): number => 0b00000001 << bitIdx;
|
||||
|
||||
export class Bitmap {
|
||||
private bits: Uint8Array;
|
||||
|
||||
/**
|
||||
* Bitmap - a simple bitset backed by a Uint8Array.
|
||||
* Indices are zero-based.
|
||||
* @example
|
||||
* const b = new Bitmap(64); // capacity for 64 bits
|
||||
* b.set(10);
|
||||
* b.set(20);
|
||||
* console.log(b.contains(10)); // true
|
||||
*
|
||||
* @param {number} [x=32] - Initial capacity in bits (defaults to 32).
|
||||
*/
|
||||
constructor(x = 32) {
|
||||
this.bits = new Uint8Array(computeBitsArrayLength(x));
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate over all set bit indices in ascending order.
|
||||
* Yields the numeric index of each set bit.
|
||||
* @yields {number} The index of a set bit (0-based).
|
||||
*/
|
||||
public *[Symbol.iterator](): Generator<number> {
|
||||
for (let i = 0; i < this.bits.length; i++) {
|
||||
const byte = this.bits[i];
|
||||
|
|
@ -22,6 +65,12 @@ export class Bitmap {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the underlying array can hold at least up to bit index `x`.
|
||||
* This may reallocate the underlying Uint8Array, keeping existing bits.
|
||||
* @param {number} x - Bit index to accommodate.
|
||||
* @returns {void}
|
||||
*/
|
||||
public grow(x: number): void {
|
||||
const arrLength = Math.max(1, computeBitsArrayLength(x + 1));
|
||||
if (arrLength <= this.bits.length) return;
|
||||
|
|
@ -30,12 +79,24 @@ export class Bitmap {
|
|||
this.bits.set(prev);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the bit at index `x` to 1.
|
||||
* Automatically grows the internal buffer if necessary.
|
||||
* @param {number} x - Bit index to set (0-based).
|
||||
* @returns {void}
|
||||
*/
|
||||
public set(x: number): void {
|
||||
const idx = getBitPositionIndex(x);
|
||||
if (idx >= this.bits.length) this.grow(x);
|
||||
this.bits[idx] |= getMask(getBitPosition(x));
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the bit at index `x` (set to 0).
|
||||
* If `x` is beyond current capacity, the call is a no-op.
|
||||
* @param {number} x - Bit index to clear (0-based).
|
||||
* @returns {void}
|
||||
*/
|
||||
public remove(x: number): void {
|
||||
const idx = getBitPositionIndex(x);
|
||||
if (idx >= this.bits.length) return;
|
||||
|
|
@ -43,6 +104,11 @@ export class Bitmap {
|
|||
this.bits[idx] &= ~mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the bit at index `x` is set.
|
||||
* @param {number} x - Bit index to test (0-based).
|
||||
* @returns {boolean} True if the bit is 1, false otherwise.
|
||||
*/
|
||||
public contains(x: number): boolean {
|
||||
const idx = getBitPositionIndex(x);
|
||||
if (idx >= this.bits.length) return false;
|
||||
|
|
@ -50,6 +116,10 @@ export class Bitmap {
|
|||
return (this.bits[idx] & mask) === mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count number of set bits in the bitmap (Hamming weight).
|
||||
* @returns {number} Number of bits set to 1.
|
||||
*/
|
||||
public count(): number {
|
||||
let count = 0;
|
||||
for (const byte of this.bits) {
|
||||
|
|
@ -62,6 +132,12 @@ export class Bitmap {
|
|||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bitwise AND with another bitmap. Returns a new Bitmap containing the intersection.
|
||||
* The result's capacity is equal to the left-hand bitmap's capacity (cloned from `this`).
|
||||
* @param {Bitmap} bitmap - Other bitmap to AND with.
|
||||
* @returns {Bitmap} New Bitmap representing this & bitmap.
|
||||
*/
|
||||
public and(bitmap: Bitmap): Bitmap {
|
||||
const otherBits = (bitmap as Bitmap).bits;
|
||||
const result = this.clone() as Bitmap;
|
||||
|
|
@ -78,6 +154,11 @@ export class Bitmap {
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bitwise AND NOT (this & ~bitmap). Returns a new Bitmap.
|
||||
* @param {Bitmap} bitmap - Other bitmap to subtract from this.
|
||||
* @returns {Bitmap} New Bitmap representing this & ~bitmap.
|
||||
*/
|
||||
public andNot(bitmap: Bitmap): Bitmap {
|
||||
const otherBits = (bitmap as Bitmap).bits;
|
||||
const result = this.clone() as Bitmap;
|
||||
|
|
@ -90,6 +171,12 @@ export class Bitmap {
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bitwise OR (union) with another bitmap. Returns a new Bitmap.
|
||||
* The resulting bitmap will be large enough to contain bits from both operands.
|
||||
* @param {Bitmap} bitmap - Other bitmap to OR with.
|
||||
* @returns {Bitmap} New Bitmap representing this | bitmap.
|
||||
*/
|
||||
public or(bitmap: Bitmap): Bitmap {
|
||||
const otherBits = (bitmap as Bitmap).bits;
|
||||
let result = this.clone() as Bitmap;
|
||||
|
|
@ -110,6 +197,12 @@ export class Bitmap {
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bitwise XOR (symmetric difference) with another bitmap. Returns a new Bitmap.
|
||||
* The resulting bitmap will be large enough to contain bits from both operands.
|
||||
* @param {Bitmap} bitmap - Other bitmap to XOR with.
|
||||
* @returns {Bitmap} New Bitmap representing this ^ bitmap.
|
||||
*/
|
||||
public xor(bitmap: Bitmap): Bitmap {
|
||||
const otherBits = (bitmap as Bitmap).bits;
|
||||
let result = this.clone() as Bitmap;
|
||||
|
|
@ -130,6 +223,12 @@ export class Bitmap {
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate over set bits and call `fn` for each set bit index in ascending order.
|
||||
* If `fn` returns `false`, iteration stops early.
|
||||
* @param {(x: number) => boolean | void} fn - Callback invoked with each set bit index. Returning `false` stops iteration.
|
||||
* @returns {void}
|
||||
*/
|
||||
public range(fn: (x: number) => boolean | void): void {
|
||||
let needContinueIterating = true;
|
||||
for (let i = 0; i < this.bits.length; i++) {
|
||||
|
|
@ -144,6 +243,11 @@ export class Bitmap {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove bits for which `fn(bitIndex)` returns false. Mutates this bitmap.
|
||||
* @param {(x: number) => boolean} fn - Predicate called for each set bit index; if it returns false the bit is cleared.
|
||||
* @returns {void}
|
||||
*/
|
||||
public filter(fn: (x: number) => boolean): void {
|
||||
for (let i = 0; i < this.bits.length; i++) {
|
||||
for (let j = 0; j < 8; j++) {
|
||||
|
|
@ -155,18 +259,31 @@ export class Bitmap {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all bits (set all to zero).
|
||||
* @returns {void}
|
||||
*/
|
||||
public clear(): void {
|
||||
for (let i = 0; i < this.bits.length; i++) {
|
||||
this.bits[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a deep copy of this bitmap.
|
||||
* The clone's capacity is equal to the number of bits represented by the current byte-length.
|
||||
* @returns {Bitmap} A new Bitmap instance with the same bits set.
|
||||
*/
|
||||
public clone(): Bitmap {
|
||||
const clonedBitmap = new Bitmap(this.bits.length * 8);
|
||||
clonedBitmap.bits.set(this.bits);
|
||||
return clonedBitmap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the smallest set bit index or -1 if none are set.
|
||||
* @returns {number} Minimum set bit index, or -1 if empty.
|
||||
*/
|
||||
public min(): number {
|
||||
for (let i = 0; i < this.bits.length; i++) {
|
||||
const byte = this.bits[i];
|
||||
|
|
@ -180,6 +297,10 @@ export class Bitmap {
|
|||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the largest set bit index or -1 if none are set.
|
||||
* @returns {number} Maximum set bit index, or -1 if empty.
|
||||
*/
|
||||
public max(): number {
|
||||
let x = -1;
|
||||
for (let i = this.bits.length - 1; i >= 0; i--) {
|
||||
|
|
@ -191,6 +312,10 @@ export class Bitmap {
|
|||
return x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the first zero bit index (smallest index not set). If all bits are set, returns capacity (bits.length * 8).
|
||||
* @returns {number} Index of the first zero bit, or capacity if none found.
|
||||
*/
|
||||
public minZero(): number {
|
||||
for (let i = 0; i < this.bits.length; i++) {
|
||||
const byte = this.bits[i];
|
||||
|
|
@ -204,6 +329,10 @@ export class Bitmap {
|
|||
return this.bits.length * 8;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the last zero bit index (largest index not set) or -1 if all bits are set.
|
||||
* @returns {number} Index of the last zero bit, or -1 if none found.
|
||||
*/
|
||||
public maxZero(): number {
|
||||
for (let i = this.bits.length - 1; i >= 0; i--) {
|
||||
const byte = this.bits[i];
|
||||
|
|
|
|||
Loading…
Reference in New Issue