|
|
|
@ -50,7 +50,8 @@ async function lp_solve(text) |
|
|
|
|
return { score, vars }; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
async function optimize_initial({ osd_tree, pg_count, pg_size = 3, pg_minsize = 2, max_combinations = 10000, parity_space = 1, ordered = false }) |
|
|
|
|
async function optimize_initial({ osd_tree, pg_count, pg_size = 3, pg_minsize = 2, hier_sizes = null, |
|
|
|
|
max_combinations = 10000, parity_space = 1, ordered = false, seq_layout = false }) |
|
|
|
|
{ |
|
|
|
|
if (!pg_count || !osd_tree) |
|
|
|
|
{ |
|
|
|
@ -58,7 +59,7 @@ async function optimize_initial({ osd_tree, pg_count, pg_size = 3, pg_minsize = |
|
|
|
|
} |
|
|
|
|
const all_weights = Object.assign({}, ...Object.values(osd_tree)); |
|
|
|
|
const total_weight = Object.values(all_weights).reduce((a, c) => Number(a) + Number(c), 0); |
|
|
|
|
const all_pgs = Object.values(random_combinations(osd_tree, pg_size, max_combinations, parity_space > 1)); |
|
|
|
|
const all_pgs = Object.values(random_hier_combinations(osd_tree, hier_sizes || [ pg_size, 1 ], max_combinations, parity_space > 1, seq_layout)); |
|
|
|
|
const pg_per_osd = {}; |
|
|
|
|
for (const pg of all_pgs) |
|
|
|
|
{ |
|
|
|
@ -216,39 +217,45 @@ function calc_intersect_weights(old_pg_size, pg_size, pg_count, prev_weights, al |
|
|
|
|
return move_weights; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function add_valid_previous(osd_tree, prev_weights, all_pgs) |
|
|
|
|
function build_parent_per_leaf(osd_tree, res = {}, parents = []) |
|
|
|
|
{ |
|
|
|
|
// Add previous combinations that are still valid
|
|
|
|
|
const hosts = Object.keys(osd_tree).sort(); |
|
|
|
|
const host_per_osd = {}; |
|
|
|
|
for (const host in osd_tree) |
|
|
|
|
for (const item in osd_tree) |
|
|
|
|
{ |
|
|
|
|
for (const osd in osd_tree[host]) |
|
|
|
|
{ |
|
|
|
|
host_per_osd[osd] = host; |
|
|
|
|
} |
|
|
|
|
if (osd_tree[item] instanceof Object) |
|
|
|
|
build_parent_per_leaf(osd_tree[item], res, [ ...parents, item ]); |
|
|
|
|
else |
|
|
|
|
res[item] = parents; |
|
|
|
|
} |
|
|
|
|
return res; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function add_valid_previous(osd_tree, prev_weights, all_pgs, hier_sizes) |
|
|
|
|
{ |
|
|
|
|
// Add previous combinations that are still valid
|
|
|
|
|
const parent_per_osd = build_parent_per_leaf(osd_tree); |
|
|
|
|
skip_pg: for (const pg_name in prev_weights) |
|
|
|
|
{ |
|
|
|
|
const seen_hosts = {}; |
|
|
|
|
const seen = []; |
|
|
|
|
const pg = pg_name.substr(3).split(/_/); |
|
|
|
|
for (const osd of pg) |
|
|
|
|
{ |
|
|
|
|
if (!host_per_osd[osd] || seen_hosts[host_per_osd[osd]]) |
|
|
|
|
{ |
|
|
|
|
if (!parent_per_osd[osd]) |
|
|
|
|
continue skip_pg; |
|
|
|
|
for (let i = 0; i < parent_per_osd[osd].length; i++) |
|
|
|
|
{ |
|
|
|
|
seen[parent_per_osd[osd][i]]++; |
|
|
|
|
if (seen[parent_per_osd[osd][i]] > hier_sizes[i]) |
|
|
|
|
continue skip_pg; |
|
|
|
|
} |
|
|
|
|
seen_hosts[host_per_osd[osd]] = true; |
|
|
|
|
} |
|
|
|
|
if (!all_pgs[pg_name]) |
|
|
|
|
{ |
|
|
|
|
all_pgs[pg_name] = pg; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Try to minimize data movement
|
|
|
|
|
async function optimize_change({ prev_pgs: prev_int_pgs, osd_tree, pg_size = 3, pg_minsize = 2, max_combinations = 10000, parity_space = 1, ordered = false }) |
|
|
|
|
async function optimize_change({ prev_pgs: prev_int_pgs, osd_tree, pg_size = 3, pg_minsize = 2, |
|
|
|
|
hier_sizes = null, max_combinations = 10000, parity_space = 1, ordered = false, seq_layout = false }) |
|
|
|
|
{ |
|
|
|
|
if (!osd_tree) |
|
|
|
|
{ |
|
|
|
@ -273,10 +280,10 @@ async function optimize_change({ prev_pgs: prev_int_pgs, osd_tree, pg_size = 3, |
|
|
|
|
} |
|
|
|
|
const old_pg_size = prev_int_pgs[0].length; |
|
|
|
|
// Get all combinations
|
|
|
|
|
let all_pgs = random_combinations(osd_tree, pg_size, max_combinations, parity_space > 1); |
|
|
|
|
let all_pgs = random_hier_combinations(osd_tree, hier_sizes || [ pg_size, 1 ], max_combinations, parity_space > 1, seq_layout); |
|
|
|
|
if (old_pg_size == pg_size) |
|
|
|
|
{ |
|
|
|
|
add_valid_previous(osd_tree, prev_weights, all_pgs); |
|
|
|
|
add_valid_previous(osd_tree, prev_weights, all_pgs, hier_sizes || [ pg_size, 1 ]); |
|
|
|
|
} |
|
|
|
|
all_pgs = Object.values(all_pgs); |
|
|
|
|
const pg_per_osd = {}; |
|
|
|
|