@eagleoutice/flowr-dev
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
107 lines • 3.03 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BiMap = void 0;
/**
* Implementation of a bidirectional map
*
* All map-related functions are based on the normal Key -> Value map
*/
class BiMap {
[Symbol.toStringTag] = 'BiMap';
size = 0;
k2v = new Map();
/* see {@link BiMapReverse}: `undefined` until the first reverse lookup unless this map was asked to be eager */
v2k;
eager;
/**
* @param base - the entries to fill the map with
* @param reverse - when to fill the value -> key direction; see {@link BiMapReverse}
*/
constructor(base, reverse = 'lazy') {
this.eager = reverse === 'eager';
if (this.eager) {
this.v2k = new WeakMap();
}
if (base != null) {
for (const [k, v] of base) {
this.set(k, v);
}
}
}
[Symbol.iterator]() {
return this.k2v[Symbol.iterator]();
}
clear() {
this.size = 0;
this.k2v.clear();
this.v2k = this.eager ? new WeakMap() : undefined;
}
delete(key) {
const value = this.k2v.get(key);
if (value === undefined) {
return false;
}
this.k2v.delete(key);
/* another key may still hold this value, so dropping just its entry would lose a live mapping */
this.staleReverse();
this.size = this.k2v.size;
return true;
}
entries() {
return this.k2v.entries();
}
forEach(callbackFunction) {
this.k2v.forEach(callbackFunction);
}
get(key) {
return this.k2v.get(key);
}
getKey(value) {
return this.reverse().get(value);
}
has(key) {
return this.k2v.has(key);
}
hasValue(value) {
return this.reverse().has(value);
}
keys() {
return this.k2v.keys();
}
set(key, value) {
const replaced = this.k2v.get(key);
this.k2v.set(key, value);
if (replaced !== undefined && replaced !== value) {
/* the value this key held may now be unreachable, so its reverse entry cannot stand */
this.staleReverse();
}
else {
this.v2k?.set(value, key);
}
this.size = this.k2v.size;
return this;
}
/** the reverse direction can no longer be maintained in place, so re-derive it (at once if eager) */
staleReverse() {
this.v2k = undefined;
if (this.eager) {
this.reverse();
}
}
values() {
return this.k2v.values();
}
/** the value -> key direction, filled from the entries already present if this is its first use */
reverse() {
if (this.v2k === undefined) {
const v2k = new WeakMap();
for (const [k, v] of this.k2v) {
v2k.set(v, k);
}
this.v2k = v2k;
}
return this.v2k;
}
}
exports.BiMap = BiMap;
//# sourceMappingURL=bimap.js.map