Skip to content

Commit 3a24680

Browse files
authored
Merge pull request #29 from will-path/patch-1
Add hasAnyInRange to TypedFastBitSet
2 parents 001bfb4 + 99fbef0 commit 3a24680

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

src/BitSet.range.spec.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { bitsetTest } from "./testUtils";
22
import { SparseTypedFastBitSet } from "./SparseTypedFastBitSet";
3+
import { TypedFastBitSet } from "./TypedFastBitSet";
34

45
describe("sparse biggest logic", () => {
56
it("Testing sparse addRange/removeRange", () => {
@@ -25,6 +26,27 @@ describe("sparse biggest logic", () => {
2526
});
2627
});
2728

29+
describe("fixed bitset logic", () => {
30+
it("Testing has any in range", () => {
31+
const b1 = new TypedFastBitSet();
32+
b1.addRange(100, 200);
33+
b1.addRange(230, 250);
34+
expect(b1.hasAnyInRange(0, 100)).toBe(false); // before
35+
expect(b1.hasAnyInRange(200, 204)).toBe(false); // endword === firstword
36+
expect(b1.hasAnyInRange(200, 229)).toBe(false); // gaps
37+
expect(b1.hasAnyInRange(250, 300)).toBe(false); // after
38+
expect(b1.hasAnyInRange(99, 101)).toBe(true); // across start 1
39+
expect(b1.hasAnyInRange(99, 140)).toBe(true); // across start 2
40+
expect(b1.hasAnyInRange(99, 201)).toBe(true); // across start/end
41+
expect(b1.hasAnyInRange(100, 140)).toBe(true); // start
42+
expect(b1.hasAnyInRange(100, 200)).toBe(true); // start past end
43+
expect(b1.hasAnyInRange(101, 198)).toBe(true); // inside
44+
expect(b1.hasAnyInRange(120, 121)).toBe(true); // smol
45+
expect(b1.hasAnyInRange(197, 200)).toBe(true); // end
46+
expect(b1.hasAnyInRange(199, 210)).toBe(true); // across end
47+
});
48+
});
49+
2850
bitsetTest(({ name, build, arrayEqual }) => {
2951
describe(name, () => {
3052
it("Testing add Range", () => {

src/TypedFastBitSet.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,24 @@ export class TypedFastBitSet implements BitSet {
169169
return (this.words[index >>> 5] & (1 << index)) !== 0;
170170
}
171171

172+
/**
173+
* Is any value of the (exclusive) range contained in the set?
174+
*/
175+
hasAnyInRange(start: number, end: number): boolean {
176+
if (start >= end) return false;
177+
const words = this.words;
178+
start = Math.min(start, (words.length << 5) - 1);
179+
end = Math.min(end, (words.length << 5) - 1);
180+
const firstword = start >>> 5;
181+
const endword = (end - 1) >> 5;
182+
if (firstword === endword)
183+
return (words[firstword] & ((~0 << start) & (~0 >>> -end))) !== 0;
184+
if ((words[firstword] & (~0 << start)) !== 0) return true;
185+
for (let index = firstword + 1; index < endword - 1; index++)
186+
if (words[index] !== 0) return true;
187+
return (words[endword] & (~0 >>> -end)) !== 0;
188+
}
189+
172190
/**
173191
* Tries to add the value (Set the bit at index to true)
174192
*

0 commit comments

Comments
 (0)