UNPKG

van-emde-boas

Version:

van Emde Boas trees

39 lines 2.96 kB
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.VEB=void 0;class VEB{constructor(bound){this.bound=bound;this.summary=null;this.min=-1;this.max=-1;this._size=0;const shift=Math.floor(Math.log2(bound)/2);this.shift=shift;const lo_mask=0xffffffff>>>(32-shift);this.lo_mask=lo_mask;this.clusters={};} get size(){return this._size;} insert(x){if(x>=this.bound||x<0){throw new Error(`${x}is out of bounds for universe size ${this.bound}.`);} let t=this;let top=0;const path=[];for(;;){const{min,max,_size}=t;if(x===min||x===max){return false;} if(_size===0){t.min=x;t.max=x;break;} if(x<min){t.min=x;x=min;} else if(x>max){t.max=x;x=max;} if(_size===1) break;const{clusters}=t;const i=x>>>t.shift;let cluster=clusters[i];if(!cluster){const cluster_size=1<<t.shift;cluster=new VEB(cluster_size);clusters[i]=cluster;if(t.summary===null){t.summary=new VEB(Math.ceil(t.bound/cluster_size));} t.summary.insert(i);} path[top++]=t;x=x&t.lo_mask;t=cluster;} while(top>0){path[--top]._size++;} t._size++;return true;} delete(x){z:{let i;let j;Number;let cluster;const{min,max,_size}=this;if(x===min){switch(_size){case 1:this.max=-1;case 2:this.min=this.max;break z;} i=this.summary.min;cluster=this.clusters[i];j=cluster.min;this.min=(i<<this.shift)|j;} else if(x===max){switch(_size){case 1:this.min=-1;case 2:this.max=this.min;break z;} i=this.summary.max;cluster=this.clusters[i];j=cluster.max;this.max=(i<<this.shift)|j;} else{i=x>>>this.shift;cluster=this.clusters[i];if(!cluster){return false;} j=x&this.lo_mask;} if(!cluster.delete(j)){return false;} if(cluster._size===0){this.summary.delete(i);if(this.summary._size===0){this.summary=null;} delete this.clusters[i];}} this._size--;return true;} next(x){let t=this;let hi=0;for(;;){const{clusters,min,max,shift,summary}=t;if(x<=min){return hi|min;} let i=x>>>shift;const cluster=clusters[i];if(cluster){const j=x&t.lo_mask;if(j<=cluster.max){hi=hi|(i<<shift);t=cluster;x=j;continue;}} i=summary!==null?summary.next(i+1):-1;if(i===-1){return x<=max?hi|max:-1;} return hi|(i<<shift)|clusters[i].min;}} has(x){let t=this;for(;;){if(x===t.min||x===t.max){return true;} const cluster=t.clusters[x>>>t.shift];if(!cluster){return false;} x=x&t.lo_mask;t=cluster;}} prev(x){let t=this;let hi=0;for(;;){const{clusters,min,max,shift,summary}=t;if(x>=max){return hi|max;} let i=x>>>shift;const cluster=clusters[i];if(cluster){const j=x&t.lo_mask;if(j>=cluster.min){hi=hi|(i<<shift);t=cluster;x=j;continue;}} i=i>0&&summary!==null?summary.prev(i-1):-1;if(i===-1){return x>=min?hi|min:-1;} return hi|(i<<shift)|clusters[i].max;}}*keys(){const{min,_size}=this;if(_size===0){return;} yield min;const{max,clusters}=this;if(max>min){if(this.summary){const{shift}=this;for(const i of this.summary){for(const j of clusters[i]){yield(i<<shift)|j;}}} yield max;}} values(){return this.keys();}*entries(){for(const i of this.keys()){yield[i,i];}} [Symbol.iterator](){return this.keys();}} exports.VEB=VEB;