All files / sportident/src/utils NumberRangeRegistry.ts

100% Statements 26/26
100% Branches 10/10
100% Functions 7/7
100% Lines 26/26

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 4737x 37x     37x 34x 34x     56x 56x   71x 71x 71x 71x 71x 1x         70x     55x 55x       69x 69x   100x 100x 100x 100x     69x 69x 40x   29x      
import Immutable from 'immutable';
import * as generalUtils from './general';
import {NumberRange} from './NumberRange';
 
export class NumberRangeRegistry<T> {
    public numberRanges: Immutable.List<NumberRange> = Immutable.List();
    public values: Immutable.List<T> = Immutable.List();
 
    register(numberRange: NumberRange, value: T): void {
        const index = generalUtils.binarySearch(this.numberRanges, numberRange, {
            getLength: (numberRanges) => numberRanges.size,
            getNewRange: (numberRanges, numberRangeToInsert, start, end) => {
                const mid = Math.floor((start + end) / 2);
                const midNumberRange = numberRanges.get(mid)!;
                const isEntirelyBeforeMid = numberRangeToInsert.isEntirelyBefore(midNumberRange);
                const isEntirelyAfterMid = numberRangeToInsert.isEntirelyAfter(midNumberRange);
                if (!isEntirelyBeforeMid && !isEntirelyAfterMid) {
                    throw new Error(
                        `Refusing to insert ${numberRangeToInsert.toString()} ` +
                        `next to ${midNumberRange.toString()}`,
                    );
                }
                return isEntirelyBeforeMid ? [start, mid] : [mid + 1, end];
            },
        });
        this.numberRanges = this.numberRanges.insert(index, numberRange);
        this.values = this.values.insert(index, value);
    }
 
    getValueForNumber(number: number): T|undefined {
        const index = generalUtils.binarySearch(this.numberRanges, number, {
            getLength: (numberRanges) => numberRanges.size,
            getNewRange: (numberRanges, number_, start, end) => {
                const mid = Math.floor((start + end) / 2);
                const midNumberRange = numberRanges.get(mid)!;
                const isBeforeOrInMid = !midNumberRange.isEntirelyBefore(number_);
                return isBeforeOrInMid ? [start, mid] : [mid + 1, end];
            },
        });
        const numberRangeAtIndex = this.numberRanges.get(index);
        if (numberRangeAtIndex !== undefined && numberRangeAtIndex.contains(number)) {
            return this.values.get(index);
        }
        return undefined;
    }
}