infinity-map
Version:
A Map that doesn't throw if you put more than 16 million items in it. Because that's what the native `Map` object does for some reason.
88 lines (87 loc) • 2.13 kB
JavaScript
/* MAIN */
class InfinityMap {
/* CONSTRUCTOR */
constructor(entries = []) {
if (entries.length < 16777215) {
this.current = new Map(entries);
this.pool = [this.current];
}
else {
this.current = new Map();
this.pool = [this.current];
for (const [key, value] of entries) {
this.set(key, value);
}
}
}
/* GETTERS */
get size() {
return this.pool.reduce((sum, map) => sum + map.size, 0);
}
/* API */
clear() {
this.current = new Map();
this.pool = [this.current];
return;
}
delete(key) {
return this.pool.some(map => map.delete(key));
}
get(key) {
for (const map of this.pool) {
if (!map.has(key))
continue;
return map.get(key);
}
return;
}
has(key) {
return this.pool.some(map => map.has(key));
}
set(key, value) {
let targetMap = this.current;
if (this.pool.length > 1) {
for (const map of this.pool) {
if (!map.has(key))
continue;
targetMap = map;
break;
}
}
targetMap.set(key, value);
if (this.current.size === 16777215) {
this.current = new Map();
this.pool.push(this.current);
}
return this;
}
/* ITERATION API */
*[Symbol.iterator]() {
for (const map of this.pool) {
yield* map[Symbol.iterator]();
}
}
*keys() {
for (const map of this.pool) {
yield* map.keys();
}
}
*values() {
for (const map of this.pool) {
yield* map.values();
}
}
*entries() {
for (const map of this.pool) {
yield* map.entries();
}
}
forEach(callback, thisArg) {
for (const [key, value] of this) {
callback.call(thisArg, value, key, this);
}
return;
}
}
/* EXPORT */
export default InfinityMap;