
Hi, I'm trying to make use of memory mapped files with Haskell. It is kind of fun, I managed to mmap a file (actualy CreateFileMapping, because I'm on a Windows box), managed to setup finalizers (those kind of work now, see my posts about finalizers and FFI). Now I got to content... and here is the problem. Data I want to read is large, mostly binary with parts that must be parsed. But peekArray is not lazy (is IO action), produces large lists in strict mode. So I had to write my own thing. Provided that underlying data does not change following unsafeLazyPeekArray and friends should be good. Does anybody see any problems in following code? Maybe there is something obvious I do not see... Those functions were designed to be list less, when used in producer consumer fashion list will not be generated (I hope). Is current state GHC compiler smart enough to optimize this efficiently? How can I help it with this task (maybe a pragma here and there?) Anyway, the code. Maybe someone find it interesting: unsafeLazyPeekArray size ptr = unsafeLazyPeekArrayOffset 0 size ptr unsafeLazyPeekArrayOffset :: Storable a => Int -> Int -> ForeignPtr a -> [a] unsafeLazyPeekArrayOffset offset size ptr | size <= 0 = [] | otherwise = unsafePerformIO $ helper offset where helper index | index >= size = return [] | otherwise = unsafeInterleaveIO $ do x <- withForeignPtr ptr (\xptr -> peekElemOff xptr index) xs <- helper (index+1) return (x:xs) unsafeLazyPeekArrayOffset0 :: (Storable a, Eq a) => Int -> a -> ForeignPtr a -> [a] unsafeLazyPeekArrayOffset0 offset marker ptr = unsafePerformIO $ helper offset where helper index = unsafeInterleaveIO $ do x <- withForeignPtr ptr (\xptr -> peekElemOff xptr index) if x==marker then return [] else do xs <- helper (index+1) return (x:xs) unsafeLazyPeekArray0 :: (Storable a, Eq a) => a -> ForeignPtr a -> [a] unsafeLazyPeekArray0 marker ptr = unsafeLazyPeekArrayOffset0 0 marker ptr -- Pozdrawiam, Regards, Gracjan
participants (1)
-
Gracjan Polak