Implement multi-level tree extractor for hierarchical failure domains
This commit is contained in:
@@ -505,6 +505,7 @@ function put_aligned_pgs(aligned_pgs, int_pgs, prev_int_pgs, keygen)
|
||||
// Convert multi-level osd_tree = { level: number|string, id?: string, size?: number, children?: osd_tree }[]
|
||||
// levels = { string: number }
|
||||
// to a two-level osd_tree suitable for all_combinations()
|
||||
// FIXME: Replace with extract_tree_levels({ level: -Infinity, children: osd_tree }, [ failure_domain_level, osd_level ], levels)
|
||||
function flatten_tree(osd_tree, levels, failure_domain_level, osd_level, domains = {}, i = { i: 1 })
|
||||
{
|
||||
osd_level = levels[osd_level] || osd_level;
|
||||
@@ -539,6 +540,49 @@ function extract_osds(osd_tree, levels, osd_level, osds = {})
|
||||
return osds;
|
||||
}
|
||||
|
||||
// Convert multi-level tree_node = { level: number|string, id?: string, size?: number, children?: tree_node[] }
|
||||
// levels = { string: number }
|
||||
// to a multi-level OSD tree suitable for random_hier_combinations()
|
||||
// (or in case of just 2 levels - for all_combinations() / random_combinations())
|
||||
//
|
||||
// Example:
|
||||
// tree_node = { level: 'dc', children: [ { level: 'rack', children: [ { level: 'host', children: [ { level: 'osd', size: 10 } ] } ] } ] }
|
||||
// extract_levels = [ 'rack', 'osd' ]
|
||||
// level_defs = { dc: 1, rack: 2, host: 3, osd: 4 }
|
||||
//
|
||||
// Result:
|
||||
// { rack0: { osd1: 10 } }
|
||||
function extract_tree_levels(tree_node, extract_levels, level_defs, new_tree = { idx: 1, items: {} })
|
||||
{
|
||||
const next_level = Number(level_defs[extract_levels[0]] || extract_levels[0]) || 0;
|
||||
const level_name = level_defs[extract_levels[0]] ? extract_levels[0] : 'l'+extract_levels[0]+'_';
|
||||
const is_leaf = extract_levels.length == 1;
|
||||
if ((level_defs[tree_node.level] || tree_node.level) >= next_level)
|
||||
{
|
||||
if (!is_leaf)
|
||||
{
|
||||
// Insert a (possibly fake) level
|
||||
const nt = { idx: 1, items: {} };
|
||||
new_tree.items[level_name+(new_tree.idx++)] = nt.items;
|
||||
extract_tree_levels(tree_node, extract_levels.slice(1), level_defs, nt);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Insert a leaf node
|
||||
const leaf_id = tree_node.id || (level_name+(new_tree.idx++));
|
||||
new_tree.items[leaf_id] = tree_node.size;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (const child_node of tree_node.children||[])
|
||||
{
|
||||
extract_tree_levels(child_node, extract_levels, level_defs, new_tree);
|
||||
}
|
||||
}
|
||||
return new_tree.items;
|
||||
}
|
||||
|
||||
// generate random PGs with hierarchical failure domains, i.e. for example 3 DC each with 2 HOSTS
|
||||
// osd_tree = { level3_id: { level2_id: { level1_id: scalar_value } }, ... }
|
||||
// osd_tree may contain arbitrary number of levels, but level count must be the same across the whole tree
|
||||
@@ -853,6 +897,7 @@ module.exports = {
|
||||
pg_list_space_efficiency,
|
||||
pg_per_osd_space_efficiency,
|
||||
flatten_tree,
|
||||
extract_tree_levels,
|
||||
|
||||
lp_solve,
|
||||
make_int_pgs,
|
||||
|
||||
Reference in New Issue
Block a user