squeeze 1.0.4.2 → 1.0.4.4
raw patch · 15 files changed
+82/−77 lines, 15 filessetup-changed
Files
- Setup.hs +2/−2
- changelog +6/−2
- debian/DEBIAN/control +4/−3
- makefile +2/−2
- squeeze.cabal +4/−4
- squeeze.spec +2/−2
- src/Main.hs +10/−10
- src/Squeeze/Control/Concurrent/DivideAndConquer.hs +2/−1
- src/Squeeze/Data/CommandOptions.hs +9/−10
- src/Squeeze/Data/File.hs +7/−8
- src/Squeeze/Squeeze.hs +15/−16
- src/Squeeze/Test/Data/CommandOptions.hs +4/−3
- src/Squeeze/Test/Data/FileCombinations.hs +6/−5
- src/Squeeze/Test/Performance.hs +6/−6
- src/Squeeze/Test/Squeeze.hs +3/−3
Setup.hs view
@@ -1,5 +1,5 @@ #!/usr/bin/env runhaskell -import qualified Distribution.Simple+import qualified Distribution.Simple -main = Distribution.Simple.defaultMain+main = Distribution.Simple.defaultMain
changelog view
@@ -93,5 +93,9 @@ 1.0.4.2 * Improved the syntax of 'verbosity' in the usage-message. * Tested with 'haskell-platform-2013.2.0.0'.- * Added a function 'Data.CommandOptions.subtractFile' to adjust 'Data.CommandOptions.CommandOptions', after removing a file from the problem; previously done incorrectly.-+ * Added a function 'Data.CommandOptions.subtractFile' to adjust 'Data.CommandOptions.CommandOptions' after removing a file from the problem; previously done incorrectly, causing an error when running with '+RTS -N2'.+1.0.4.3+ * Changed the value of '0/0' to '0' rather than '1' in 'Data.CommandOptions.subtractFile'.+1.0.4.4+ * Either replaced instances of '(<$>)' with 'fmap' to avoid ambiguity between "Control.Applicative" & "Prelude" which (from 'base-4.8') also exports this symbol, or hid the symbol when importing the "Prelude"..+ * In module "Main", redirected version-message to stderr.
debian/DEBIAN/control view
@@ -1,10 +1,11 @@ Package: squeeze-Version: 1.0.4.2-1+Version: 1.0.4.4-1 Section: utils Priority: optional-Architecture: i386+#Architecture: i386+Architecture: amd64 Depends: libc6-Installed-size: 1825+Installed-size: 2448 Maintainer: Dr. Alistair Ward <squeeze at functionalley dot eu> Provides: Homepage: http://functionalley.eu
makefile view
@@ -1,4 +1,4 @@-# Copyright (C) 2010 Dr. Alistair Ward+# Copyright (C) 2010-2014 Dr. Alistair Ward # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by@@ -45,7 +45,7 @@ @$@ -i 'Reduce duplication' src/ +RTS -N sdist:- runhaskell Setup $@+ TAR_OPTIONS='--format=ustar' runhaskell Setup $@ check: sdist cabal upload --check --verbose=3 dist/*.tar.gz;
squeeze.cabal view
@@ -1,8 +1,8 @@ -- Package-properties Name: squeeze-Version: 1.0.4.2+Version: 1.0.4.4 Cabal-Version: >= 1.6-Copyright: (C) 2010-2014 Dr. Alistair Ward+Copyright: (C) 2010-2015 Dr. Alistair Ward License: GPL License-file: LICENSE Author: Dr. Alistair Ward@@ -11,7 +11,7 @@ Build-Type: Simple Description: Returns progressively better subsets of the specified files, selected to fit into a limited space, without wasting more than the specific ratio. Category: Utils-Tested-With: GHC == 7.4, GHC == 7.6+Tested-With: GHC == 7.4, GHC == 7.6, GHC == 7.10 Homepage: http://functionalley.eu Maintainer: squeeze <at> functionalley <dot> eu Bug-reports: squeeze <at> functionalley <dot> eu@@ -56,7 +56,7 @@ toolshed >= 0.14, unix - GHC-options: -Wall -O2+ GHC-options: -Wall -O2 -fno-warn-tabs if impl(ghc >= 7.4.1) GHC-prof-options: -prof -fprof-auto -fprof-cafs
squeeze.spec view
@@ -1,4 +1,4 @@-# Copyright (C) 2012-2013 Dr. Alistair Ward+# Copyright (C) 2012-2014 Dr. Alistair Ward # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by@@ -22,7 +22,7 @@ Summary: Finds the optimal subset of the specified files, to fit into a limited space, with minimal wastage Name: squeeze-Version: 1.0.4.2+Version: 1.0.4.4 Release: 1 License: GPLv3 #From '/usr/share/doc/packages/rpm/GROUPS'.
src/Main.hs view
@@ -1,5 +1,5 @@ {-- Copyright (C) 2010-2013 Dr. Alistair Ward+ Copyright (C) 2010-2015 Dr. Alistair Ward This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by@@ -28,6 +28,7 @@ module Main(main) where +import Prelude hiding ((<$>), (<*>)) -- The "Prelude" from 'base-4.8' exports this symbol. import Control.Applicative((<*>), (<$>)) import qualified Control.Monad import qualified Control.Monad.Writer@@ -39,7 +40,7 @@ import qualified Distribution.Verbosity import qualified Distribution.Version import qualified Factory.Math.Probability-import qualified Paths_squeeze as Paths --Either local stub, or package-instance autogenerated by 'Setup.hs build'.+import qualified Paths_squeeze as Paths -- Either local stub, or package-instance autogenerated by 'Setup.hs build'. import qualified Squeeze.Data.CommandOptions as Data.CommandOptions import qualified Squeeze.Data.File as Data.File import qualified Squeeze.Squeeze as Squeeze@@ -58,10 +59,10 @@ import qualified ToolShed.System.TimeAction -- | Coerce the polymorphic data-type to concrete instance, in order that it's fields may be read from the command-line.-type CommandOptions' = Data.CommandOptions.CommandOptions Rational --'Double' would also be a suitable type-parameter.+type CommandOptions' = Data.CommandOptions.CommandOptions Rational -- 'Double' would also be a suitable type-parameter. -- | Used to thread user-defined command-line options, though the list of functions which implement them.-type CommandLineAction = CommandOptions' -> IO CommandOptions' --Supplied as the type-argument to 'G.OptDescr'.+type CommandLineAction = CommandOptions' -> IO CommandOptions' -- Supplied as the type-argument to 'G.OptDescr'. -- | On failure to parse the specified string, returns an explanatory error. read' :: Read a => String -> String -> a@@ -164,16 +165,15 @@ runQuickChecks _ = Test.QuickChecks.run >> System.Exit.exitWith System.Exit.ExitSuccess printVersion, printUsage :: IO (Data.CommandOptions.CommandOptions f)- printVersion = Text.Printf.printf "%s\n\n%s %s.\n%s.\n%s.\n%s %s.\n" packageName "Copyright (C) 2010-2013" author "This program comes with ABSOLUTELY NO WARRANTY" "This is free software, & you are welcome to redistribute it under certain conditions" "Written by" author >> System.Exit.exitWith System.Exit.ExitSuccess where+ printVersion = System.IO.hPutStrLn System.IO.stderr (Distribution.Text.display packageIdentifier ++ "\n\nCopyright (C) 2010-2015 " ++ author ++ ".\nThis program comes with ABSOLUTELY NO WARRANTY.\nThis is free software, and you are welcome to redistribute it under certain conditions.\n\nWritten by " ++ author ++ ".") >> System.Exit.exitWith System.Exit.ExitSuccess where packageIdentifier :: Distribution.Package.PackageIdentifier packageIdentifier = Distribution.Package.PackageIdentifier {- Distribution.Package.pkgName = Distribution.Package.PackageName progName, --CAVEAT: coincidentally.+ Distribution.Package.pkgName = Distribution.Package.PackageName progName, -- CAVEAT: coincidentally. Distribution.Package.pkgVersion = Distribution.Version.Version (Data.Version.versionBranch Paths.version) [] } - packageName, author :: String- packageName = Distribution.Text.display packageIdentifier- author = "Dr. Alistair Ward"+ author :: String+ author = "Dr. Alistair Ward" printUsage = Text.Printf.hPrintf System.IO.stderr "Usage:\t%s %s\n\nEBNF argument-format:\n\t%-22s = %s;\n\t%-22s = %s;\n\t%-22s = %s;\n\t%-22s = %s;\n\t%-22s = %s;\n\t%-22s = %s;\n\t%-22s = %s;\n\t%-22s = %s;\n\t%-22s = %s;\n\nE.g.\n\t%s\n\t%s\n\t%s\n" ( G.usageInfo progName optDescrList@@ -194,7 +194,7 @@ (commandLineActions, nonOptions, [{-errors-}]) -> do commandOptions <- Data.List.foldl' (>>=) ( return {-to IO-monad-} ToolShed.Defaultable.defaultValue- ) {-transform using CommandLineAction-mutators-} commandLineActions --ie: do o1 <- CommandLineAction[0] commandOptions[0]; o2 <- CommandLineAction[1] o1; ...+ ) {-transform using CommandLineAction-mutators-} commandLineActions -- ie: do o1 <- CommandLineAction[0] commandOptions[0]; o2 <- CommandLineAction[1] o1; ... if not $ ToolShed.SelfValidate.isValid commandOptions then fail $ ToolShed.SelfValidate.getFirstError commandOptions
src/Squeeze/Control/Concurrent/DivideAndConquer.hs view
@@ -1,5 +1,5 @@ {-- Copyright (C) 2013 Dr. Alistair Ward+ Copyright (C) 2013-2015 Dr. Alistair Ward This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by@@ -33,6 +33,7 @@ divideAndConquer ) where +import Prelude hiding ((<$>), (<*>)) -- The "Prelude" from 'base-4.8' exports this symbol. import Control.Applicative((<*>), (<$>)) import qualified Control.Concurrent import qualified Control.Concurrent.Chan
src/Squeeze/Data/CommandOptions.hs view
@@ -1,5 +1,5 @@ {-- Copyright (C) 2010 Dr. Alistair Ward+ Copyright (C) 2010-2014 Dr. Alistair Ward This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by@@ -64,9 +64,9 @@ instance Fractional f => ToolShed.Defaultable.Defaultable (CommandOptions f) where defaultValue = MkCommandOptions { getIncludeEmpty = False,- getMaximumBytes = 4700000000, --DVD-size; just under 4.4GiB.+ getMaximumBytes = 4700000000, -- DVD-size; just under 4.4GiB. getMaybeRandomSeed = Nothing,- getMinimumUsageRatio = 99 / 100, --99% full.+ getMinimumUsageRatio = 99 / 100, -- 99% full. getVerbosity = Distribution.Verbosity.normal } @@ -80,8 +80,8 @@ -- | Smart constructor. mkCommandOptions :: (- Ord ratio,- Real ratio+ Ord ratio,+ Real ratio ) => Bool -> Data.File.FileSize@@ -108,14 +108,13 @@ subtractFile fileSize commandOptions | fileSize < 0 = error $ "Squeeze.Data.CommandOptions.subtractFile:\tnegative file-size=" ++ show fileSize | maximumBytes' < 0 = error $ "Squeeze.Data.CommandOptions.subtractFile:\tfile-size=" ++ show fileSize ++ " > maximum=" ++ show maximumBytes- | maximumBytes' == 0 = commandOptions {- getMaximumBytes = 0,- getMinimumUsageRatio = 1 -- CAVEAT: calculation below would yield 0 / 0.- } | otherwise = commandOptions { getMaximumBytes = maximumBytes',- getMinimumUsageRatio = fromIntegral (max 0 $ deriveMinimumBytes commandOptions - fromIntegral fileSize) / fromIntegral maximumBytes'+ getMinimumUsageRatio = if maximumBytes' == 0+ then 0 -- CAVEAT: the calculation below would otherwise attempt to evaluate 0 / 0.+ else fromIntegral (max 0 $ deriveMinimumBytes commandOptions - fileSize) / fromIntegral maximumBytes' } where+ maximumBytes, maximumBytes' :: Data.File.FileSize maximumBytes = getMaximumBytes commandOptions maximumBytes' = maximumBytes - fileSize
src/Squeeze/Data/File.hs view
@@ -1,5 +1,5 @@ {-- Copyright (C) 2010-2013 Dr. Alistair Ward+ Copyright (C) 2010-2015 Dr. Alistair Ward This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by@@ -44,7 +44,6 @@ hasSizeBy ) where -import Control.Applicative((<$>)) import Control.Arrow((&&&)) import qualified Control.Monad import qualified Control.Monad.Writer@@ -61,7 +60,7 @@ type FilePathList = [System.IO.FilePath] -- | A type-synonym specifically to hold file-sizes (in bytes).-type FileSize = Integer --Matches the return-type of 'IO.hFileSize'.+type FileSize = Integer -- Matches the return-type of 'IO.hFileSize'. -- | A type suitable for containing a file-path, qualified by the corresponding 'FileSize'. type FileSizeAndPath = (FileSize, System.IO.FilePath)@@ -93,15 +92,15 @@ -} expandDirectory :: System.IO.FilePath -> IO FilePathList expandDirectory filePath = do- stat <- System.Posix.Files.getFileStatus filePath --CAVEAT: throws if the user is unauthorised, or the file is non-existent.+ stat <- System.Posix.Files.getFileStatus filePath -- CAVEAT: throws if the user is unauthorised, or the file is non-existent. if System.Posix.Files.isDirectory stat then System.Directory.getDirectoryContents filePath >>= fmap concat . mapM ( expandDirectory {-recurse-} . (filePath </>) {-qualify the path-} ) . filter (- `notElem` [".", ".."] --Prevent infinite recursion.+ `notElem` [".", ".."] -- Prevent infinite recursion. )- else {-non-directory-} return {-to IO-monad-} [filePath] --CAVEAT: this could include devices, pipes, sockets, symlinks ...+ else {-non-directory-} return {-to IO-monad-} [filePath] -- CAVEAT: this could include devices, pipes, sockets, symlinks ... {- | * Finds any file-paths which have been specified more than once.@@ -117,11 +116,11 @@ * CAVEAT: the size of a symlink, is that of the file to which it refers. -} findSize :: System.IO.FilePath -> IO FileSize-findSize filePath = expandDirectory filePath >>= fmap aggregateSize . mapM (\f -> flip (,) f <$> System.IO.withFile f System.IO.ReadMode System.IO.hFileSize)+findSize filePath = expandDirectory filePath >>= fmap aggregateSize . mapM (\f -> flip (,) f `fmap` System.IO.withFile f System.IO.ReadMode System.IO.hFileSize) -- | Finds file-sizes. findSizes :: FilePathList -> IO [FileSizeAndPath]-findSizes = uncurry (<$>) . (flip zip &&& mapM findSize)+findSizes = uncurry fmap . (flip zip &&& mapM findSize) -- | Sorts a list of 'FileSizeAndPath' by increasing size; ie. smallest first. orderByIncreasingSize :: [FileSizeAndPath] -> [FileSizeAndPath]
src/Squeeze/Squeeze.hs view
@@ -1,5 +1,5 @@ {-- Copyright (C) 2010-2013 Dr. Alistair Ward+ Copyright (C) 2010-2015 Dr. Alistair Ward This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by@@ -35,7 +35,6 @@ partitionEmptyFilesAndDistributeAndFindBestFit ) where -import Control.Applicative((<$>)) import qualified Control.Arrow import Control.Arrow((&&&)) import qualified Control.Concurrent@@ -70,16 +69,16 @@ ) . ( Data.FileCombination.nullFileCombination : ) . nonEmptyCombinations minimumCombinationSize . uncurry zip . (- id &&& Data.File.accumulateSize --Associate the list of possible files with its accumulating size.+ id &&& Data.File.accumulateSize -- Associate the list of possible files with its accumulating size. ) . dropWhile (- Data.File.hasSizeBy (> maximumCombinationSize) --Remove files which individually exceed the maximum permissible; assuming they've been sorted by decreasing size.+ Data.File.hasSizeBy (> maximumCombinationSize) -- Remove files which individually exceed the maximum permissible; assuming they've been sorted by decreasing size. ) where nonEmptyCombinations :: Data.File.FileSize -> [(Data.File.FileSizeAndPath, Data.File.FileSize)] -> [Data.FileCombination.FileCombination] nonEmptyCombinations _ [] = [] nonEmptyCombinations minimumBytes ((fileSizeAndPath, aggregateSize) : remainder)- | aggregateSize < minimumBytes = [] --Even if all the files are selected, the minimum-size criterion won't be satisfied.+ | aggregateSize < minimumBytes = [] -- Even if all the files are selected, the minimum-size criterion won't be satisfied. | otherwise = Data.FileCombination.singleton fileSizeAndPath : foldr binaryChoice [] (- nonEmptyCombinations (minimumBytes - Data.File.getSize fileSizeAndPath) remainder --Recurse.+ nonEmptyCombinations (minimumBytes - Data.File.getSize fileSizeAndPath) remainder -- Recurse. ) where binaryChoice :: Data.FileCombination.FileCombination -> [Data.FileCombination.FileCombination] -> [Data.FileCombination.FileCombination]@@ -120,22 +119,22 @@ in do Control.Monad.when (Data.CommandOptions.getVerbosity commandOptions' == maxBound) . System.IO.hPutStrLn System.IO.stderr $ "INFO: acceptable file-size interval " ++ show solutionSizeBounds ++ " bytes." - return {-to IO-monad-} $ findBestFit solutionSizeBounds increasingFileSizeAndPathList --Delegate the task to the single-threaded algorithm.+ return {-to IO-monad-} $ findBestFit solutionSizeBounds increasingFileSizeAndPathList -- Delegate the task to the single-threaded algorithm. slave numCapabilities' commandOptions' (selectedFileSizeAndPath {-the smallest-} : remainingFileSizeAndPaths) = let- recurse = slave $ numCapabilities' `div` 2 --Partially apply.+ recurse = slave $ numCapabilities' `div` 2 -- Partially apply. in do Control.Monad.when (Data.CommandOptions.getVerbosity commandOptions' == maxBound) . System.IO.hPutStrLn System.IO.stderr $ "INFO: " ++ show numCapabilities' ++ " CPU-cores => bisecting task into those, with & without " ++ show selectedFileSizeAndPath ++ "." - fileCombinationsExcludingSelected <- recurse commandOptions' {-i.e the original space-} remainingFileSizeAndPaths --This is about half the total task.+ fileCombinationsExcludingSelected <- recurse commandOptions' {-i.e the original space-} remainingFileSizeAndPaths -- This is about half the total task. - let - commandOptions'' = Data.CommandOptions.subtractFile (Data.File.getSize selectedFileSizeAndPath) commandOptions' --Reduce the requirements by the size of the selected file.+ let+ commandOptions'' = Data.CommandOptions.subtractFile (Data.File.getSize selectedFileSizeAndPath) commandOptions' -- Reduce the requirements by the size of the selected file. if Data.CommandOptions.getMaximumBytes commandOptions'' < 0- then return {-to IO-monad-} fileCombinationsExcludingSelected --The selected file won't fit.+ then return {-to IO-monad-} fileCombinationsExcludingSelected -- The selected file won't fit. else map (- Data.FileCombination.prepend selectedFileSizeAndPath --Prepend the selected file to all file-combinations.- ) <$> recurse commandOptions'' remainingFileSizeAndPaths >>= Control.Concurrent.DivideAndConquer.divideAndConquer Data.FileCombination.risingMergeByAggregateFileSize fileCombinationsExcludingSelected --Merge the part-solutions.+ Data.FileCombination.prepend selectedFileSizeAndPath -- Prepend the selected file to all file-combinations.+ ) `fmap` recurse commandOptions'' remainingFileSizeAndPaths >>= Control.Concurrent.DivideAndConquer.divideAndConquer Data.FileCombination.risingMergeByAggregateFileSize fileCombinationsExcludingSelected -- Merge the part-solutions. in Control.Concurrent.getNumCapabilities >>= (\numCapabilities -> slave numCapabilities commandOptions $ Data.File.orderByIncreasingSize fileSizeAndPathList) {- |@@ -161,7 +160,7 @@ Data.FileCombination.getFilePathList = emptyFilePathCombination ++ Data.FileCombination.getFilePathList fileCombination } ) $ Data.List.subsequences {-find all combinations-} emptyFiles- ) <$> nonEmptyFileCombinations+ ) `fmap` nonEmptyFileCombinations | otherwise {-exclude empty files-} = do Control.Monad.unless (Data.CommandOptions.getVerbosity commandOptions == minBound || null emptyFiles) . System.IO.hPutStrLn System.IO.stderr $ "WARNING: rejecting empty files; " ++ show emptyFiles ++ "." @@ -173,5 +172,5 @@ where printStatistics l = Control.Monad.unless (Data.CommandOptions.getVerbosity commandOptions == minBound || null l) . System.IO.hPutStrLn System.IO.stderr $ "INFO: file-(count, aggregate size, mean, standard-deviation); " ++ show (Data.File.getFileSizeStatistics l :: (Int, Data.File.FileSize, Float, Float)) ++ "." (emptyFiles, nonEmptyFilePathAndSizeList) = Control.Arrow.first (map Data.File.getPath) $ Data.List.partition (Data.File.hasSizeBy (== 0)) fileSizeAndPathList- nonEmptyFileCombinations = distributeAndFindBestFit commandOptions nonEmptyFilePathAndSizeList --Delegate.+ nonEmptyFileCombinations = distributeAndFindBestFit commandOptions nonEmptyFilePathAndSizeList -- Delegate.
src/Squeeze/Test/Data/CommandOptions.hs view
@@ -1,6 +1,6 @@ {-# OPTIONS_GHC -fno-warn-orphans #-} {-- Copyright (C) 2013 Dr. Alistair Ward+ Copyright (C) 2013-2015 Dr. Alistair Ward This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by@@ -27,6 +27,7 @@ CommandOptions ) where +import Prelude hiding ((<$>), (<*>)) -- The "Prelude" from 'base-4.8' exports this symbol. import Control.Applicative((<$>), (<*>)) import qualified Test.QuickCheck import qualified Squeeze.Data.CommandOptions as Data.CommandOptions@@ -40,9 +41,9 @@ Test.QuickCheck.Arbitrary ratio ) => Test.QuickCheck.Arbitrary (Data.CommandOptions.CommandOptions ratio) where arbitrary = Data.CommandOptions.mkCommandOptions <$> Test.QuickCheck.arbitrary {-includeEmpty-} <*> (- abs <$> Test.QuickCheck.arbitrary --maximumBytes.+ abs <$> Test.QuickCheck.arbitrary -- maximumBytes. ) <*> Test.QuickCheck.arbitrary {-maybeRandomSeed-} <*> (- recip . succ . abs <$> Test.QuickCheck.arbitrary --minimumUsageRatio.+ recip . succ . abs <$> Test.QuickCheck.arbitrary -- minimumUsageRatio. ) <*> Test.QuickCheck.arbitrary {-verbosity-} -- | Defines a concrete type for testing.
src/Squeeze/Test/Data/FileCombinations.hs view
@@ -1,6 +1,6 @@ {-# OPTIONS_GHC -fno-warn-orphans #-} {-- Copyright (C) 2010 Dr. Alistair Ward+ Copyright (C) 2010-2015 Dr. Alistair Ward This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by@@ -26,7 +26,6 @@ quickChecks ) where -import Control.Applicative((<$>)) import Control.Arrow((&&&)) import qualified Data.List import qualified Squeeze.Data.FileCombination as Data.FileCombination@@ -34,8 +33,8 @@ instance Test.QuickCheck.Arbitrary Data.FileCombination.FileCombination where arbitrary = do- filePathList <- Data.List.nub <$> (Test.QuickCheck.elements [0 .. 99] >>= Test.QuickCheck.vector)- aggregateFileSize <- Test.QuickCheck.elements [0 .. Data.List.genericLength filePathList] --Assume files of size either zero or one byte.+ filePathList <- Data.List.nub `fmap` (Test.QuickCheck.elements [0 .. 99] >>= Test.QuickCheck.vector)+ aggregateFileSize <- Test.QuickCheck.elements [0 .. Data.List.genericLength filePathList] -- Assume files of size either zero or one byte. return $ Data.FileCombination.mkFileCombination aggregateFileSize filePathList @@ -46,4 +45,6 @@ prop_risingFilter = Test.QuickCheck.label "prop_risingFilter" . uncurry (==) . (id &&& Data.List.sort) . map Data.FileCombination.getAggregateFileSize . Data.FileCombination.risingFilter 0 prop_risingFilter' = Test.QuickCheck.label "prop_risingFilter'" . uncurry (==) . (id &&& Data.FileCombination.risingFilter 0) . Data.List.sortBy Data.FileCombination.comparingAggregateFileSize - prop_risingMergeByAggregateFileSize = Test.QuickCheck.label "prop_risingMergeByAggregateFileSize" . uncurry (==) . (id &&& map head . Data.List.group . uncurry Data.FileCombination.risingMergeByAggregateFileSize . (id &&& id)) . Data.FileCombination.risingFilter 0+ prop_risingMergeByAggregateFileSize = Test.QuickCheck.label "prop_risingMergeByAggregateFileSize" . uncurry (==) . (+ id &&& map head . Data.List.group . uncurry Data.FileCombination.risingMergeByAggregateFileSize . (id &&& id)+ ) . Data.FileCombination.risingFilter 0
src/Squeeze/Test/Performance.hs view
@@ -53,18 +53,18 @@ -> IO [Data.FileCombination.FileCombination] run commandOptions fileCount probabilityDistribution = do randomGen <- Data.Maybe.maybe System.Random.getStdGen {-use the global random-number generator-} (- return {-to IO-monad-} . System.Random.mkStdGen --Seed the random-number generator as specified.- ) $ Data.CommandOptions.getMaybeRandomSeed commandOptions --Select a random-number generator.+ return {-to IO-monad-} . System.Random.mkStdGen -- Seed the random-number generator as specified.+ ) $ Data.CommandOptions.getMaybeRandomSeed commandOptions -- Select a random-number generator. let (acceptedFileSizeAndPathList, logFile) = Control.Monad.Writer.runWriter . Data.File.selectSuitableFileSizes (- <= Data.CommandOptions.getMaximumBytes commandOptions --This may reduce the requested number of files, but compensating distorts the requested distribution.+ <= Data.CommandOptions.getMaximumBytes commandOptions -- This may reduce the requested number of files, but compensating distorts the requested distribution. ) . (- `zip` map show [0 :: Int ..] --Construct a Data.File.FileSizeAndPath, by using a counter as the file-name.+ `zip` map show [0 :: Int ..] -- Construct a Data.File.FileSizeAndPath, by using a counter as the file-name. ) . take fileCount . filter (- >= 0 --A suitable distribution shouldn't generate negative file-sizes.+ >= 0 -- A suitable distribution shouldn't generate negative file-sizes. ) . map (- ceiling :: Double -> Integer --File-sizes are integral.+ ceiling :: Double -> Integer -- File-sizes are integral. ) $ Factory.Math.Probability.generatePopulation probabilityDistribution randomGen Control.Monad.when (Data.CommandOptions.getVerbosity commandOptions > minBound) . System.IO.hPutStrLn System.IO.stderr $ Data.List.intercalate "\n" logFile
src/Squeeze/Test/Squeeze.hs view
@@ -39,7 +39,7 @@ quickChecks :: IO () quickChecks = Test.QuickCheck.quickCheck `mapM_` [prop_totalCombinations, prop_fileSizeBounds, prop_allFiles, prop_monotonicFileSize, prop_uniqueFileNames] where mkFileSizeAndPathList :: (Integral i, Show i) => [i] -> [Data.File.FileSizeAndPath]- mkFileSizeAndPathList = take 12 . Data.List.nubBy (ToolShed.Data.List.equalityBy snd) . map (toInteger . abs &&& show) --CAVEAT: may be shorter than requested.+ mkFileSizeAndPathList = take 12 . Data.List.nubBy (ToolShed.Data.List.equalityBy snd) . map (toInteger . abs &&& show) -- CAVEAT: may be shorter than requested. prop_totalCombinations, prop_fileSizeBounds, prop_allFiles, prop_monotonicFileSize, prop_uniqueFileNames :: [Integer] -> Test.QuickCheck.Property prop_totalCombinations integers = Test.QuickCheck.label "prop_totalCombinations" $ (length . Data.List.nub . Squeeze.findCombinations (0, fromIntegral (maxBound :: Int)) $ Data.File.orderByDecreasingSize fileSizeAndPathList) == 2 ^ length fileSizeAndPathList where@@ -51,8 +51,8 @@ fileSizeBounds :: Factory.Data.Interval.Interval Data.File.FileSize fileSizeBounds = (minimumBytes, maximumBytes) where maximumBytes, minimumBytes :: Data.File.FileSize- maximumBytes = round $ fromIntegral (Data.File.aggregateSize fileSizeAndPathList) / (4.0 :: Double) --Arbitrarily.- minimumBytes = maximumBytes `div` 2 --Arbitrarily.+ maximumBytes = round $ fromIntegral (Data.File.aggregateSize fileSizeAndPathList) / (4.0 :: Double) -- Arbitrarily.+ minimumBytes = maximumBytes `div` 2 -- Arbitrarily. prop_allFiles integers = Test.QuickCheck.label "prop_allFiles" . (== aggregateSize) . last . map Data.FileCombination.getAggregateFileSize $ Squeeze.findBestFit (Factory.Data.Interval.precisely aggregateSize) fileSizeAndPathList where fileSizeAndPathList = mkFileSizeAndPathList integers