From 0c75d66122596a9a168c4acee7d65348b02067a2 Mon Sep 17 00:00:00 2001 From: Mats Rauhala Date: Fri, 29 Oct 2021 17:34:41 +0300 Subject: [PATCH] Simplify querying --- src/Control/Addressbook/Query.hs | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/src/Control/Addressbook/Query.hs b/src/Control/Addressbook/Query.hs index ca43a54..24d534c 100644 --- a/src/Control/Addressbook/Query.hs +++ b/src/Control/Addressbook/Query.hs @@ -4,15 +4,12 @@ module Control.Addressbook.Query where import Data.Text (Text) import qualified Data.Text as T -import qualified Data.Text.Encoding as TE import Conduit import qualified Data.Conduit.Binary as CB import qualified Data.Conduit.Combinators as C -import qualified Data.Conduit.List as CL import qualified Data.Conduit.Text as CT -import qualified Data.Map.Strict as Map import System.IO (stdout) @@ -26,27 +23,20 @@ import System.FilePath import Control.Exception (catch) -import Data.ByteString (ByteString) -import qualified Data.ByteString.Char8 as B -- XXX: The current Data.Trie implementation is much slower than Data.Set query :: Text -> IO () query prefix = do datDir <- fromMaybe "./" <$> lookupEnv "HOME" - state <- catch @IOError (runResourceT $ runConduit $ readState datDir) (\_ -> pure Map.empty) - runConduit $ outputResults state + catch @IOError (runResourceT $ runConduit $ filterAddresses datDir) $ \e -> print e where - readState :: FilePath -> ConduitM () Void (ResourceT IO) (Map.Map ByteString [Text]) - readState dir = + prefixLC = T.toLower prefix + filterAddresses :: FilePath -> ConduitT () Void (ResourceT IO) () + filterAddresses dir = CB.sourceFile (dir ".addressbook.dat") .| CT.decode CT.utf8 .| CT.lines - .| C.foldMap (\s -> Map.singleton (TE.encodeUtf8 $ T.toLower s) [s]) - prefixB = TE.encodeUtf8 prefix - outputResults :: Map.Map ByteString [Text] -> ConduitM () Void IO () - outputResults state = - CL.sourceList (Map.elems $ Map.filterWithKey (\k _ -> prefixB `B.isPrefixOf` k) state) - .| C.concat - .| C.map (<> "\n") + .| C.filter (\v -> prefixLC `T.isPrefixOf` (T.toLower v)) .| CT.encode CT.utf8 + .| C.map (<> "\n") .| CB.sinkHandle stdout