110 lines
3.0 KiB
JavaScript
110 lines
3.0 KiB
JavaScript
|
|
import v8 from 'node:v8';
|
||
|
|
import { Arbiter } from '../src/core/Arbiter.js';
|
||
|
|
|
||
|
|
function parseArgs(argv) {
|
||
|
|
const args = new Map();
|
||
|
|
for (let i = 2; i < argv.length; i++) {
|
||
|
|
const value = argv[i];
|
||
|
|
if (!value.startsWith('--')) continue;
|
||
|
|
const [key, inline] = value.slice(2).split('=');
|
||
|
|
if (inline !== undefined) {
|
||
|
|
args.set(key, inline);
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
const next = argv[i + 1];
|
||
|
|
if (next && !next.startsWith('--')) {
|
||
|
|
args.set(key, next);
|
||
|
|
i++;
|
||
|
|
} else {
|
||
|
|
args.set(key, true);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return args;
|
||
|
|
}
|
||
|
|
|
||
|
|
function parseSizes(value) {
|
||
|
|
if (!value) return null;
|
||
|
|
return value.split(',').map(item => Number(item.trim())).filter(Number.isFinite);
|
||
|
|
}
|
||
|
|
|
||
|
|
function formatBytes(bytes) {
|
||
|
|
const units = ['B', 'KB', 'MB', 'GB'];
|
||
|
|
let idx = 0;
|
||
|
|
let val = bytes;
|
||
|
|
while (val >= 1024 && idx < units.length - 1) {
|
||
|
|
val /= 1024;
|
||
|
|
idx++;
|
||
|
|
}
|
||
|
|
return `${val.toFixed(2)}${units[idx]}`;
|
||
|
|
}
|
||
|
|
|
||
|
|
function gc() {
|
||
|
|
if (global.gc) {
|
||
|
|
global.gc();
|
||
|
|
global.gc();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function buildNodes(arbiter, count, prefix) {
|
||
|
|
for (let i = 0; i < count; i++) {
|
||
|
|
arbiter.addNode(`${prefix}:${i}`, prefix);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function addEdges(arbiter, size, relation, perNode, srcPrefix = 'user', dstPrefix = 'resource') {
|
||
|
|
for (let i = 0; i < size; i++) {
|
||
|
|
for (let j = 0; j < perNode; j++) {
|
||
|
|
const dstId = (i + j) % size;
|
||
|
|
arbiter.addRelation(`${srcPrefix}:${i}`, relation, `${dstPrefix}:${dstId}`);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function buildGraph(arbiter, size) {
|
||
|
|
buildNodes(arbiter, size, 'user');
|
||
|
|
buildNodes(arbiter, size, 'resource');
|
||
|
|
|
||
|
|
addEdges(arbiter, size, 'owner', 1);
|
||
|
|
addEdges(arbiter, size, 'viewer', 1);
|
||
|
|
addEdges(arbiter, size, 'group_tuple_to_userset', 1);
|
||
|
|
addEdges(arbiter, size, 'plan_chain', 1);
|
||
|
|
addEdges(arbiter, size, 'account_admin_chain', 1);
|
||
|
|
addEdges(arbiter, size, 'blocked_unless', 1);
|
||
|
|
addEdges(arbiter, size, 'age_abac', 2);
|
||
|
|
addEdges(arbiter, size, 'risk_limit', 2);
|
||
|
|
addEdges(arbiter, size, 'feature_flag', 1);
|
||
|
|
addEdges(arbiter, size, 'owa_union', 1);
|
||
|
|
addEdges(arbiter, size, 'owa_comparator_nested', 5);
|
||
|
|
|
||
|
|
const relationConfigs = ['owner', 'viewer', 'group_tuple_to_userset', 'plan_chain', 'account_admin_chain',
|
||
|
|
'blocked_unless', 'age_abac', 'risk_limit', 'feature_flag', 'owa_union', 'owa_comparator_nested'];
|
||
|
|
for (const relation of relationConfigs) {
|
||
|
|
arbiter.setRelationConfig(relation, { type: 'direct' });
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
const args = parseArgs(process.argv);
|
||
|
|
const sizes = parseSizes(args.get('sizes')) || [10000, 50000];
|
||
|
|
|
||
|
|
console.log('memory_breakdown');
|
||
|
|
console.log('size,space,space_used,space_size,space_available,physical');
|
||
|
|
|
||
|
|
for (const size of sizes) {
|
||
|
|
const arbiter = new Arbiter();
|
||
|
|
gc();
|
||
|
|
buildGraph(arbiter, size);
|
||
|
|
gc();
|
||
|
|
|
||
|
|
const spaces = v8.getHeapSpaceStatistics();
|
||
|
|
for (const space of spaces) {
|
||
|
|
console.log([
|
||
|
|
size,
|
||
|
|
space.space_name,
|
||
|
|
formatBytes(space.space_used_size),
|
||
|
|
formatBytes(space.space_size),
|
||
|
|
formatBytes(space.space_available_size),
|
||
|
|
formatBytes(space.physical_space_size)
|
||
|
|
].join(','));
|
||
|
|
}
|
||
|
|
}
|