UNPKG

typescript-algorithms-and-datastructures

Version:
113 lines 4.3 kB
(function (factory) { if (typeof module === "object" && typeof module.exports === "object") { var v = factory(require, exports); if (v !== undefined) module.exports = v; } else if (typeof define === "function" && define.amd) { define(["require", "exports"], factory); } })(function (require, exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); class BitArray { constructor(size) { this.length = 0; this.length = size; this.buffer = new Uint32Array(this.calculateBufferSize(this.length)); } count() { return this.buffer.reduce((total, chunk) => this.bitsCountInNumber(chunk) + total, 0); } get(index) { this.validateIndex(index); const chunkOffset = Math.floor(index / 32); const bitOffset = index - chunkOffset * 32; return !!(this.buffer[chunkOffset] & (1 << bitOffset)); } getIndexes() { let result = []; let bitIndex = 0; let bit = false; while (bitIndex < this.length) { bit = this.get(bitIndex); if (bit) { result.push(bitIndex); } bitIndex++; } return result; } reset() { this.buffer.fill(0); return this; } resize(newSize) { if (newSize < 0) { throw new RangeError(`Invalid new BitSet size ${newSize}`); } const newBufferSize = this.calculateBufferSize(newSize); this.length = newSize; if (newBufferSize > this.buffer.length) { const oldBuffer = this.buffer; this.buffer = new Uint32Array(newBufferSize); this.buffer.set(oldBuffer); } else if (newBufferSize < this.buffer.length) { const oldBuffer = this.buffer; this.buffer = new Uint32Array(newBufferSize); this.buffer.set(oldBuffer.slice(0, newBufferSize)); } return this; } size() { return this.length; } splice(startIndex, deleteCount) { if (isNaN(deleteCount) || deleteCount < 1) { return; } if (startIndex < 0) { startIndex = this.length + startIndex; if (startIndex < 0) { throw new RangeError(`${startIndex} is less than 0`); } } else if (startIndex >= this.length) { throw new RangeError(`${startIndex} exceeds the array size ${this.length}`); } const tempBuffer = this.getIndexes() .filter(index => index < startIndex || index >= startIndex + deleteCount) .map(index => index >= startIndex + deleteCount ? index - deleteCount : index); this.reset(); this.resize(this.length - deleteCount); tempBuffer.forEach(id => this.set(id, true)); } set(index, value) { this.validateIndex(index); const chunkOffset = Math.floor(index / 32); const offset = index - chunkOffset * 32; if (value) { this.buffer[chunkOffset] |= (1 << offset); } else { this.buffer[chunkOffset] &= ~(1 << offset); } return this; } calculateBufferSize(bitsCount) { return Math.ceil(bitsCount / 32) * 4; } bitsCountInNumber(value) { value -= ((value >>> 1) & 0x55555555); value = (value & 0x33333333) + ((value >>> 2) & 0x33333333); return (((value + (value >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24); } validateIndex(index) { if (index > this.length - 1 || index < 0) { throw new RangeError("Index is too large."); } } } exports.BitArray = BitArray; }); //# sourceMappingURL=BitArray.js.map