حالا هسکل هم فایل Parquet مینویسه
خلاصهٔ کاملتر
تیم DataHaskell برای کتابخونهٔ Dataframe یه writer برای فرمت Parquet نوشته. Parquet یعنی همون فرمت ذخیرهٔ ستونی که کل اکوسیستم دیتا ساینس باهاش کار میکنه. تو مقاله اومده که استفادهش سادهست: دیتافریم رو میدی به writeParquet و خودش با اندازههای پیشفرض برای row group و page فایلو میسازه.
main = do
sales <- D.readParquet "sales_data.parquet"
sales
|> D.groupBy ["product"]
|> D.aggregate [ F.sum (F.col @Int "amount") `as` "total" ]
|> D.writeParquet "total_orders.parquet"نویسنده میگه تا حالا هسکل برای سریالایز کردن داده عملاً فقط CSV و JSON و دامپ کردن تو ByteString رو داشت. هرچی حجم داده بالاتر بره اینها کندتر و دستوپاگیرتر میشن و فرمتهای خونگی هم با ابزارهای استاندارد دیتا جور در نمیان. Parquet سادگی رو فدا میکنه تا در عوض فشردهسازی بهتر و خوندنِ کمترِ دادهٔ بیربط رو بده.
اگه بخوای دقیقتر تنظیم کنی، writeParquetWithOptions هست با کلیدهایی مثل pageSize، rowGroupSize، batchRows، subBatchRows و compressionCodec. نکته اینه که هر column chunk تو یه row group باید تعداد سطر یکسان داشته باشه، ولی هر ستون با انکودینگ و فشردهسازی خودش تعداد سطر متفاوتی تا رسیدن به اندازهٔ هدف جا میده. برای همین اندازهٔ page و row group فقط تا حد امکان رعایت میشه و کار روی دستههای batchRows تایی جلو میره.
چون از قبل معلوم نیست هر بافر چقدر باید بزرگ باشه، بافرها باید بتونن رشد کنن. پیادهسازی از MutableByteArray پینشده استفاده میکنه تا موقع flush بشه اونو به Ptr Word8 تبدیل کرد. پینشده بودن یه دردسر داره: نمیشه از grow خودِ Data.Primitive استفاده کرد و باید آرایهٔ جدید ساخت و قدیمی رو دست GC سپرد. ensureCapacity هر بار حدود ۱.۵ برابرِ فضای لازم میگیره تا این رشدها کم پیش بیاد.
به گفتهٔ نویسنده کل writer رو میشه یه fold افکتدار روی دیتافریم دید: روی سطرها حلقه میزنه، داده رو تو بافر page مینویسه، بافر page که پر شد میره تو بافر column chunk و اون هم سرِ اندازهٔ row group روی فایل خالی میشه. خروجی نهایی فولد هم همون متادیتاییه که آخر فایل میشینه. فعلاً definition level فقط تا ۱ پشتیبانی میشه، یعنی ستون nullable آره ولی اسکیمای تودرتو نه.
نکات کلیدی:
- writeParquet با تنظیمات پیشفرض مینویسه و writeParquetWithOptions اندازهٔ page و row group و کدک فشردهسازی رو دست خودت میده.
- اندازهٔ page و row group هدفه نه تضمین؛ کار روی دستههای batchRows و زیردستههای subBatchRows تایی انجام میشه.
- بافرها MutableByteArray پینشدهان و ensureCapacity موقع کمبود جا، حدود ۱.۵ برابرِ نیاز آرایهٔ تازه میسازه.
- فقط definition level تا ۱ و repetition level صفر پشتیبانی میشه، پس اسکیمای تودرتو فعلاً خارج از محدودهست.




