packages feed

hw-eliasfano-0.1.1.0: app/App/Commands/LoadSave.hs

{-# LANGUAGE DataKinds           #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications    #-}

module App.Commands.LoadSave
  ( cmdLoadSave
  ) where

import Control.Lens
import Data.Generics.Product.Any
import Data.Semigroup            ((<>))
import Data.Word
import Options.Applicative       hiding (columns)

import qualified App.Commands.Types                            as Z
import qualified Data.Binary.Get                               as G
import qualified Data.ByteString.Lazy                          as LBS
import qualified Data.Vector.Storable                          as DVS
import qualified HaskellWorks.Data.EliasFano                   as EF
import qualified HaskellWorks.Data.PackedVector.PackedVector64 as PV
import qualified System.IO                                     as IO

{-# ANN module ("HLint: ignore Reduce duplication"  :: String) #-}
{-# ANN module ("HLint: ignore Redundant do"        :: String) #-}

decodeWord32s :: LBS.ByteString -> [Word32]
decodeWord32s = fmap (G.runGet G.getWord32le) . go
  where go :: LBS.ByteString -> [LBS.ByteString]
        go lbs = case LBS.splitAt 4 lbs of
          (lt, rt) -> if LBS.length lt == 4
            then lt:go rt
            else if LBS.length lt == 0
              then []
              else [LBS.take 4 (lt <> LBS.replicate 4 0)]

runLoadSave :: Z.LoadSaveOptions -> IO ()
runLoadSave opts = do
  lbs <- LBS.readFile (opts ^. the @"input")
  let ws = fmap fromIntegral (decodeWord32s lbs) :: [Word64]
  let ef = EF.fromListWord64 ws :: EF.EliasFano
  -- let x = DVS.length (PV.swBuffer (EF.efCount ef))
  IO.putStrLn $ "Eliasfano:"
    <> " bits: "  <> show (ef & EF.efBucketBits & DVS.length                )
    <> " count: " <> show (ef & EF.efLoSegments & PV.swBuffer & DVS.length  )
    <> " pv: "    <> show (ef & EF.efCount                                  )
    <> " lbc: "   <> show (ef & EF.efLoBitCount                             )

optsLoadSave :: Parser Z.LoadSaveOptions
optsLoadSave = Z.LoadSaveOptions
  <$> strOption
        (   long "input"
        <>  short 'i'
        <>  help "Input file of little-endian monotonically increasing word32s"
        <>  metavar "FILE"
        )
  <*> strOption
        (   long "output"
        <>  short 'o'
        <>  help "Output files"
        <>  metavar "FILE"
        )

cmdLoadSave :: Mod CommandFields (IO ())
cmdLoadSave = command "load-save"  $ flip info idm $ runLoadSave <$> optsLoadSave