jvm-batching 0.1.1 → 0.1.2
raw patch · 4 files changed
+53/−33 lines, 4 filesdep ~inline-javadep ~jnidep ~jvm
Dependency ranges changed: inline-java, jni, jvm
Files
- jvm-batching.cabal +5/−4
- src/main/haskell/Language/Java/Batching.hs +46/−27
- src/test/haskell/Language/Java/BatchingSpec.hs +0/−1
- src/test/haskell/Spec.hs +2/−1
jvm-batching.cabal view
@@ -1,5 +1,5 @@ name: jvm-batching-version: 0.1.1+version: 0.1.2 synopsis: Provides batched marshalling of values between Java and Haskell. description: Please see README.md. homepage: http://github.com/tweag/inline-java/tree/master/jvm-batching#readme@@ -43,9 +43,9 @@ base >= 4.7 && < 5, bytestring, distributed-closure >= 0.3.5,- jni >= 0.6.0 && <0.7,- jvm >= 0.4.0 && <0.5,- inline-java >= 0.7 && <0.9,+ jni >= 0.7.0 && <0.8,+ jvm >= 0.5.0 && <0.6,+ inline-java >= 0.7 && <0.10, singletons >= 2.2, text, vector@@ -68,6 +68,7 @@ text, vector default-language: Haskell2010+ cpp-options: -DHSPEC_DISCOVER=hspec-discover benchmark micro-benchmarks type: exitcode-stdio-1.0
src/main/haskell/Language/Java/Batching.hs view
@@ -18,7 +18,6 @@ {-# LANGUAGE UndecidableInstances #-} {-# OPTIONS_GHC -fno-warn-orphans #-}-{-# OPTIONS_GHC -fplugin=Language.Java.Inline.Plugin #-} -- | This module provides composable batched marshalling. --@@ -28,7 +27,7 @@ -- primitive values can be as slow as marshalling a single value. -- -- Because of this, reifying an iterator or a container is best done by--- accumulates multiple elements on the java side before passing them to the+-- accumulating multiple elements on the java side before passing them to the -- Haskell side. And conversely, when reflecting an iterator or container, -- multiple Haskell values are put together before marshalling to the Java -- side.@@ -71,7 +70,7 @@ -- > ) -- > reifyBatch :: J (Batch a) -> Int32 -> IO (V.Vector a) ----- @newReifyBatched@ produces a java object implementing the @BatchWriter@+-- @newBatchWriter@ produces a java object implementing the @BatchWriter@ -- interface, and @reifyBatch@ allows to read a batch created in this fashion. -- -- Conversely, batches can be read on the Java side using the interface@@ -96,7 +95,7 @@ -- advantage of batching requires defining the methods explicitly. The default -- implementations are useful for cases where speed is not important, for -- instance when the iterators to reflect or reify contain a single element or--- just a very few.+-- just very few. -- -- 'Vector's and 'ByteString's are batched with the follow scheme. --@@ -200,9 +199,15 @@ -- | Batches of arrays of variable length ----- The first component is an array or batch containing the actual elements,--- and the second component is an @int[]@ where the ith position has the--- offset of the first position after the ith array.+-- The first component is an array or batch B containing the elements+-- of all the arrays in the batch. The second component is an array of+-- offsets F. The ith position in the offset array is the first position+-- in B after the ith array of the batch.+--+-- Thus, the first array of the batch can be found in B between the+-- indices 0 and F[0], the second array of the batch is between the+-- indices F[0] and F[1], and so on.+-- type ArrayBatch ty = 'Class "io.tweag.jvm.batching.Tuple2" <> '[ ty@@ -219,29 +224,47 @@ :: forall a b ty. (Int32 -> J ty -> IO a) -- ^ reify the array/batch of values -- (takes the amount of elements in the array)- -> (Int -> Int -> a -> IO b) -- ^ slice at a given offset of given length of some value+ -> (Int -> Int -> a -> IO b) -- ^ slice at a given offset of given length of some array a -> J (ArrayBatch ty) -> Int32 -> IO (V.Vector b) reifyArrayBatch reifyB slice batch0 batchSize = do- result <- VM.new (fromIntegral batchSize) let batch = unsafeUngeneric batch0- vecEnds <- [java| (int[])$batch._2 |] >>= reify- let count = if VS.null vecEnds then 0 else VS.last vecEnds- vecValues <- [java| $batch._1 |] >>= reifyB count . fromObject- _ <- foldM (writeVector result vecEnds vecValues) 0 [0 .. batchSize - 1]- V.unsafeFreeze result+ arrayEnds <- reifyArrayOffsets batch+ arrayValues <- reifyArrayValues arrayEnds batch+ reifySlices arrayEnds arrayValues where fromObject :: JObject -> J x fromObject = unsafeCast - writeVector :: VM.IOVector b -> VS.Vector Int32 -> a -> Int32 -> Int32 -> IO Int32- writeVector mv ends values offset i32 = do- let i = fromIntegral i32+ reifyArrayOffsets+ :: J ('Class "io.tweag.jvm.batching.Tuple2") -> IO (VS.Vector Int32)+ reifyArrayOffsets batch = [java| (int[])$batch._2 |] >>= reify++ reifyArrayValues arrayEnds batch = do+ let count = if VS.null arrayEnds then 0 else VS.last arrayEnds+ [java| $batch._1 |] >>= reifyB count . fromObject++ reifySlices arrayEnds arrayValues = do+ result <- VM.new (fromIntegral batchSize)+ _ <- foldM+ (writeSliceToVector result arrayEnds arrayValues)+ 0+ [0 .. fromIntegral batchSize - 1]+ V.unsafeFreeze result++ writeSliceToVector+ :: VM.IOVector b -- ^ output vector to write to+ -> VS.Vector Int32 -- ^ ends[i] holds the offset of the (i+1)th slice+ -> a -- ^ input vector to read slices from+ -> Int32 -- ^ offset of the slice to read from the input vector+ -> Int -- ^ index of the position to write in the output vector+ -> IO Int32 -- ^ offset of the next slice to read+ writeSliceToVector output arrayEnds arrayValues offset i = do slice (fromIntegral offset)- (fromIntegral $ ends VS.! i - offset) values- >>= VM.unsafeWrite mv i- return $ ends VS.! i+ (fromIntegral $ arrayEnds VS.! i - offset) arrayValues+ >>= VM.unsafeWrite output i+ return $ arrayEnds VS.! i -- | A class for batching reflection of values. --@@ -323,9 +346,7 @@ bigvec <- concatenate $ V.toList vecs jvec <- reflectB bigvec jends <- reflect ends- generic <$> Language.Java.new [ coerce (upcast jvec)- , coerce (upcast jends)- ]+ generic <$> Language.Java.new (upcast jvec) (upcast jends) withStatic [d| instance Batchable Bool where@@ -610,16 +631,14 @@ instance Batchable a => Batchable (V.Vector a) where type Batch (V.Vector a) = ArrayBatch (Batch a) - instance (SingI (Interp a), SingI (Batch a), BatchReify a)- => BatchReify (V.Vector a) where+ instance BatchReify a => BatchReify (V.Vector a) where newBatchWriter _ = do _b <- unsafeUngeneric <$> newBatchWriter (Proxy :: Proxy a) generic <$> [java| new BatchWriters.ObjectArrayBatchWriter($_b) |] reifyBatch = reifyArrayBatch (flip reifyBatch) (fmap (fmap return) . V.unsafeSlice) - instance (SingI (Interp a), SingI (Batch a), BatchReflect a)- => BatchReflect (V.Vector a) where+ instance BatchReflect a => BatchReflect (V.Vector a) where newBatchReader _ = do _b <- unsafeUngeneric <$> newBatchReader (Proxy :: Proxy a) generic <$> [java| new BatchReaders.ObjectArrayBatchReader($_b) |]
src/test/haskell/Language/Java/BatchingSpec.hs view
@@ -1,7 +1,6 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE QuasiQuotes #-}-{-# OPTIONS_GHC -fplugin=Language.Java.Inline.Plugin #-} module Language.Java.BatchingSpec where
src/test/haskell/Spec.hs view
@@ -1,1 +1,2 @@-{-# OPTIONS_GHC -F -pgmF hspec-discover -optF --module-name=Spec #-}+{-# LANGUAGE CPP #-}+{-# OPTIONS_GHC -F -pgmF HSPEC_DISCOVER -optF --module-name=Spec #-}