All files Iteration.ts

100% Statements 51/51
100% Branches 12/12
100% Functions 5/5
100% Lines 49/49
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77          6x 6x 4506x 4506x 6x   4500x         6x     2x             6x 6x 6x 6x     2x 4506x 4506x 4708x 4502x 4502x 4502x 4502x 2x 2x   4502x   206x 191x 191x 191x 191x 191x 191x   15x 6x 6x 6x 6x 6x 6x   9x 5x 5x 5x 5x 5x 5x   4x 4x 4x   4506x   2x  
import trailingZeros from 'count-trailing-zeros';
import { HierarchicalBitset } from "./BitSet";
import { BITS } from "./Utils"
 
export function iterate(a: HierarchicalBitset, callback: (value: object) => void) {
  const iterator = createIterator(a);
  while(true) {
    const { value, done } = iterator.next();
    if(done) {
      break;
    }
    callback(value);
  };
}
 
export function createIterator(a: HierarchicalBitset): BitSetIterator {
  return new BitSetIterator(a, [0, 0, 0, a.byte(0, 3)], [0, 0, 0]);
}
 
export class BitSetIterator {
  set: HierarchicalBitset;
  masks: [number, number, number, number];
  prefix: [number, number, number];
  done: boolean;
 
  constructor(set: HierarchicalBitset, masks: [number, number,  number, number], prefix: [number, number, number]) {
    this.set = set;
    this.masks = masks;
    this.prefix = prefix;
    this.done = false;
  }
 
  next() {
    let value = undefined;
    while(true) {
      if (this.masks[0] != 0) {
        const bit = trailingZeros(this.masks[0]);
        this.masks[0] &= ~(1 << bit);
        value = this.prefix[0] | bit;
        if(value >= this.set.size()) {
          this.done = true;
          value = undefined;
        }
        break;
      }
      if (this.masks[1] != 0) {
        const bit = trailingZeros(this.masks[1]);
        this.masks[1] &= ~(1 << bit);
        const index = this.prefix[1] | bit;
        this.masks[0] = this.set.byte(index, 0);
        this.prefix[0] = index << BITS;
        continue;
      }
      if (this.masks[2] != 0) {
        const bit = trailingZeros(this.masks[2]);
        this.masks[2] &= ~(1 << bit);
        const index = this.prefix[2] | bit;
        this.masks[1] = this.set.byte(index, 1);
        this.prefix[1] = index << BITS;
        continue;
      }
      if (this.masks[3] != 0) {
        const bit = trailingZeros(this.masks[3]);
        this.masks[3] &= ~(1 << bit);
        const index = this.prefix[3] | bit;
        this.masks[2] = this.set.byte(index, 2);
        this.prefix[2] = index << BITS;
        continue;
      }
      this.done = true;
      value = undefined;
      break;
    }
    return { value, done: this.done };
  }
}