packages feed

wireform-parquet-0.1.0.0: src/Parquet/Nested/Generate.hs

{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedSums #-}
{-# LANGUAGE UnboxedTuples #-}

{- | Internal strict vector construction without per-element Either, list
spines or deferred indexing closures.
-}
module Parquet.Nested.Generate (generate#) where

import Data.Vector qualified as V
import Data.Vector.Mutable qualified as VM
import GHC.Exts (Int (I#), Int#, runRW#, (+#), (==#))
import GHC.ST (ST (..))


-- Materialize only visited rows, with no boxed index or per-row Either.
-- Force each result before storing it, avoiding deferred indexing closures
-- that retain a whole input column after conversion.
generate# :: Int# -> (Int# -> (# String | a #)) -> (# String | V.Vector a #)
generate# count produce = runRW# $ \state ->
  case VM.unsafeNew (I# count) of
    ST allocate ->
      case allocate state of
        (# state1, output #) ->
          let go index state2 =
                case index ==# count of
                  1# -> case V.unsafeFreeze output of
                    ST freeze -> case freeze state2 of
                      (# _, result #) -> (# | result #)
                  _ -> case produce index of
                    (# message | #) -> (# message | #)
                    (# | value #) -> case value of
                      !strictValue -> case VM.unsafeWrite output (I# index) strictValue of
                        ST write -> case write state2 of
                          (# state3, () #) -> go (index +# 1#) state3
          in go 0# state1
{-# INLINE generate# #-}