|
|
@ -140,20 +140,20 @@ function make_int_pgs(weights, pg_count, round_robin) |
|
|
|
return int_pgs; |
|
|
|
} |
|
|
|
|
|
|
|
function calc_intersect_weights(pg_size, pg_count, prev_weights, all_pgs) |
|
|
|
function calc_intersect_weights(old_pg_size, pg_size, pg_count, prev_weights, all_pgs, ordered) |
|
|
|
{ |
|
|
|
const move_weights = {}; |
|
|
|
if ((1 << pg_size) < pg_count) |
|
|
|
if ((1 << old_pg_size) < pg_count) |
|
|
|
{ |
|
|
|
const intersect = {}; |
|
|
|
for (const pg_name in prev_weights) |
|
|
|
{ |
|
|
|
const pg = pg_name.substr(3).split(/_/); |
|
|
|
for (let omit = 1; omit < (1 << pg_size); omit++) |
|
|
|
for (let omit = 1; omit < (1 << old_pg_size); omit++) |
|
|
|
{ |
|
|
|
let pg_omit = [ ...pg ]; |
|
|
|
let intersect_count = pg_size; |
|
|
|
for (let i = 0; i < pg_size; i++) |
|
|
|
let intersect_count = old_pg_size; |
|
|
|
for (let i = 0; i < old_pg_size; i++) |
|
|
|
{ |
|
|
|
if (omit & (1 << i)) |
|
|
|
{ |
|
|
@ -161,6 +161,8 @@ function calc_intersect_weights(pg_size, pg_count, prev_weights, all_pgs) |
|
|
|
intersect_count--; |
|
|
|
} |
|
|
|
} |
|
|
|
if (!ordered) |
|
|
|
pg_omit = pg_omit.filter(n => n).sort(); |
|
|
|
pg_omit = pg_omit.join(':'); |
|
|
|
intersect[pg_omit] = Math.max(intersect[pg_omit] || 0, intersect_count); |
|
|
|
} |
|
|
@ -174,10 +176,10 @@ function calc_intersect_weights(pg_size, pg_count, prev_weights, all_pgs) |
|
|
|
for (let i = 0; i < pg_size; i++) |
|
|
|
{ |
|
|
|
if (omit & (1 << i)) |
|
|
|
{ |
|
|
|
pg_omit[i] = ''; |
|
|
|
} |
|
|
|
} |
|
|
|
if (!ordered) |
|
|
|
pg_omit = pg_omit.filter(n => n).sort(); |
|
|
|
pg_omit = pg_omit.join(':'); |
|
|
|
max_int = Math.max(max_int, intersect[pg_omit] || 0); |
|
|
|
} |
|
|
@ -186,15 +188,18 @@ function calc_intersect_weights(pg_size, pg_count, prev_weights, all_pgs) |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
const prev_pg_hashed = Object.keys(prev_weights).map(pg_name => pg_name.substr(3).split(/_/).reduce((a, c) => { a[c] = 1; return a; }, {})); |
|
|
|
const prev_pg_hashed = Object.keys(prev_weights).map(pg_name => pg_name |
|
|
|
.substr(3).split(/_/).reduce((a, c, i) => { a[c] = i+1; return a; }, {})); |
|
|
|
for (const pg of all_pgs) |
|
|
|
{ |
|
|
|
if (!prev_weights['pg_'+pg.join('_')]) |
|
|
|
{ |
|
|
|
let max_int = 0; |
|
|
|
for (const prev_hash in prev_pg_hashed) |
|
|
|
for (const prev_hash of prev_pg_hashed) |
|
|
|
{ |
|
|
|
const intersect_count = pg.reduce((a, osd) => a + (prev_hash[osd] ? 1 : 0), 0); |
|
|
|
const intersect_count = ordered |
|
|
|
? pg.reduce((a, osd, i) => a + (prev_hash[osd] == 1+i ? 1 : 0), 0) |
|
|
|
: pg.reduce((a, osd, i) => a + (prev_hash[osd] ? 1 : 0), 0); |
|
|
|
if (max_int < intersect_count) |
|
|
|
{ |
|
|
|
max_int = intersect_count; |
|
|
@ -243,7 +248,7 @@ function add_valid_previous(osd_tree, prev_weights, all_pgs) |
|
|
|
} |
|
|
|
|
|
|
|
// 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 }) |
|
|
|
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 }) |
|
|
|
{ |
|
|
|
if (!osd_tree) |
|
|
|
{ |
|
|
@ -266,9 +271,13 @@ async function optimize_change({ prev_pgs: prev_int_pgs, osd_tree, pg_size = 3, |
|
|
|
prev_pg_per_osd[osd].push([ pg_name, (i >= pg_minsize ? parity_space : 1) ]); |
|
|
|
} |
|
|
|
} |
|
|
|
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); |
|
|
|
add_valid_previous(osd_tree, prev_weights, all_pgs); |
|
|
|
if (old_pg_size == pg_size) |
|
|
|
{ |
|
|
|
add_valid_previous(osd_tree, prev_weights, all_pgs); |
|
|
|
} |
|
|
|
all_pgs = Object.values(all_pgs); |
|
|
|
const pg_per_osd = {}; |
|
|
|
for (const pg of all_pgs) |
|
|
@ -282,7 +291,7 @@ async function optimize_change({ prev_pgs: prev_int_pgs, osd_tree, pg_size = 3, |
|
|
|
} |
|
|
|
} |
|
|
|
// Penalize PGs based on their similarity to old PGs
|
|
|
|
const move_weights = calc_intersect_weights(pg_size, pg_count, prev_weights, all_pgs); |
|
|
|
const move_weights = calc_intersect_weights(old_pg_size, pg_size, pg_count, prev_weights, all_pgs, ordered); |
|
|
|
// Calculate total weight - old PG weights
|
|
|
|
const all_pg_names = all_pgs.map(pg => 'pg_'+pg.join('_')); |
|
|
|
const all_pgs_hash = all_pg_names.reduce((a, c) => { a[c] = true; return a; }, {}); |
|
|
|