UNPKG

i2bplustree

Version:

A package to implement the Improved Interval B+ tree, in TypeScript

138 lines (122 loc) 4.92 kB
import { IBplusInternalNode, Interval, FlatInterval } from './internal'; /** * Class implementation of a Interval B+-Tree. * This is the class the user will be importing and using, so it works as an user interface for the IB+-tree * * Based on Article: https://pdfs.semanticscholar.org/1343/91e2537a8a9db15a1b5cce2ef66aa3352506.pdf * B+tree where each node is augmented with the same kind of information as in the binary Interval-trees. */ export class IBplusTree<T extends FlatInterval> { private root: IBplusInternalNode<T>; /** * IBplusTree Constructor. * Alpha is a parameter (0 < alpha < 1) which can be tuned to adjust space(hence update cost)/query_time tradeoff. * Higher values will lead to fewer splits and hence less storage expansion, but also to worse query efficiency. * Smaller values will lead to better query efficiency, but increase storage requirements and update costs (due to * reinsertion of split parts). * * @param order The tree's maximum number of children per node. * @param alpha If alpha is inferior to 0 time splits are not used, and otherwise they are (see consideration regarding * alpha above). */ constructor(order: number, private alpha: number = 0) { if (order < 2) throw new Error('IB+ tree must have order >= 2'); if (alpha >= 1) throw new Error('Alpha can either be negative or a value belonging to ]0, 1['); this.root = new IBplusInternalNode<T>(order); } /** * Insert the given Interval in the tree * * @param int The interval to be inserted */ insert(int: T): void { this.root.insert(int, this.alpha); while (!this.root.isRoot()) this.root = this.root.getParent(); } /** * Delete the given Interval from the tree * * @param int The Interval to be removed */ delete(int: T): void { this.root.delete(int, this.alpha); if (this.root.isChildNewRoot()) // It is forcibly of type IBPlusInternalNode this.root = <IBplusInternalNode<T>>this.root.getChildren()[0]; } /** * Destroy all intervals stored in the tree that are fully * contained in the given bounds. * * @param lowerBound The range query lower bound * @param upperBound The range query upper bound */ rangeDelete(lowerBound: number, upperBound: number): void { this.root.rangeDelete(lowerBound, upperBound); while (this.root.isChildNewRoot()) // It is forcibly of type IBPlusInternalNode this.root = <IBplusInternalNode<T>>this.root.getChildren()[0]; } /** * Verify if the given interval exists in the tree. * * @param interval the interval to be searched * @returns the object if exists, null otherwise. */ exists(interval: T): boolean { return this.root.exists(interval); } /** * Get all intervals stored in the tree with equal bounds to the given ones. * * @param lowerBound The interval query lower bound * @param upperBound The interval query upper bound * @returns Array of found intervals. */ search(lowerBound: number, upperBound: number): Set<T> { return this.root.search(new FlatInterval(lowerBound, upperBound)); } /** * Gets the Interval with the lowest bound that intersects the * given interval. * * @param lowerBound The interval query lower bound * @param upperBound The interval query upper bound * @returns the FlatInterval that was found, null if none intersected. */ loneRangeSearch(lowerBound: number, upperBound: number): T | null { return this.root.loneRangeSearch(new FlatInterval(lowerBound, upperBound)); } /** * Find all intervals stored in the tree that intersect the given range. * * @param lowerBound The range query lower bound * @param upperBound The range query upper bound * @returns Set of intervals that intersect the range */ allRangeSearch(lowerBound: number, upperBound: number): Set<T> { return this.root.allRangeSearch(new FlatInterval(lowerBound, upperBound)); } /** * Find all intervals stored in the tree that are contained in the given range. * * @param lowerBound The range query lower bound * @param upperBound The range query upper bound * @returns Set of intervals that are contained in the range */ containedRangeSearch(lowerBound: number, upperBound: number): Set<T> { return this.root.containedRangeSearch(new FlatInterval(lowerBound, upperBound)); } /** * Represents the current tree as a string. * Useful for printing purposes. * * @returns the root as a string */ asString(): string { return this.root.asString(); } }