dataframe-fastcsv-1.1.1.0: src/DataFrame/IO/CSV/Fast/TextMerge.hs
{-# LANGUAGE BangPatterns #-}
{- | Parallel byte-level merge of per-chunk text columns: the byte copies
and offset rebase fan out over the chunk list, so a large text column does
not serialize the merge phase. Wraps the merged shared buffer + offsets as
'PackedText' (no 'Data.Text.Text' spine, no eager UTF-8 validation), exactly
as the pure 'mergeTextChunks' now produces.
-}
module DataFrame.IO.CSV.Fast.TextMerge (
mergeTextChunksPar,
) where
import qualified Data.Text.Array as A
import qualified Data.Vector.Unboxed as VU
import qualified Data.Vector.Unboxed.Mutable as VUM
import Control.Monad (void)
import Control.Monad.ST (stToIO)
import DataFrame.IO.CSV.Fast.Workers (pooledRun)
import DataFrame.Internal.Column (Column (..))
import DataFrame.Internal.ColumnMerge (
TextChunk (..),
mergeTextChunks,
spliceBitmaps,
tcRows,
)
import DataFrame.Internal.PackedText (mkPackedContiguous)
{- | Merge text chunks with @width@-way parallel byte copies + offset
rebase, then wrap the shared buffer as 'PackedText'. Single chunks take
the pure (zero-copy) path.
-}
mergeTextChunksPar :: Int -> [TextChunk] -> IO Column
mergeTextChunksPar _ [c] = pure $! mergeTextChunks [c]
mergeTextChunksPar width cs = do
let byteOffs = scanl (+) 0 (map tcUsed cs)
rowOffs = scanl (+) 0 (map tcRows cs)
totalBytes = last byteOffs
totalRows = last rowOffs
marr <- stToIO (A.new (max 1 totalBytes))
offsMV <- VUM.unsafeNew (totalRows + 1)
VUM.unsafeWrite offsMV 0 0
-- Byte copy + offset rebase, parallel over chunks (disjoint ranges).
void . pooledRun width $
[ do
stToIO (A.copyI (tcUsed c) marr bOff (tcBytes c) 0)
let co = tcOffsets c
n = tcRows c
fill !i
| i > n = pure ()
| otherwise = do
VUM.unsafeWrite
offsMV
(rOff + i)
(bOff + VU.unsafeIndex co i)
fill (i + 1)
fill 1
| (c, bOff, rOff) <- zip3 cs byteOffs rowOffs
]
arr <- stToIO (A.unsafeFreeze marr)
offs <- VU.unsafeFreeze offsMV
let !bm = spliceBitmaps [(tcBitmap c, tcRows c) | c <- cs]
pure (PackedText bm (mkPackedContiguous arr offs))