Jump to content

File size distribution: Difference between revisions

m
→‎{{header|Haskell}}: fix error conditions with empty or single sets. Skip over various IOExceptions.
m (→‎{{header|Haskell}}: fix non terminating condition)
m (→‎{{header|Haskell}}: fix error conditions with empty or single sets. Skip over various IOExceptions.)
Line 396:
import Control.Concurrent (forkIO, setNumCapabilities)
import Control.Concurrent.Chan (Chan, newChan, readChan, writeChan, writeList2Chan)
import Control.Exception (catch, IOException)
import Control.Monad (filterM, join, replicateM, replicateM_, forever, (>=>))
import Data.Char (isDigit)
import Data.List (sort, genericLength, genericTake, sortBy)
import GHC.Conc (getNumProcessors)
import System.Directory (getDirectoryContents, doesFileExist
, doesDirectoryExist, pathIsSymbolicLink)
import System.Environment (getArgs)
import System.FilePath.Posix (pathSeparator, (</>))
import System.IO (hFileSize, withFile, IOMode(ReadMode), FilePath)
import Text.Printf (printf)
Line 414 ⟶ 415:
 
frequencyGroups :: Int -> [Integer] -> [FrequencyGroup]
frequencyGroups totalGroups_ xs[] = placeGroups xs groupMinMax[]
frequencyGroups totalGroups xs
| length xs == 1 = [((xs !! 0, xs !! 0), 1)]
| otherwise = placeGroups xs groupMinMax
where
range = maximum xs - minimum xs
Line 428 ⟶ 432:
else g
) gs
 
 
fileSizes :: [Item] -> [Integer]
Line 456 ⟶ 459:
 
groupsFromGroup :: Int -> [Integer] -> FrequencyGroup -> [FrequencyGroup]
groupsFromGroup gsize fileSizes ((min, max), count) = frequencyGroups gsize range
| length range > 1 = frequencyGroups gsize range
| otherwise = [((min, max), count)]
where
collectBetween min max = filter (\n -> n >= min && n <= max)
Line 462 ⟶ 467:
 
expandGroups :: Int -> [Integer] -> Integer -> [FrequencyGroup] -> [FrequencyGroup]
expandGroups gsize fileSizes groupThreshold = loop 15
| groupThreshold > 0 = loop 15
| otherwise = id
where
loop 0 gs = gs -- break out in case we can't go below threshold
Line 492 ⟶ 499:
 
collectItems :: FilePath -> IO [Item]
collectItems folderPath = docatch tryCollect
(\e -> do
contents <- fmap (folderPath </>) <$> getDirectoryContents folderPath
let err = show (e :: IOException)
files <- filterM doesFileExist contents
printf "Skipping: %s\n" err
folders <- drop 2 <$> filterM doesDirectoryExist contents
pure []
items <- mapM (\f -> File f <$> withFile f ReadMode hFileSize) files
)
pure $ items <> fmap Folder folders
where
tryCollect = do
contents <- fmap (folderPath </>) <$> getDirectoryContents folderPath
files <- filterM doesFileExist contents
folders <- drop 2 <$> filterM doesDirectoryExist contents
items <- mapM (\f -> File f <$> withFile f ReadMode hFileSize) files
pure $ items <> fmap Folder folders
 
displayFrequency :: Integer -> FrequencyGroup -> IO ()
Anonymous user
Cookies help us deliver our services. By using our services, you agree to our use of cookies.