UNPKG

@tanishiking/aho-corasick

Version:

TypeScript implementation of the Aho-Corasick algorithm for efficient string matching

108 lines (107 loc) 4.25 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.IntervalNode = void 0; var Direction; (function (Direction) { Direction[Direction["Right"] = 0] = "Right"; Direction[Direction["Left"] = 1] = "Left"; })(Direction || (Direction = {})); /** * Binary tree to find all intervals that overlaps with the given interval efficiently. */ var IntervalNode = /** @class */ (function () { /** * * @param intervals intervals, note that they should be sorted by size decending. */ function IntervalNode(intervals) { var _this = this; this.intervals = []; this.left = null; this.right = null; this.medianPoint = this.determineMedian(intervals); var toLeft = []; var toRight = []; intervals.forEach(function (interval) { if (interval.end < _this.medianPoint) { toLeft.push(interval); } else if (_this.medianPoint < interval.start) { toRight.push(interval); } else { _this.intervals.push(interval); } }); if (toLeft.length > 0) this.left = new IntervalNode(toLeft); if (toRight.length > 0) this.right = new IntervalNode(toRight); } /** * Find all intervals overlap with the given interval. * * @param interval - the interval object to find its overlaps. */ IntervalNode.prototype.findOverlaps = function (interval) { if (this.medianPoint < interval.start) { var fromRightChild = this.right !== null ? this.right.findOverlaps(interval) : []; var fromThisNode = this.checkForOverlaps(interval, Direction.Right); return fromRightChild.concat(fromThisNode).filter(function (current) { return !interval.equals(current); }); } else if (interval.end < this.medianPoint) { var fromLeftChild = this.left !== null ? this.left.findOverlaps(interval) : []; var fromThisNode = this.checkForOverlaps(interval, Direction.Left); return fromLeftChild.concat(fromThisNode).filter(function (current) { return !interval.equals(current); }); } else { var fromRightChild = this.right !== null ? this.right.findOverlaps(interval) : []; var fromLeftChild = this.left !== null ? this.left.findOverlaps(interval) : []; return this.intervals .concat(fromRightChild) .concat(fromLeftChild) .filter(function (current) { return !interval.equals(current); }); } }; /** * Find the intervals that overlaps with the given interval (which never contains median point) * from the intervals of this node (which always contains median point). * median * ---------------------o--------------------- * given interval ------[xxxxxxx]--------------[xxxxx]------- * current ------------[xxxxxxxxxxxxxxxxxxx]---------- * * @param interval - the interval to find its overlaps. * @param direction - the direction to search for. */ IntervalNode.prototype.checkForOverlaps = function (interval, direction) { return this.intervals.filter(function (current) { if (direction === Direction.Left) return current.start <= interval.end; else return current.end >= interval.start; }); }; /** * Find a median point from left most start and right most ends. * * @param intervals */ IntervalNode.prototype.determineMedian = function (intervals) { var start = -1; var end = -1; intervals.forEach(function (interval) { var currentStart = interval.start; var currentEnd = interval.end; if (start === -1 || currentStart < start) { start = currentStart; } if (end === -1 || currentEnd > end) { end = currentEnd; } }); return Math.floor((start + end) / 2); }; return IntervalNode; }()); exports.IntervalNode = IntervalNode;