Files
buildpath/match_collector/item_tree.ts

89 lines
2.4 KiB
TypeScript

type ItemTree = {
data: any
count: number
children: Array<ItemTree>
};
function treeInit() : ItemTree {
return {data:undefined, count:0, children:[]}
}
function treeNode(data : number, count : number) : ItemTree {
return {data:data, count:count, children:[]}
}
/*
* Merge a node with an item tree
*/
function nodeMerge(itemtree : ItemTree, node : ItemTree) {
const item = node.data;
const count = node.count;
let next : ItemTree | null = null;
// Try to find an existing node in this tree level with same item
for(let node of itemtree.children) {
if(node.data == item) {
node.count += 1;
next = node;
break;
}
}
// If not found, add item node at this level
if(next == null) {
next = treeNode(item, count)
itemtree.children.push(next)
}
return next;
}
/*
* Merge a full build path with an existing item tree
*/
function treeMerge(itemtree : ItemTree, items : Array<number>) {
let current = itemtree;
for(let item of items) {
current = nodeMerge(current, {data: item, count:1, children:[]})
}
}
function treeCutBranches(itemtree : ItemTree, thresholdCount : number, thresholdPerc : number) {
// Remove branches that are above threshold count
while(itemtree.children.length > thresholdCount) {
let leastUsedBranch = itemtree.children.reduce((a, b) => Math.min(a.count, b.count) == a.count ? a : b, {data:undefined, count: +Infinity, children: []})
itemtree.children.splice(itemtree.children.indexOf(leastUsedBranch), 1)
}
// Remove branches that are of too low usage
let toRemove : Array<ItemTree> = []
for(let child of itemtree.children) {
if((child.count/itemtree.count) < thresholdPerc) {
toRemove.push(child)
}
}
for(let tr of toRemove) {
itemtree.children.splice(itemtree.children.indexOf(tr), 1)
}
itemtree.children.map((x) => treeCutBranches(x, thresholdCount, thresholdPerc))
}
function treeMergeTree(itemtree1: ItemTree, itemtree2: ItemTree) {
for(let child of itemtree2.children) {
let node = nodeMerge(itemtree1, child)
treeMergeTree(node, child)
}
}
function treeSort(itemtree: ItemTree) {
itemtree.children.sort((a, b) => b.count - a.count)
for(let item of itemtree.children) {
treeSort(item)
}
}
export {ItemTree, treeMerge, treeInit, treeCutBranches, treeSort}