Skip to content

Instantly share code, notes, and snippets.

@bjin
Last active August 29, 2015 14:14
Show Gist options
  • Save bjin/7d03dd2bdb6c7b891739 to your computer and use it in GitHub Desktop.
Save bjin/7d03dd2bdb6c7b891739 to your computer and use it in GitHub Desktop.
raidz-calc
*.hi
*.o
/calc
import Control.Applicative ((<$>))
import Text.Printf (printf)
import Control.Monad (when)
import System.IO (hFlush, stdout)
prompt :: String -> IO Integer
prompt str = do
putStr $ "Input " ++ str ++ ": "
hFlush stdout
read <$> getLine
ceilDiv :: Integer -> Integer -> Integer
ceilDiv a b = (a + b - 1) `div` b
infixl 7 `ceilDiv`
main = do
blocks <- prompt "recordsize / blocksize (typically 32 or 256)"
raidz_level <- prompt "raidz level (1/2/3)"
when (raidz_level < 1 || raidz_level > 3) $ fail "bad raid level"
disks <- prompt $ "disks (at least " ++ show (raidz_level + 1) ++ ")"
when (disks <= raidz_level) $ fail "bad disks"
let effect_disks = disks - raidz_level
rows = blocks `ceilDiv` effect_disks
needed_blocks' = rows * raidz_level + blocks
needed_blocks = needed_blocks' `ceilDiv` (raidz_level + 1) * (raidz_level + 1)
actual_ratio = fromIntegral blocks / fromIntegral needed_blocks :: Double
ideal_ratio = fromIntegral (disks - raidz_level) / fromIntegral disks :: Double
relative_ratio = (ideal_ratio - actual_ratio) / ideal_ratio
printf "Actual ratio: %.3f%%\n" (actual_ratio * 100)
printf "Relative ratio loss: %.3f%%\n" (relative_ratio * 100)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment