calculator.127local.net/public/calculators/raid.js
2025-09-01 16:06:47 -07:00

32 lines
1.8 KiB
JavaScript

import {fmt, revive, persist, labelInput, labelSelect} from '/js/util.js';
export default {
id:'raid', name:'RAID Usable Capacity', about:'Estimates only; assumes identical drives. Controller/FS overhead not included.',
render(root){
const key='calc_raid_v1';
const s = revive(key,{level:'5', drives:6, size:18});
const ui = document.createElement('div');
ui.append(
labelSelect('RAID level','level', s.level, [['0','RAID 0 (stripe)'],['1','RAID 1 (mirror)'],['5','RAID 5 (1 disk parity)'],['6','RAID 6 (2 disk parity)'],['10','RAID 10 (mirror+stripe)']]),
labelInput('Number of drives','number','drives', s.drives,{min:'1',step:'1'}),
labelInput('Drive size (TB, decimal)','number','size', s.size,{min:'0',step:'0.01'})
);
const out = document.createElement('div'); out.className='result'; ui.append(out);
function calc(){
const L = ui.querySelector('[name=level]').value;
const N = Math.max(1, parseInt(ui.querySelector('[name=drives]').value||0,10));
const S = (+ui.querySelector('[name=size]').value||0) * 1e12;
let usable=0, ft='';
if(L==='0'){ usable = N*S; ft='0 disk'; }
else if(L==='1'){ usable = Math.floor(N/2)*S; ft='can lose all but 1 in each mirror pair'; }
else if(L==='5'){ usable = (N-1)*S; ft='1 disk'; }
else if(L==='6'){ usable = (N-2)*S; ft='2 disks'; }
else if(L==='10'){ usable = Math.floor(N/2)*S; ft='1 disk per mirror pair'; }
const teb = usable / (1024**4);
const tb = usable / 1e12;
out.innerHTML = `<div><strong>Usable:</strong> ${fmt.format(tb)} TB · ${fmt.format(teb)} TiB</div><div class="muted">Fault tolerance: ${ft}</div>`;
persist(key,{level:L, drives:N, size:+ui.querySelector('[name=size]').value});
}
ui.addEventListener('input', calc); calc(); root.append(ui);
}
}