@memlab/core
Version:
memlab core libraries
79 lines (78 loc) • 2.26 kB
JavaScript
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @lightSyntaxTransform
* @oncall memory_lab
*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
// V8's Set has a maximum capacity of 2^24 (16,777,216) elements.
// Chrome M148+ heap snapshots can exceed this, so we shard across
// multiple native Sets keyed by value range.
const DEFAULT_SHARD_CAPACITY = 5000000;
class NumericSet {
constructor(iterable) {
this.shards = new Map();
this._size = 0;
this.shardCapacity = DEFAULT_SHARD_CAPACITY;
if (iterable) {
for (const value of iterable) {
this.add(value);
}
}
}
getShardKey(value) {
return Math.floor(value / this.shardCapacity);
}
add(value) {
const shardKey = this.getShardKey(value);
let shard = this.shards.get(shardKey);
if (!shard) {
shard = new Set();
this.shards.set(shardKey, shard);
}
const prevSize = shard.size;
shard.add(value);
if (shard.size > prevSize) {
this._size++;
}
return this;
}
has(value) {
var _a;
const shard = this.shards.get(this.getShardKey(value));
return (_a = shard === null || shard === void 0 ? void 0 : shard.has(value)) !== null && _a !== void 0 ? _a : false;
}
delete(value) {
const shard = this.shards.get(this.getShardKey(value));
if (shard === null || shard === void 0 ? void 0 : shard.delete(value)) {
this._size--;
return true;
}
return false;
}
get size() {
return this._size;
}
forEach(callback) {
for (const shard of this.shards.values()) {
for (const value of shard) {
callback(value, value, this);
}
}
}
clear() {
this.shards.clear();
this._size = 0;
}
*[Symbol.iterator]() {
for (const shard of this.shards.values()) {
yield* shard;
}
}
}
exports.default = NumericSet;