Make the analysis parallel #2
@ -41,6 +41,7 @@ library
|
|||||||
, vector
|
, vector
|
||||||
, containers
|
, containers
|
||||||
, filepath
|
, filepath
|
||||||
|
, parallel
|
||||||
hs-source-dirs: src
|
hs-source-dirs: src
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
ghc-options: -Wall
|
ghc-options: -Wall
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{ mkDerivation, attoparsec, base, bytestring, conduit
|
{ mkDerivation, attoparsec, base, bytestring, conduit
|
||||||
, conduit-extra, containers, criterion, filepath, hedgehog
|
, conduit-extra, containers, criterion, filepath, hedgehog
|
||||||
, hedgehog-corpus, HUnit, lens, lib, mtl, optparse-applicative
|
, hedgehog-corpus, HUnit, lens, lib, mtl, optparse-applicative
|
||||||
, tasty, tasty-hedgehog, tasty-hunit, text, vector
|
, parallel, tasty, tasty-hedgehog, tasty-hunit, text, vector
|
||||||
}:
|
}:
|
||||||
mkDerivation {
|
mkDerivation {
|
||||||
pname = "addressbook";
|
pname = "addressbook";
|
||||||
@ -11,10 +11,11 @@ mkDerivation {
|
|||||||
isExecutable = true;
|
isExecutable = true;
|
||||||
libraryHaskellDepends = [
|
libraryHaskellDepends = [
|
||||||
attoparsec base bytestring conduit conduit-extra containers
|
attoparsec base bytestring conduit conduit-extra containers
|
||||||
filepath lens mtl text vector
|
filepath lens mtl parallel text vector
|
||||||
];
|
];
|
||||||
executableHaskellDepends = [
|
executableHaskellDepends = [
|
||||||
base criterion hedgehog-corpus optparse-applicative text
|
base bytestring containers criterion hedgehog-corpus
|
||||||
|
optparse-applicative text
|
||||||
];
|
];
|
||||||
testHaskellDepends = [
|
testHaskellDepends = [
|
||||||
base bytestring conduit conduit-extra containers hedgehog
|
base bytestring conduit conduit-extra containers hedgehog
|
||||||
|
@ -25,6 +25,12 @@ import System.Environment
|
|||||||
(lookupEnv)
|
(lookupEnv)
|
||||||
import System.FilePath
|
import System.FilePath
|
||||||
((</>))
|
((</>))
|
||||||
|
import Data.Set (Set)
|
||||||
|
import Data.ByteString (ByteString)
|
||||||
|
import qualified Data.Set as Set
|
||||||
|
import qualified Data.ByteString.Lazy as LBS
|
||||||
|
import Data.Char (ord)
|
||||||
|
import qualified Data.ByteString.Lazy.Char8 as LBC
|
||||||
|
|
||||||
combine :: (MonadUnliftIO m, MonadResource m, MonadThrow m, MonadIO m) => ConduitM FilePath Header m ()
|
combine :: (MonadUnliftIO m, MonadResource m, MonadThrow m, MonadIO m) => ConduitM FilePath Header m ()
|
||||||
combine = await >>= \case
|
combine = await >>= \case
|
||||||
@ -33,6 +39,23 @@ combine = await >>= \case
|
|||||||
|
|
||||||
run :: IO ()
|
run :: IO ()
|
||||||
run = do
|
run = do
|
||||||
|
datDir <- fromMaybe "./" <$> lookupEnv "HOME"
|
||||||
|
x <- LBS.getContents >>= stream
|
||||||
|
runResourceT $
|
||||||
|
runConduit (CL.sourceList (Set.elems x) .| C.map (<> "\n") .| CB.sinkFileCautious (datDir </> ".addressbook.dat"))
|
||||||
|
where
|
||||||
|
separate = \case
|
||||||
|
From x -> [x]
|
||||||
|
To xs -> F.toList xs
|
||||||
|
stream :: LBS.ByteString -> IO (Set ByteString)
|
||||||
|
stream xs = F.fold <$> traverse (parse . LBC.unpack) (LBS.split (fromIntegral $ ord '\n') xs)
|
||||||
|
parse path =
|
||||||
|
runResourceT $
|
||||||
|
runConduit $
|
||||||
|
CB.sourceFile path .| parseEmail .| C.concatMap separate .| CT.encode CT.utf8 .| C.foldMap Set.singleton
|
||||||
|
|
||||||
|
run_ :: IO ()
|
||||||
|
run_ = do
|
||||||
datDir <- fromMaybe "./" <$> lookupEnv "HOME"
|
datDir <- fromMaybe "./" <$> lookupEnv "HOME"
|
||||||
runResourceT $ do
|
runResourceT $ do
|
||||||
x <- runConduit stream
|
x <- runConduit stream
|
||||||
|
Loading…
Reference in New Issue
Block a user