@eagleoutice/flowr
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
102 lines • 5.13 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.postProcessFeatureFolder = postProcessFeatureFolder;
exports.printClusterReport = printClusterReport;
const path_1 = __importDefault(require("path"));
const fs_1 = __importDefault(require("fs"));
const clusterer_1 = require("./clusterer");
const log_1 = require("../../../util/log");
const defaultmap_1 = require("../../../util/collections/defaultmap");
const ansi_1 = require("../../../util/text/ansi");
const feature_1 = require("../../features/feature");
const decorate_1 = require("../../../r-bridge/lang-4.x/ast/model/processing/decorate");
const file_provider_1 = require("../../output/file-provider");
const arrays_1 = require("../../../util/collections/arrays");
/**
* Post process the collections in a given folder, reducing them in a memory preserving way.
* @param filepath - Path to the root file of the data collection like `statistics-out/top-2023-01-01-00-00-00/`
* @param features - Collection of features to post process, expects corresponding folders to exist
* @returns non-aggregated reports for each sub-key of each feature
*/
function postProcessFeatureFolder(filepath, features) {
if (!fs_1.default.existsSync(filepath)) {
log_1.log.warn(`Folder for ${filepath} does not exist, skipping post processing`);
return [];
}
const results = [];
for (const feature of features) {
const result = processFeatureFolder(filepath, feature);
if (result.length > 0) {
results.push(...result);
}
}
return results;
}
/**
* Process a single feature folder like `Assignments/`
* @param filepath - Same as the input to {@link postProcessFeatureFolder}
* @param feature - The (single) feature to process
*/
function processFeatureFolder(filepath, feature) {
const featureInfo = feature_1.ALL_FEATURES[feature];
const targetPath = path_1.default.join(filepath, featureInfo.name);
if (!fs_1.default.existsSync(targetPath)) {
log_1.log.warn(`Folder for ${feature} does not exist at ${targetPath} skipping post processing of this feature`);
return [];
}
log_1.log.info(`Processing ${feature} at ${targetPath}`);
const contextIdMap = new defaultmap_1.DefaultMap((0, decorate_1.deterministicCountingIdGenerator)());
const featureSubKeys = Object.keys(featureInfo.initialValue);
const reports = [];
for (const subKey of featureSubKeys) {
const value = processFeatureSubKey(targetPath, subKey, contextIdMap);
if (value !== undefined) {
reports.push(value);
}
}
return reports;
}
function processFeatureSubKey(featurePath, subKey, contextIdMap) {
const targetPath = path_1.default.join(featurePath, `${subKey}${file_provider_1.defaultStatisticsFileSuffix}`);
if (!fs_1.default.existsSync(targetPath)) {
log_1.log.warn(`Folder for ${subKey} does not exist at ${targetPath} skipping post processing of this key`);
return undefined;
}
return (0, clusterer_1.clusterStatisticsOutput)(targetPath, contextIdMap);
}
/**
* Prints the report to the console, but limits the output to the `limit` entries with the highest counts.
* The names of these entries (like `->`) are returned, so they can be used to filter the following histograms.
*/
function printClusterReport(report, limit = 1000) {
console.log('\n\n\n');
console.log(report.filepath);
const shortStats = [...report.valueInfoMap.entries()].map(([name, values]) => {
return {
name,
count: (0, arrays_1.arraySum)([...values.values()]),
unique: values.size()
};
}).sort((a, b) => b.count - a.count).slice(0, limit);
const { longestName, longestCount, longestUnique } = shortStats.reduce((acc, { name, count, unique }) => {
return {
longestName: Math.max(acc.longestName, name.length),
longestCount: Math.max(acc.longestCount, count.toLocaleString().length),
longestUnique: Math.max(acc.longestUnique, unique.toLocaleString().length),
};
}, { longestName: 0, longestCount: 0, longestUnique: 0 });
for (const { name, count, unique } of shortStats) {
const strId = `${name}`.padEnd(longestName, ' ');
const strCount = count.toLocaleString().padStart(longestCount, ' ');
const strUnique = unique.toLocaleString().padStart(longestUnique, ' ');
const uniqueSuffix = `\t (${strUnique} ${ansi_1.formatter.format('unique', { color: 7 /* Colors.White */, effect: ansi_1.ColorEffect.Foreground })})`;
console.log(`\t${ansi_1.formatter.format(strId, { style: 1 /* FontStyles.Bold */ })}\t ${strCount} ` +
`${ansi_1.formatter.format('total', { color: 7 /* Colors.White */, effect: ansi_1.ColorEffect.Foreground })}`
+ (count !== unique ? uniqueSuffix : ''));
}
return shortStats.map(({ name }) => name);
}
//# sourceMappingURL=post-process-output.js.map