fileplow-0.1.0.0: src/Data/FilePlow/Ordered.hs
module Data.FilePlow.Ordered
( SeekTarget(..), seekTo )
where
import Data.FilePlow
import Numeric.Search
data SeekTarget b
= StLargerThan !b
-- ^ put the handle to the first entry that is larger than the provided value.
-- Useful for files with entries in ASCending order
| StSmallerThan !b
-- ^ put the handle to the first entry that is smaller than the provided value.
-- Useful for files with entries in DESCending order
deriving (Show, Eq)
-- ^ place the file handling to a specific 'SeekTarget' provided a function that
-- extracts a value/entry at a specific position
seekTo ::
(Ord b, Eq b, PlowHandle hdl)
=> hdl
-> SeekTarget b
-> (hdl -> IO b)
-> IO Bool
seekTo hdl st extract =
do s <- pFileSize hdl
ranges <- searchM (fromTo 0 (s - 1)) divForever $ \pos ->
do case st of
StLargerThan _ -> pSeek hdl AbsoluteSeek pos
StSmallerThan _ -> pSeek hdl AbsoluteSeek (s - 1 - pos)
val <- extract hdl
pure $
case st of
StLargerThan x -> (val >= x)
StSmallerThan x -> (val <= x)
let tgtVal =
case st of
StSmallerThan _ -> largest True ranges
StLargerThan _ -> smallest True ranges
case tgtVal of
Just pos ->
case st of
StLargerThan _ -> pSeek hdl AbsoluteSeek pos >> pure True
StSmallerThan _ -> pSeek hdl AbsoluteSeek (s - 1 - pos) >> pure True
Nothing -> pure False