data-sketches-core-0.2.0.0: src/DataSketches/Frequencies/CountMin/Internal.hs
{-# LANGUAGE ForeignFunctionInterface #-}
module DataSketches.Frequencies.CountMin.Internal
( CountMinSketch
, mkCountMinSketch
, cmsInsert
, cmsInsertN
, cmsEstimate
, cmsMerge
, cmsWidth
, cmsDepth
) where
import Control.DeepSeq (NFData(..))
import Control.Monad.Primitive
import Data.Word
import Foreign.C.Types
import Foreign.ForeignPtr
import Foreign.Ptr
newtype CountMinSketch s = CountMinSketch (ForeignPtr ())
instance NFData (CountMinSketch s) where rnf !_ = ()
foreign import ccall unsafe "cms_new" c_cms_new :: CDouble -> CDouble -> IO (Ptr ())
foreign import ccall unsafe "&cms_free" c_cms_free :: FunPtr (Ptr () -> IO ())
foreign import ccall unsafe "cms_c_insert" c_cms_insert :: Ptr () -> Word64 -> Word64 -> IO ()
foreign import ccall unsafe "cms_c_estimate" c_cms_estimate :: Ptr () -> Word64 -> IO Word64
foreign import ccall unsafe "cms_c_merge" c_cms_merge :: Ptr () -> Ptr () -> IO ()
foreign import ccall unsafe "cms_c_width" c_cms_width :: Ptr () -> IO CInt
foreign import ccall unsafe "cms_c_depth" c_cms_depth :: Ptr () -> IO CInt
withSketch :: CountMinSketch s -> (Ptr () -> IO a) -> IO a
withSketch (CountMinSketch fp) = withForeignPtr fp
{-# INLINE withSketch #-}
mkCountMinSketch :: PrimMonad m => Double -> Double -> m (CountMinSketch (PrimState m))
mkCountMinSketch epsilon delta = unsafePrimToPrim $ do
ptr <- c_cms_new (realToFrac epsilon) (realToFrac delta)
fp <- newForeignPtr c_cms_free ptr
pure (CountMinSketch fp)
cmsInsert :: PrimMonad m => CountMinSketch (PrimState m) -> Word64 -> m ()
cmsInsert sk item = cmsInsertN sk item 1
{-# INLINE cmsInsert #-}
cmsInsertN :: PrimMonad m => CountMinSketch (PrimState m) -> Word64 -> Word64 -> m ()
cmsInsertN sk item n = unsafePrimToPrim $ withSketch sk $ \p -> c_cms_insert p item n
{-# INLINE cmsInsertN #-}
cmsEstimate :: PrimMonad m => CountMinSketch (PrimState m) -> Word64 -> m Word64
cmsEstimate sk item = unsafePrimToPrim $ withSketch sk $ \p -> c_cms_estimate p item
cmsMerge :: PrimMonad m => CountMinSketch (PrimState m) -> CountMinSketch (PrimState m) -> m ()
cmsMerge dst src = unsafePrimToPrim $
withSketch dst $ \pd -> withSketch src $ \ps -> c_cms_merge pd ps
cmsWidth :: PrimMonad m => CountMinSketch (PrimState m) -> m Int
cmsWidth sk = unsafePrimToPrim $ withSketch sk $ fmap fromIntegral . c_cms_width
cmsDepth :: PrimMonad m => CountMinSketch (PrimState m) -> m Int
cmsDepth sk = unsafePrimToPrim $ withSketch sk $ fmap fromIntegral . c_cms_depth