packages feed

data-sketches 0.3.0.1 → 0.3.1.0

raw patch · 10 files changed

+19/−1108 lines, 10 filesdep +data-sketches-coredep −cerealdep −deepseqdep −prettyprinterPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: data-sketches-core

Dependencies removed: cereal, deepseq, prettyprinter

API changes (from Hackage documentation)

- DataSketches.Quantiles.RelativeErrorQuantile: computeTotalRetainedItems :: PrimMonad m => ReqSketch (PrimState m) -> m Int
- DataSketches.Quantiles.RelativeErrorQuantile: instance Control.DeepSeq.NFData (DataSketches.Quantiles.RelativeErrorQuantile.ReqSketch s)
- DataSketches.Quantiles.RelativeErrorQuantile: instance DataSketches.Quantiles.RelativeErrorQuantile.Types.TakeSnapshot DataSketches.Quantiles.RelativeErrorQuantile.ReqSketch
- DataSketches.Quantiles.RelativeErrorQuantile: instance GHC.Classes.Eq DataSketches.Quantiles.RelativeErrorQuantile.CumulativeDistributionInvariants
- DataSketches.Quantiles.RelativeErrorQuantile: instance GHC.Exception.Type.Exception DataSketches.Quantiles.RelativeErrorQuantile.CumulativeDistributionInvariants
- DataSketches.Quantiles.RelativeErrorQuantile: instance GHC.Generics.Generic (DataSketches.Quantiles.RelativeErrorQuantile.ReqSketch s)
- DataSketches.Quantiles.RelativeErrorQuantile: instance GHC.Show.Show (DataSketches.Quantiles.RelativeErrorQuantile.Types.Snapshot DataSketches.Quantiles.RelativeErrorQuantile.ReqSketch)
- DataSketches.Quantiles.RelativeErrorQuantile: instance GHC.Show.Show DataSketches.Quantiles.RelativeErrorQuantile.CumulativeDistributionInvariants
- DataSketches.Quantiles.RelativeErrorQuantile: mkAuxiliaryFromReqSketch :: PrimMonad m => ReqSketch (PrimState m) -> m ReqAuxiliary
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Auxiliary: MReqAuxiliary :: {-# UNPACK #-} !MutVar s (MVector s (Double, Word64)) -> !RankAccuracy -> {-# UNPACK #-} !Word64 -> MReqAuxiliary s
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Auxiliary: ReqAuxiliary :: {-# UNPACK #-} !Vector (Double, Word64) -> !RankAccuracy -> {-# UNPACK #-} !Word64 -> ReqAuxiliary
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Auxiliary: [mraHighRankAccuracy] :: MReqAuxiliary s -> !RankAccuracy
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Auxiliary: [mraSize] :: MReqAuxiliary s -> {-# UNPACK #-} !Word64
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Auxiliary: [mraWeightedItems] :: MReqAuxiliary s -> {-# UNPACK #-} !MutVar s (MVector s (Double, Word64))
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Auxiliary: [raHighRankAccuracy] :: ReqAuxiliary -> !RankAccuracy
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Auxiliary: [raSize] :: ReqAuxiliary -> {-# UNPACK #-} !Word64
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Auxiliary: [raWeightedItems] :: ReqAuxiliary -> {-# UNPACK #-} !Vector (Double, Word64)
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Auxiliary: data MReqAuxiliary s
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Auxiliary: data ReqAuxiliary
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Auxiliary: getQuantile :: ReqAuxiliary -> Double -> Criterion -> Double
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Auxiliary: instance GHC.Classes.Eq DataSketches.Quantiles.RelativeErrorQuantile.Internal.Auxiliary.ReqAuxiliary
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Auxiliary: instance GHC.Show.Show DataSketches.Quantiles.RelativeErrorQuantile.Internal.Auxiliary.ReqAuxiliary
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Auxiliary: mergeSortIn :: PrimMonad m => MReqAuxiliary (PrimState m) -> DoubleBuffer (PrimState m) -> Word64 -> Int -> m ()
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Auxiliary: mkAuxiliary :: (PrimMonad m, s ~ PrimState m) => RankAccuracy -> Word64 -> Int -> Vector (ReqCompactor s) -> m ReqAuxiliary
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Compactor: CompactorReturn :: {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !DoubleBuffer s -> CompactorReturn s
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Compactor: [crDeltaNominalSize] :: CompactorReturn s -> {-# UNPACK #-} !Int
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Compactor: [crDeltaRetItems] :: CompactorReturn s -> {-# UNPACK #-} !Int
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Compactor: [crDoubleBuffer] :: CompactorReturn s -> {-# UNPACK #-} !DoubleBuffer s
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Compactor: compact :: PrimMonad m => ReqCompactor (PrimState m) -> m (CompactorReturn (PrimState m))
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Compactor: data CompactorReturn s
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Compactor: data ReqCompactor s
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Compactor: getBuffer :: PrimMonad m => ReqCompactor (PrimState m) -> m (DoubleBuffer (PrimState m))
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Compactor: getCoin :: PrimMonad m => ReqCompactor (PrimState m) -> m Bool
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Compactor: getLgWeight :: ReqCompactor s -> Word8
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Compactor: getNominalCapacity :: PrimMonad m => ReqCompactor (PrimState m) -> m Int
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Compactor: getNumSections :: PrimMonad m => ReqCompactor (PrimState m) -> m Word8
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Compactor: instance DataSketches.Quantiles.RelativeErrorQuantile.Types.TakeSnapshot DataSketches.Quantiles.RelativeErrorQuantile.Internal.Compactor.ReqCompactor
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Compactor: instance GHC.Show.Show (DataSketches.Quantiles.RelativeErrorQuantile.Types.Snapshot DataSketches.Quantiles.RelativeErrorQuantile.Internal.Compactor.ReqCompactor)
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Compactor: merge :: (PrimMonad m, s ~ PrimState m) => ReqCompactor (PrimState m) -> ReqCompactor (PrimState m) -> m (ReqCompactor s)
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Compactor: mkReqCompactor :: PrimMonad m => Gen (PrimState m) -> Word8 -> RankAccuracy -> Word32 -> m (ReqCompactor (PrimState m))
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Compactor: nearestEven :: Double -> Int
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Constants: fixRseFactor :: Double
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Constants: initNumberOfSections :: Num a => a
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Constants: minK :: Num a => a
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Constants: nomCapMulti :: Num a => a
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Constants: relRseFactor :: Double
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.Constants: sqrt2 :: Double
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer: (!) :: PrimMonad m => DoubleBuffer (PrimState m) -> Int -> m Double
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer: DoubleIsNonFiniteException :: Double -> DoubleIsNonFiniteException
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer: append :: PrimMonad m => DoubleBuffer (PrimState m) -> Double -> m ()
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer: copyBuffer :: PrimMonad m => DoubleBuffer (PrimState m) -> m (DoubleBuffer (PrimState m))
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer: data DoubleBuffer s
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer: ensureCapacity :: PrimMonad m => DoubleBuffer (PrimState m) -> Int -> m ()
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer: getCapacity :: PrimMonad m => DoubleBuffer (PrimState m) -> m Int
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer: getCount :: PrimMonad m => DoubleBuffer (PrimState m) -> m Int
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer: getCountWithCriterion :: PrimMonad m => DoubleBuffer (PrimState m) -> Double -> Criterion -> m Int
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer: getEvensOrOdds :: PrimMonad m => DoubleBuffer (PrimState m) -> Int -> Int -> Bool -> m (DoubleBuffer (PrimState m))
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer: getSpace :: PrimMonad m => DoubleBuffer (PrimState m) -> m Int
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer: getVector :: (PrimMonad m, PrimState m ~ s) => DoubleBuffer s -> m (MVector s Double)
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer: growthIncrement :: DoubleBuffer s -> Int
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer: instance DataSketches.Quantiles.RelativeErrorQuantile.Types.TakeSnapshot DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer.DoubleBuffer
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer: instance GHC.Classes.Eq DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer.DoubleIsNonFiniteException
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer: instance GHC.Exception.Type.Exception DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer.DoubleIsNonFiniteException
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer: instance GHC.Show.Show (DataSketches.Quantiles.RelativeErrorQuantile.Types.Snapshot DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer.DoubleBuffer)
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer: instance GHC.Show.Show DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer.DoubleIsNonFiniteException
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer: isEmpty :: PrimMonad m => DoubleBuffer (PrimState m) -> m Bool
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer: isSorted :: PrimMonad m => DoubleBuffer (PrimState m) -> m Bool
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer: mergeSortIn :: (PrimMonad m, HasCallStack) => DoubleBuffer (PrimState m) -> DoubleBuffer (PrimState m) -> m ()
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer: mkBuffer :: PrimMonad m => Capacity -> GrowthIncrement -> SpaceAtBottom -> m (DoubleBuffer (PrimState m))
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer: newtype DoubleIsNonFiniteException
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer: sort :: PrimMonad m => DoubleBuffer (PrimState m) -> m ()
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer: spaceAtBottom :: DoubleBuffer s -> Bool
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer: trimCount :: PrimMonad m => DoubleBuffer (PrimState m) -> Int -> m ()
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer: type Capacity = Int
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer: type GrowthIncrement = Int
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer: type SpaceAtBottom = Bool
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.InequalitySearch: (:<) :: (:<)
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.InequalitySearch: (:<=) :: (:<=)
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.InequalitySearch: (:>) :: (:>)
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.InequalitySearch: (:>=) :: (:>=)
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.InequalitySearch: class InequalitySearch s
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.InequalitySearch: data (:>=)
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.InequalitySearch: find :: (InequalitySearch s, PrimMonad m, MVector v a, Ord a) => s -> v (PrimState m) a -> Int -> Int -> a -> m Int
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.InequalitySearch: getIndex :: (InequalitySearch s, PrimMonad m, MVector v a, Ord a) => s -> v (PrimState m) a -> Int -> Int -> a -> m Int
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.InequalitySearch: inequalityCompare :: (InequalitySearch s, Ord a) => s -> a -> a -> a -> Ordering
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.InequalitySearch: instance DataSketches.Quantiles.RelativeErrorQuantile.Internal.InequalitySearch.InequalitySearch (DataSketches.Quantiles.RelativeErrorQuantile.Internal.InequalitySearch.:<)
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.InequalitySearch: instance DataSketches.Quantiles.RelativeErrorQuantile.Internal.InequalitySearch.InequalitySearch (DataSketches.Quantiles.RelativeErrorQuantile.Internal.InequalitySearch.:<=)
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.InequalitySearch: instance DataSketches.Quantiles.RelativeErrorQuantile.Internal.InequalitySearch.InequalitySearch (DataSketches.Quantiles.RelativeErrorQuantile.Internal.InequalitySearch.:>)
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.InequalitySearch: instance DataSketches.Quantiles.RelativeErrorQuantile.Internal.InequalitySearch.InequalitySearch (DataSketches.Quantiles.RelativeErrorQuantile.Internal.InequalitySearch.:>=)
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.InequalitySearch: resolve :: InequalitySearch s => s -> Int -> (Int, Int) -> (Int, Int) -> Int
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.URef: URef :: MVector s a -> URef s a
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.URef: modifyURef :: (PrimMonad m, Unbox a) => URef (PrimState m) a -> (a -> a) -> m ()
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.URef: newURef :: (PrimMonad m, Unbox a) => a -> m (URef (PrimState m) a)
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.URef: newtype URef s a
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.URef: readURef :: (PrimMonad m, Unbox a) => URef (PrimState m) a -> m a
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.URef: type IOURef = URef (PrimState IO)
- DataSketches.Quantiles.RelativeErrorQuantile.Internal.URef: writeURef :: (PrimMonad m, Unbox a) => URef (PrimState m) a -> a -> m ()
- DataSketches.Quantiles.RelativeErrorQuantile.Types: (:<) :: Criterion
- DataSketches.Quantiles.RelativeErrorQuantile.Types: (:<=) :: Criterion
- DataSketches.Quantiles.RelativeErrorQuantile.Types: HighRanksAreAccurate :: RankAccuracy
- DataSketches.Quantiles.RelativeErrorQuantile.Types: LowRanksAreAccurate :: RankAccuracy
- DataSketches.Quantiles.RelativeErrorQuantile.Types: class TakeSnapshot a where {
- DataSketches.Quantiles.RelativeErrorQuantile.Types: data Criterion
- DataSketches.Quantiles.RelativeErrorQuantile.Types: data RankAccuracy
- DataSketches.Quantiles.RelativeErrorQuantile.Types: data family Snapshot a;
- DataSketches.Quantiles.RelativeErrorQuantile.Types: instance DataSketches.Quantiles.RelativeErrorQuantile.Internal.InequalitySearch.InequalitySearch DataSketches.Quantiles.RelativeErrorQuantile.Types.Criterion
- DataSketches.Quantiles.RelativeErrorQuantile.Types: instance GHC.Classes.Eq DataSketches.Quantiles.RelativeErrorQuantile.Types.Criterion
- DataSketches.Quantiles.RelativeErrorQuantile.Types: instance GHC.Classes.Eq DataSketches.Quantiles.RelativeErrorQuantile.Types.RankAccuracy
- DataSketches.Quantiles.RelativeErrorQuantile.Types: instance GHC.Show.Show DataSketches.Quantiles.RelativeErrorQuantile.Types.Criterion
- DataSketches.Quantiles.RelativeErrorQuantile.Types: instance GHC.Show.Show DataSketches.Quantiles.RelativeErrorQuantile.Types.RankAccuracy
- DataSketches.Quantiles.RelativeErrorQuantile.Types: takeSnapshot :: (TakeSnapshot a, PrimMonad m) => a (PrimState m) -> m (Snapshot a)
- DataSketches.Quantiles.RelativeErrorQuantile.Types: }

Files

data-sketches.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack  name:           data-sketches-version:        0.3.0.1+version:        0.3.1.0 description:    Please see the README on GitHub at <https://github.com/iand675/datasketches-haskell#readme> homepage:       https://github.com/iand675/datasketches-haskell#readme bug-reports:    https://github.com/iand675/datasketches-haskell/issues@@ -30,22 +30,13 @@ library   exposed-modules:       DataSketches.Quantiles.RelativeErrorQuantile-      DataSketches.Quantiles.RelativeErrorQuantile.Internal.Auxiliary-      DataSketches.Quantiles.RelativeErrorQuantile.Internal.Compactor-      DataSketches.Quantiles.RelativeErrorQuantile.Internal.Constants-      DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer-      DataSketches.Quantiles.RelativeErrorQuantile.Internal.InequalitySearch-      DataSketches.Quantiles.RelativeErrorQuantile.Internal.URef-      DataSketches.Quantiles.RelativeErrorQuantile.Types   other-modules:       Paths_data_sketches   hs-source-dirs:       src   default-extensions:       BangPatterns-      DataKinds       FlexibleInstances-      KindSignatures       RecordWildCards       ScopedTypeVariables       StandaloneDeriving@@ -53,13 +44,10 @@       TypeOperators   build-depends:       base >=4.7 && <5-    , cereal-    , deepseq+    , data-sketches-core ==0.1.*     , ghc-prim     , mtl     , mwc-random-    , pretty-show-    , prettyprinter     , primitive     , vector     , vector-algorithms@@ -79,9 +67,7 @@       test   default-extensions:       BangPatterns-      DataKinds       FlexibleInstances-      KindSignatures       RecordWildCards       ScopedTypeVariables       StandaloneDeriving@@ -91,16 +77,14 @@   build-depends:       QuickCheck     , base >=4.7 && <5-    , cereal     , data-sketches-    , deepseq+    , data-sketches-core ==0.1.*     , ghc-prim     , hspec     , hspec-discover     , mtl     , mwc-random     , pretty-show-    , prettyprinter     , primitive     , statistics     , vector@@ -116,9 +100,7 @@       bench   default-extensions:       BangPatterns-      DataKinds       FlexibleInstances-      KindSignatures       RecordWildCards       ScopedTypeVariables       StandaloneDeriving@@ -127,15 +109,12 @@   ghc-options: -threaded -rtsopts -with-rtsopts=-N   build-depends:       base >=4.7 && <5-    , cereal     , criterion     , data-sketches-    , deepseq+    , data-sketches-core ==0.1.*     , ghc-prim     , mtl     , mwc-random-    , pretty-show-    , prettyprinter     , primitive     , vector     , vector-algorithms
src/DataSketches/Quantiles/RelativeErrorQuantile.hs view
@@ -55,115 +55,45 @@   , rankAccuracy   , isEstimationMode   , isLessThanOrEqual-  -- * Internals used in test. DO NOT USE.   -- | If you see this error, please file an issue in the GitHub repository.   , CumulativeDistributionInvariants(..)-  , mkAuxiliaryFromReqSketch-  , computeTotalRetainedItems   ) where -import Control.DeepSeq import Control.Monad (when, unless, foldM, foldM_)-import Control.Monad.Primitive-import Control.Monad.Trans+import Control.Monad.Primitive ( PrimMonad(PrimState) ) import Data.Bits (shiftL) import Data.Vector ((!), imapM_) import qualified Data.Vector as Vector import Data.Primitive.MutVar-import Data.Proxy-import Data.Word+    ( modifyMutVar', newMutVar, readMutVar, writeMutVar )+import Data.Word ( Word32, Word64 ) import DataSketches.Quantiles.RelativeErrorQuantile.Internal.Constants+    ( fixRseFactor, initNumberOfSections, relRseFactor ) import DataSketches.Quantiles.RelativeErrorQuantile.Types+    ( Criterion(..), RankAccuracy(..) ) import DataSketches.Quantiles.RelativeErrorQuantile.Internal.Compactor (ReqCompactor) import DataSketches.Quantiles.RelativeErrorQuantile.Internal.Auxiliary (ReqAuxiliary)+import DataSketches.Quantiles.RelativeErrorQuantile.Internal+    ( count,+      retainedItemCount,+      CumulativeDistributionInvariants(..),+      ReqSketch(..),+      computeTotalRetainedItems,+      getCompactors ) import qualified DataSketches.Quantiles.RelativeErrorQuantile.Internal.Auxiliary as Auxiliary import qualified DataSketches.Quantiles.RelativeErrorQuantile.Internal.Compactor as Compactor import qualified DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer as DoubleBuffer-import DataSketches.Quantiles.RelativeErrorQuantile.Internal.URef-import GHC.TypeLits+import DataSketches.Core.Internal.URef+    ( modifyURef, newURef, readURef, writeURef ) import Data.Maybe (isNothing) import qualified Data.Foldable import qualified Data.List import GHC.Exception.Type (Exception) import Control.Exception (throw, assert)-import GHC.Generics import System.Random.MWC (Gen, create) import qualified Data.Vector.Generic.Mutable as MG import Prelude hiding (sum, minimum, maximum, null)-{- |-This Relative Error Quantiles Sketch is the Haskell implementation based on the paper-"Relative Error Streaming Quantiles", https://arxiv.org/abs/2004.01668, and loosely derived from-a Python prototype written by Pavel Vesely, ported from the Java equivalent. -This implementation differs from the algorithm described in the paper in the following:--The algorithm requires no upper bound on the stream length.-Instead, each relative-compactor counts the number of compaction operations performed-so far (via variable state). Initially, the relative-compactor starts with INIT_NUMBER_OF_SECTIONS.-Each time the number of compactions (variable state) exceeds 2^{numSections - 1}, we double-numSections. Note that after merging the sketch with another one variable state may not correspond-to the number of compactions performed at a particular level, however, since the state variable-never exceeds the number of compactions, the guarantees of the sketch remain valid.--The size of each section (variable k and sectionSize in the code and parameter k in-the paper) is initialized with a value set by the user via variable k.-When the number of sections doubles, we decrease sectionSize by a factor of sqrt(2).-This is applied at each level separately. Thus, when we double the number of sections, the-nominal compactor size increases by a factor of approx. sqrt(2) (+/- rounding).--The merge operation here does not perform "special compactions", which are used in the paper-to allow for a tight mathematical analysis of the sketch.--This implementation provides a number of capabilities not discussed in the paper or provided-in the Python prototype.--The Python prototype only implemented high accuracy for low ranks. This implementation-provides the user with the ability to choose either high rank accuracy or low rank accuracy at-the time of sketch construction.--- The Python prototype only implemented a comparison criterion of "<". This implementation-allows the user to switch back and forth between the "<=" criterion and the "<=" criterion.--}-data ReqSketch s = ReqSketch-  { k :: !Word32-  , rankAccuracySetting :: !RankAccuracy-  , criterion :: !Criterion-  , sketchRng :: {-# UNPACK #-} !(Gen s)-  , totalN :: {-# UNPACK #-} !(URef s Word64)-  , minValue :: {-# UNPACK #-} !(URef s Double)-  , maxValue :: {-# UNPACK #-} !(URef s Double)-  , sumValue :: {-# UNPACK #-} !(URef s Double)-  , retainedItems :: {-# UNPACK #-} !(URef s Int)-  , maxNominalCapacitiesSize :: {-# UNPACK #-} !(URef s Int)-  , aux :: {-# UNPACK #-} !(MutVar s (Maybe ReqAuxiliary))-  , compactors :: {-# UNPACK #-} !(MutVar s (Vector.Vector (ReqCompactor s)))-  } deriving (Generic)--instance NFData (ReqSketch s) where-  rnf !rs = ()--instance TakeSnapshot ReqSketch where-  data Snapshot ReqSketch = ReqSketchSnapshot-    { snapshotRankAccuracySetting :: !RankAccuracy-    , snapshotCriterion :: !Criterion-    , snapshotTotalN :: !Word64-    , snapshotMinValue :: !Double-    , snapshotMaxValue :: !Double-    , snapshotRetainedItems :: !Int-    , snapshotMaxNominalCapacitiesSize :: !Int-    -- , aux :: !(MutVar s (Maybe ()))-    , snapshotCompactors :: !(Vector.Vector (Snapshot ReqCompactor))-    }-  takeSnapshot ReqSketch{..} = ReqSketchSnapshot rankAccuracySetting criterion-    <$> readURef totalN-    <*> readURef minValue-    <*> readURef maxValue-    <*> readURef retainedItems-    <*> readURef maxNominalCapacitiesSize-    <*> (readMutVar compactors >>= mapM takeSnapshot)--deriving instance Show (Snapshot ReqSketch)- -- | The K parameter can be increased to trade increased space efficiency for higher accuracy in rank and quantile -- calculations. Due to the way the compaction algorithm works, it must be an even number between 4 and 1024. --@@ -187,19 +117,10 @@   grow r   pure r -mkAuxiliaryFromReqSketch :: PrimMonad m => ReqSketch (PrimState m) -> m ReqAuxiliary-mkAuxiliaryFromReqSketch this = do-  total <- count this-  retainedItems <- retainedItemCount this-  compactors <- getCompactors this-  Auxiliary.mkAuxiliary (rankAccuracySetting this) total retainedItems compactors  getAux :: PrimMonad m => ReqSketch (PrimState m) -> m (Maybe ReqAuxiliary) getAux = readMutVar . aux -getCompactors :: PrimMonad m => ReqSketch (PrimState m) -> m (Vector.Vector (ReqCompactor (PrimState m)))-getCompactors = readMutVar . compactors- getNumLevels :: PrimMonad m => ReqSketch (PrimState m) -> m Int getNumLevels = fmap Vector.length . getCompactors @@ -209,20 +130,9 @@ getK :: ReqSketch s -> Word32 getK = k -retainedItemCount :: PrimMonad m => ReqSketch (PrimState m) -> m Int-retainedItemCount = readURef . retainedItems- getMaxNominalCapacity :: PrimMonad m => ReqSketch (PrimState m) -> m Int getMaxNominalCapacity = readURef . maxNominalCapacitiesSize -data CumulativeDistributionInvariants-  = CumulativeDistributionInvariantsSplitsAreEmpty-  | CumulativeDistributionInvariantsSplitsAreNotFinite-  | CumulativeDistributionInvariantsSplitsAreNotUniqueAndMontonicallyIncreasing-  deriving (Show, Eq)--instance Exception CumulativeDistributionInvariants- validateSplits :: Monad m => [Double] -> m () validateSplits splits = do   when (Data.Foldable.null splits) $ do@@ -313,10 +223,6 @@ maximum :: PrimMonad m => ReqSketch (PrimState m) -> m Double maximum = readURef . maxValue --- | Get the total number of items inserted into the sketch-count :: PrimMonad m => ReqSketch (PrimState m) -> m Word64-count = readURef . totalN- -- | Returns the approximate count of items satisfying the criterion set in the ReqSketch 'criterion' field. countWithCriterion :: (PrimMonad m, s ~ PrimState m) => ReqSketch s -> Double -> m Word64 countWithCriterion s value = fromIntegral <$> do@@ -487,16 +393,6 @@     countNominalCapacity acc compactor = do       nominalCapacity <- Compactor.getNominalCapacity compactor       pure $ nominalCapacity + acc--computeTotalRetainedItems :: PrimMonad m => ReqSketch (PrimState m) -> m Int-computeTotalRetainedItems this = do-  compactors <- getCompactors this-  Vector.foldM countBuffer 0 compactors-  where-    countBuffer acc compactor = do-      buff <- Compactor.getBuffer compactor-      buffSize <- DoubleBuffer.getCount buff-      pure $ buffSize + acc  grow :: (PrimMonad m) => ReqSketch (PrimState m) -> m () grow this = do
− src/DataSketches/Quantiles/RelativeErrorQuantile/Internal/Auxiliary.hs
@@ -1,189 +0,0 @@-module DataSketches.Quantiles.RelativeErrorQuantile.Internal.Auxiliary-  ( ReqAuxiliary(..)-  , MReqAuxiliary (..)-  , mkAuxiliary-  , getQuantile-  -- | Really extra private, just needed for tests-  , mergeSortIn-  ) where--import GHC.TypeLits-import Control.Monad (when)-import Control.Monad.Primitive-import Data.Bits (shiftL)-import Data.Word-import Data.Primitive.MutVar-import Data.Vector.Algorithms.Search-import qualified Data.Vector as Vector-import qualified Data.Vector.Unboxed.Mutable as MUVector-import DataSketches.Quantiles.RelativeErrorQuantile.Types-import DataSketches.Quantiles.RelativeErrorQuantile.Internal.Compactor (ReqCompactor)-import qualified DataSketches.Quantiles.RelativeErrorQuantile.Internal.Compactor as Compactor-import DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer (DoubleBuffer)-import qualified DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer as DoubleBuffer-import qualified Data.Vector.Unboxed as U-import Control.Monad.ST-import DataSketches.Quantiles.RelativeErrorQuantile.Internal.InequalitySearch (find)-import qualified DataSketches.Quantiles.RelativeErrorQuantile.Internal.InequalitySearch as IS-import Debug.Trace-import qualified Data.Vector.Generic.Mutable as MG--data ReqAuxiliary = ReqAuxiliary-  { raWeightedItems :: {-# UNPACK #-} !(U.Vector (Double, Word64))-  , raHighRankAccuracy :: !RankAccuracy-  , raSize :: {-# UNPACK #-} !Word64-  }-  deriving (Show, Eq)--data MReqAuxiliary s = MReqAuxiliary-  { mraWeightedItems :: {-# UNPACK #-} !(MutVar s (MUVector.MVector s (Double, Word64)))-  , mraHighRankAccuracy :: !RankAccuracy-  , mraSize :: {-# UNPACK #-} !Word64-  }--mkAuxiliary :: (PrimMonad m, s ~ PrimState m) => RankAccuracy -> Word64 -> Int -> Vector.Vector (ReqCompactor s) -> m ReqAuxiliary-mkAuxiliary rankAccuracy totalN retainedItems compactors = do-  items <- newMutVar =<< MUVector.replicate retainedItems (0, 0)-  let this = MReqAuxiliary-        { mraWeightedItems = items-        , mraHighRankAccuracy = rankAccuracy-        , mraSize = totalN-        }-  Vector.foldM_ (mergeBuffers this) 0 compactors-  createCumulativeWeights this-  dedup this-  items' <- U.unsafeFreeze =<< readMutVar items-  pure ReqAuxiliary-    { raWeightedItems = items'-    , raHighRankAccuracy = rankAccuracy-    , raSize = totalN-    }-  where-    mergeBuffers this auxCount compactor = do-      buff <- Compactor.getBuffer compactor-      buffSize <-  DoubleBuffer.getCount buff-      let lgWeight = Compactor.getLgWeight compactor-          weight = 1 `shiftL` fromIntegral lgWeight-      mergeSortIn this buff weight auxCount-      pure $ auxCount + buffSize--getWeightedItems :: PrimMonad m => MReqAuxiliary (PrimState m) -> m (MUVector.MVector (PrimState m) (Double, Word64))-getWeightedItems = readMutVar . mraWeightedItems--getItems :: PrimMonad m => MReqAuxiliary (PrimState m) -> m (MUVector.MVector (PrimState m) Double)-getItems = fmap (fst . MUVector.unzip) . getWeightedItems--getWeights :: PrimMonad m => MReqAuxiliary (PrimState m) -> m (MUVector.MVector (PrimState m) Word64)-getWeights = fmap (snd . MUVector.unzip) . getWeightedItems--getQuantile :: ReqAuxiliary -> Double -> Criterion  -> Double-getQuantile this normalRank ltEq = fst (weightedItems U.! ix)-  where-    ix = if searchResult == U.length weightedItems-      then searchResult - 1-      else searchResult-    searchResult = runST $ do-      v <- U.unsafeThaw $ snd $ U.unzip weightedItems-      let search = case ltEq of-            (:<) -> find (IS.:>)-            (:<=) -> find (IS.:>=)-      search v 0 (weightsSize - 1) rank-    weightedItems = raWeightedItems this-    weightsSize = U.length weightedItems-    rank = floor (normalRank * fromIntegral (raSize this))--createCumulativeWeights :: PrimMonad m => MReqAuxiliary (PrimState m) -> m ()-createCumulativeWeights this = do-  weights <- getWeights this-  let size = MUVector.length weights-  let accumulateM i weight = do-        when (i > 0) $ do-          prevWeight <- MUVector.read weights (i - 1)-          MUVector.unsafeWrite weights i (weight + prevWeight)-  forI_ weights (\i -> MUVector.read weights i >>= \x -> accumulateM i x)-  lastWeight <- MUVector.read weights (size - 1)-  when (lastWeight /= mraSize this) $ do-    error "invariant violated: lastWeight does not equal raSize"-  where-    forI_ :: (Monad m, MG.MVector v a) => v (PrimState m) a -> (Int -> m b) -> m ()-    {-# INLINE forI_ #-}-    forI_ v f = loop 0-      where-        loop i -          | i >= n    = return ()-          | otherwise = f i >> loop (i + 1)-        n = MG.length v---dedup :: PrimMonad m => MReqAuxiliary (PrimState m) -> m ()-dedup this = do-  weightedItems <- getWeightedItems this-  let size = MUVector.length weightedItems-  weightedItemsB <- MUVector.replicate size (0, 0)-  bi <- doDedup weightedItems size weightedItemsB 0 0-  writeMutVar (mraWeightedItems this) $ MUVector.slice 0 bi weightedItemsB-  where-    doDedup weightedItems itemsSize weightedItemsB = go-      where -        go !i !bi-          | i >= itemsSize = pure bi-          | otherwise = do-            let j = i + 1-                hidup = j-                countDups !j !hidup = if j < itemsSize -                  then do-                    (itemI, _) <- MUVector.read weightedItems i-                    (itemJ, _) <- MUVector.read weightedItems j-                    if itemI == itemJ-                      then countDups (j + 1) j-                      else pure (j, hidup)-                  else pure (j, hidup)-            (j', hidup') <- countDups j hidup-            if j' - i == 1 -- no dups-              then do-                (item, weight) <- MUVector.read weightedItems i-                MUVector.unsafeWrite weightedItemsB bi (item, weight)-                go (i + 1) (bi + 1)-              else do-                (item, weight) <- MUVector.read weightedItems hidup'-                MUVector.unsafeWrite weightedItemsB bi (item, weight)-                go j' (bi + 1)--mergeSortIn :: PrimMonad m => MReqAuxiliary (PrimState m) -> DoubleBuffer (PrimState m) -> Word64 -> Int -> m ()-mergeSortIn this bufIn defaultWeight auxCount = do-  DoubleBuffer.sort bufIn-  weightedItems <- getWeightedItems this-  otherItems <- DoubleBuffer.getVector bufIn-  otherBuffSize <- DoubleBuffer.getCount bufIn-  otherBuffCapacity <- DoubleBuffer.getCapacity bufIn-  let totalSize = otherBuffSize + auxCount - 1-      height = case mraHighRankAccuracy this of-        HighRanksAreAccurate -> otherBuffCapacity - 1-        LowRanksAreAccurate -> otherBuffSize - 1-  merge totalSize weightedItems otherItems (auxCount - 1) (otherBuffSize - 1) height -  where-    merge totalSize weightedItems otherItems = go totalSize-      where-        go !k !i !j !h -          | k < 0 = pure ()-          | i >= 0 && j >= 0 = do-            (item, weight) <- MUVector.read weightedItems i-            otherItem <- MUVector.read otherItems h-            if item >= otherItem-               then do-                 MUVector.unsafeWrite weightedItems k (item, weight)-                 continue (i - 1) j h-               else do-                 MUVector.unsafeWrite weightedItems k (otherItem, defaultWeight)-                 continue i (j - 1) (h - 1)-          | i >= 0 = do-            MUVector.read weightedItems i >>= MUVector.write weightedItems k-            continue (i - 1) j h-          | j >= 0 = do-            otherItem <- MUVector.read otherItems h-            MUVector.unsafeWrite weightedItems k (otherItem, defaultWeight)-            continue i (j - 1) (h - 1)-          | otherwise = pure ()-          where-            continue = go (k - 1)-
− src/DataSketches/Quantiles/RelativeErrorQuantile/Internal/Compactor.hs
@@ -1,237 +0,0 @@-module DataSketches.Quantiles.RelativeErrorQuantile.Internal.Compactor-  ( ReqCompactor-  , mkReqCompactor-  , CompactorReturn (..)-  , compact-  , getBuffer-  , getCoin-  , getLgWeight-  , getNominalCapacity-  , getNumSections-  , merge-  , nearestEven-  ) where--import GHC.TypeLits-import Data.Bits ((.&.), (.|.), complement, countTrailingZeros, shiftL, shiftR)-import Data.Primitive.MutVar-import Data.Proxy-import Data.Semigroup (Semigroup)-import Data.Word-import DataSketches.Quantiles.RelativeErrorQuantile.Types-import System.Random.MWC (create, Variate(uniform), Gen)-import Control.Exception (assert)-import Control.Monad (when)-import Control.Monad.Trans-import Control.Monad.Primitive-import DataSketches.Quantiles.RelativeErrorQuantile.Internal.Constants-import DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer-import DataSketches.Quantiles.RelativeErrorQuantile.Internal.URef--data CompactorReturn s = CompactorReturn-  { crDeltaRetItems :: {-# UNPACK #-} !Int-  , crDeltaNominalSize :: {-# UNPACK #-} !Int-  , crDoubleBuffer :: {-# UNPACK #-} !(DoubleBuffer s)-  }--data ReqCompactor s = ReqCompactor-  -- Configuration constants-  { rcRankAccuracy :: !RankAccuracy-  , rcLgWeight :: {-# UNPACK #-} !Word8-  , rcRng :: {-# UNPACK #-} !(Gen s)-  -- State-  , rcState :: {-# UNPACK #-} !(URef s Word64)-  , rcLastFlip :: {-# UNPACK #-} !(URef s Bool)-  , rcSectionSizeFlt :: {-# UNPACK #-} !(URef s Double)-  , rcSectionSize :: {-# UNPACK #-} !(URef s Word32)-  , rcNumSections :: {-# UNPACK #-} !(URef s Word8)-  , rcBuffer :: {-# UNPACK #-} !(MutVar s (DoubleBuffer s))-  }--instance TakeSnapshot ReqCompactor where-  data Snapshot ReqCompactor = ReqCompactorSnapshot-    { snapshotCompactorRankAccuracy :: !RankAccuracy-    , snapshotCompactorRankAccuracyState :: !Word64-    , snapshotCompactorLastFlip :: !Bool-    , snapshotCompactorSectionSizeFlt :: !Double-    , snapshotCompactorSectionSize :: !Word32-    , snapshotCompactorNumSections :: !Word8-    , snapshotCompactorBuffer :: !(Snapshot DoubleBuffer)-    }-  takeSnapshot ReqCompactor{..} = ReqCompactorSnapshot rcRankAccuracy-    <$> readURef rcState-    <*> readURef rcLastFlip-    <*> readURef rcSectionSizeFlt-    <*> readURef rcSectionSize-    <*> readURef rcNumSections-    <*> (readMutVar rcBuffer >>= takeSnapshot)--deriving instance Show (Snapshot ReqCompactor)--mkReqCompactor-  :: PrimMonad m-  => Gen (PrimState m)-  -> Word8-  -> RankAccuracy-  -> Word32-  -> m (ReqCompactor (PrimState m))-mkReqCompactor g lgWeight rankAccuracy sectionSize = do-  let nominalCapacity = fromIntegral $ nomCapMulti * initNumberOfSections * sectionSize-  buff <- mkBuffer (nominalCapacity * 2) nominalCapacity (rankAccuracy == HighRanksAreAccurate)-  ReqCompactor rankAccuracy lgWeight g-    <$> newURef 0-    <*> newURef False-    <*> newURef (fromIntegral sectionSize)-    <*> newURef sectionSize-    <*> newURef initNumberOfSections-    <*> newMutVar buff--nomCapMult :: Num a => a-nomCapMult = 2--toInt :: Integral a => a -> Int-toInt = fromIntegral--compact :: (PrimMonad m) => ReqCompactor (PrimState m) -> m (CompactorReturn (PrimState m))-compact this = do-  startBuffSize <- getCount =<< getBuffer this-  startNominalCapacity <- getNominalCapacity this-  numSections <- readURef $ rcNumSections this-  sectionSize <- readURef $ rcSectionSize this-  state <- readURef $ rcState this-  let trailingOnes = succ $ countTrailingZeros $ complement state-      sectionsToCompact = min trailingOnes $ fromIntegral numSections-  (compactionStart, compactionEnd) <- computeCompactionRange this sectionsToCompact-  -- TODO, this fails in GHCi but not in tests?-  assert (compactionEnd - compactionStart >= 2) $ do-    coin <- if state .&. 1 == 1-      then fmap not $ readURef $ rcLastFlip this-      else flipCoin this-    writeURef (rcLastFlip this) coin-    buff <- getBuffer this-    promote <- getEvensOrOdds buff compactionStart compactionEnd coin-    trimCount buff $ startBuffSize - (compactionEnd - compactionStart)-    modifyURef (rcState this) (+ 1)-    ensureEnoughSections this-    endBuffSize <- getCount buff-    promoteBuffSize <- getCount promote-    endNominalCapacity <- getNominalCapacity this-    pure $ CompactorReturn-      { crDeltaRetItems = endBuffSize - startBuffSize + promoteBuffSize-      , crDeltaNominalSize = endNominalCapacity - startNominalCapacity-      , crDoubleBuffer = promote-      }--getLgWeight :: ReqCompactor s -> Word8-getLgWeight = rcLgWeight--getBuffer :: PrimMonad m => ReqCompactor (PrimState m) -> m (DoubleBuffer (PrimState m))-getBuffer = readMutVar . rcBuffer--flipCoin :: (PrimMonad m) => ReqCompactor (PrimState m) -> m Bool-flipCoin = uniform . rcRng--getCoin :: PrimMonad m => ReqCompactor (PrimState m) -> m Bool-getCoin = readURef . rcLastFlip--getNominalCapacity :: PrimMonad m => ReqCompactor (PrimState m) -> m Int-getNominalCapacity compactor = do-  numSections <- readURef $ rcNumSections compactor-  sectionSize <- readURef $ rcSectionSize compactor-  pure $ nomCapMult * toInt numSections * toInt sectionSize--getNumSections :: PrimMonad m => ReqCompactor (PrimState m) -> m Word8-getNumSections = readURef . rcNumSections--getSectionSizeFlt :: PrimMonad m => ReqCompactor (PrimState m) -> m Double-getSectionSizeFlt = readURef . rcSectionSizeFlt--getState :: PrimMonad m => ReqCompactor (PrimState m) -> m Word64-getState = readURef . rcState---- | Merge the other given compactor into this one. They both must have the--- same @lgWeight@-merge-  :: (PrimMonad m, s ~ PrimState m)-  => ReqCompactor (PrimState m)-  -- ^ The compactor to merge into-  -> ReqCompactor (PrimState m)-  -- ^ The compactor to merge from -  -> m (ReqCompactor s)-merge this otherCompactor = assert (rcLgWeight this == rcLgWeight otherCompactor) $ do-  otherState <- readURef $ rcState otherCompactor-  modifyURef (rcState this) (.|. otherState)-  ensureMaxSections--  buff <- getBuffer this-  sort buff--  otherBuff <- getBuffer otherCompactor-  sort otherBuff--  otherBuffIsBigger <- (>) <$> getCount otherBuff <*> getCount buff-  finalBuff <- if otherBuffIsBigger-     then do-        otherBuff' <- copyBuffer otherBuff-        mergeSortIn otherBuff' buff-        writeMutVar (rcBuffer this) otherBuff'-     else mergeSortIn buff otherBuff-  pure this-  where-    ensureMaxSections = do-      adjusted <- ensureEnoughSections this-      -- loop until no adjustments can be made-      when adjusted ensureMaxSections---- | Adjust the sectionSize and numSections if possible.-ensureEnoughSections-  :: PrimMonad m-  => ReqCompactor (PrimState m)-  -> m Bool-  -- ^ 'True' if the SectionSize and NumSections were adjusted.-ensureEnoughSections compactor = do-  sectionSizeFlt <- readURef $ rcSectionSizeFlt compactor-  let szf = sectionSizeFlt / sqrt2-      ne = nearestEven szf-  state <- readURef $ rcState compactor-  numSections <- readURef $ rcNumSections compactor-  sectionSize <- readURef $ rcSectionSize compactor-  if state >= (1 `shiftL` toInt (numSections - 1))-     && sectionSize > minK-     && ne >= minK-     then do-       writeURef (rcSectionSizeFlt compactor) szf-       writeURef (rcSectionSize compactor) $ fromIntegral ne-       modifyURef (rcNumSections compactor) (`shiftL` 1)-       buf <- getBuffer compactor-       nomCapacity <- getNominalCapacity compactor-       ensureCapacity buf (2 * nomCapacity)-       pure True-     else pure False---- | Computes the start and end indices of the compacted region-computeCompactionRange-  :: PrimMonad m-  => ReqCompactor (PrimState m)-  -> Int-  -- ^ secsToCompact the number of contiguous sections to compact-  -> m (Int, Int)--- ^ the start and end indices of the compacted region in compact form-computeCompactionRange this secsToCompact = do-  buffSize <- getCount =<< getBuffer this-  nominalCapacity <- getNominalCapacity this-  numSections <- readURef $ rcNumSections this-  sectionSize <- readURef $ rcSectionSize this-  let nonCompact = (nominalCapacity `div` 2) + (fromIntegral numSections - secsToCompact) * fromIntegral sectionSize-      nonCompact' = if (buffSize - nonCompact) .&. 1 == 1 then nonCompact - 1 else nonCompact-  pure $ case rcRankAccuracy this of-    HighRanksAreAccurate -> (0, fromIntegral $ buffSize - nonCompact')-    LowRanksAreAccurate -> (nonCompact', buffSize)---- | Returns the nearest even integer to the given value. Also used by test.-nearestEven-  :: Double-  -- ^ the given value-  -> Int-  -- ^ the nearest even integer to the given value.-nearestEven x = round (x / 2) `shiftL` 1
− src/DataSketches/Quantiles/RelativeErrorQuantile/Internal/Constants.hs
@@ -1,21 +0,0 @@-module DataSketches.Quantiles.RelativeErrorQuantile.Internal.Constants where--- Constants-import Data.Word--sqrt2 :: Double -sqrt2 = sqrt 2--initNumberOfSections :: Num a => a-initNumberOfSections = 3--minK :: Num a => a-minK = 4--nomCapMulti :: Num a => a-nomCapMulti = 2--relRseFactor :: Double-relRseFactor = sqrt (0.0512 / fromIntegral initNumberOfSections)--fixRseFactor :: Double-fixRseFactor = 0.084
− src/DataSketches/Quantiles/RelativeErrorQuantile/Internal/DoubleBuffer.hs
@@ -1,319 +0,0 @@-{-# LANGUAGE MagicHash #-}-{-# LANGUAGE UnboxedTuples #-}-module DataSketches.Quantiles.RelativeErrorQuantile.Internal.DoubleBuffer-  ( DoubleBuffer-  , Capacity-  , GrowthIncrement-  , SpaceAtBottom-  , DoubleIsNonFiniteException(..)-  , mkBuffer-  , copyBuffer-  , append-  , ensureCapacity-  , getCountWithCriterion-  , getEvensOrOdds-  , (!) -- getItem-  , growthIncrement-  , spaceAtBottom-  , getCapacity-  , getCount-  , getSpace-  , getVector-  , isEmpty-  , isSorted-  , sort-  , mergeSortIn-  , trimCount-  ) where--import DataSketches.Quantiles.RelativeErrorQuantile.Types-import Control.Monad-import Control.Monad.Primitive-import Control.Monad.Reader.Class-import Data.Primitive.MutVar-import qualified Data.Vector.Unboxed as UVector-import qualified Data.Vector.Unboxed.Mutable as MUVector-import DataSketches.Quantiles.RelativeErrorQuantile.Internal.URef-import Data.Vector.Algorithms.Intro (sortByBounds)-import Data.Vector.Algorithms.Search-import GHC.Prim-import GHC.Stack-import System.IO.Unsafe ()-import qualified DataSketches.Quantiles.RelativeErrorQuantile.Internal.InequalitySearch as IS-import Control.Exception---- | A special buffer of floats specifically designed to support the ReqCompactor class.-data DoubleBuffer s = DoubleBuffer-  { vec :: {-# UNPACK #-} !(MutVar s (MUVector.MVector s Double))-  , count :: {-# UNPACK #-} !(URef s Int)-  , sorted :: {-# UNPACK #-} !(URef s Bool)-  , growthIncrement :: {-# UNPACK #-} !Int-  , spaceAtBottom :: !Bool-  }--instance TakeSnapshot DoubleBuffer where-  data Snapshot DoubleBuffer = DoubleBufferSnapshot-    { dbSnapshotVec :: UVector.Vector Double-    , dbSnapshotCount :: !Int-    , dbSnapshotSorted :: !Bool-    , dbSnapshotGrowthIncrement :: !Int-    , dbSnapshotSpaceAtBottom :: !Bool-    }-  takeSnapshot DoubleBuffer{..} = DoubleBufferSnapshot-    <$> (readMutVar vec >>= UVector.freeze)-    <*> readURef count-    <*> readURef sorted-    <*> pure growthIncrement-    <*> pure spaceAtBottom--deriving instance Show (Snapshot DoubleBuffer)--type Capacity = Int-type GrowthIncrement = Int-type SpaceAtBottom = Bool---- | Constructs an new empty FloatBuffer with an initial capacity specified by--- the <code>capacity</code> argument.-mkBuffer :: PrimMonad m => Capacity -> GrowthIncrement -> SpaceAtBottom -> m (DoubleBuffer (PrimState m))-mkBuffer capacity_ growthIncrement spaceAtBottom = do-  vec <- newMutVar =<< MUVector.new capacity_-  count <- newURef 0-  sorted <- newURef True-  pure $ DoubleBuffer{..}--copyBuffer :: PrimMonad m => DoubleBuffer (PrimState m) -> m (DoubleBuffer (PrimState m))-copyBuffer buf@DoubleBuffer{..} = do-  vec <- newMutVar =<< MUVector.clone =<< getVector buf-  count <- newURef =<< getCount buf-  sorted <- newURef =<< readURef sorted-  pure $ DoubleBuffer {..}---- | Appends the given item to the active array and increments the active count.--- This will expand the array if necessary.-append :: PrimMonad m => DoubleBuffer (PrimState m) -> Double -> m ()-append buf@DoubleBuffer{..} x = do-  ensureSpace buf 1-  index <- if spaceAtBottom-    then-      (\capacity_ count_ -> capacity_ - count_ - 1)-        <$> getCapacity buf-        <*> getCount buf-    else readURef count-  modifyURef count (+ 1)-  getVector buf >>= \vec -> MUVector.unsafeWrite vec index x-  writeURef sorted False-{-# SCC append #-}---- | Ensures that the capacity of this FloatBuffer is at least newCapacity.--- If newCapacity &lt; capacity(), no action is taken.-ensureSpace :: PrimMonad m => DoubleBuffer (PrimState m) -> Int -> m ()-ensureSpace buf@DoubleBuffer{..} space = do-  count_ <- readURef count-  capacity_ <- getCapacity buf-  let notEnoughSpace = count_ + space > capacity_-  when notEnoughSpace $ do-    let newCap = count_ + space + growthIncrement-    ensureCapacity buf newCap--getVector :: (PrimMonad m, PrimState m ~ s) => DoubleBuffer s -> m (MUVector.MVector s Double)-getVector = readMutVar . vec-{-# INLINE getVector #-}--getCapacity :: PrimMonad m => DoubleBuffer (PrimState m) -> m Int-getCapacity = fmap MUVector.length . getVector-{-# INLINE getCapacity #-}--ensureCapacity :: PrimMonad m => DoubleBuffer (PrimState m) -> Int -> m ()-ensureCapacity buf@DoubleBuffer{..} newCapacity = do-  capacity_ <- getCapacity buf-  when (newCapacity > capacity_) $ do-    count_ <- getCount buf-    (srcPos, destPos) <- if spaceAtBottom-      then do-        pure (capacity_ - count_, newCapacity - count_)-      else pure (0, 0)-    oldVec <- getVector buf-    newVec <- MUVector.new newCapacity-    MUVector.unsafeCopy-      (MUVector.slice destPos count_ newVec)-      (MUVector.slice srcPos count_ oldVec)-    writeMutVar vec newVec-{-# SCC ensureCapacity #-}--newtype DoubleIsNonFiniteException = DoubleIsNonFiniteException Double-  deriving (Show, Eq)--instance Exception DoubleIsNonFiniteException--getCountWithCriterion :: PrimMonad m => DoubleBuffer (PrimState m) -> Double -> Criterion -> m Int-getCountWithCriterion buf@DoubleBuffer{..} value criterion = do-  when (isNaN value || isInfinite value) $ throw $ DoubleIsNonFiniteException value-  sort buf-  count_ <- getCount buf-  vec <- getVector buf-  (low, high) <- if spaceAtBottom-    then do-      capacity_ <- getCapacity buf-      pure (capacity_ - count_, capacity_ - 1)-    else pure (0, count_)--  ix <- IS.find criterion vec low high value-  pure $! if ix == MUVector.length vec-    then 0-    else ix - low + 1---- data EvensOrOdds = Evens | Odds--getEvensOrOdds :: PrimMonad m => DoubleBuffer (PrimState m) -> Int -> Int -> Bool -> m (DoubleBuffer (PrimState m))-getEvensOrOdds buf@DoubleBuffer{..} startOffset endOffset odds = do-  (start, end) <- if spaceAtBottom-    then do-      basis <- (-) <$> getCapacity buf <*> getCount buf-      pure (basis + startOffset, basis + endOffset)-    else pure (startOffset, endOffset)-  sort buf-  let range = endOffset - startOffset-  vec <- getVector buf-  out <- MUVector.new (range `div` 2)-  go vec out start 0-  where-    odd = if odds then 1 else 0-    go vec !out !i !j = if j < MUVector.length out-      then do-        MUVector.unsafeWrite out j =<< MUVector.unsafeRead vec (i + odd)-        go vec out (i + 2) (j + 1)-      else do-        count <- newURef (MUVector.length out)-        sorted <- newURef True-        vec <- newMutVar out-        pure DoubleBuffer-          { vec = vec-          , count = count-          , sorted = sorted-          , growthIncrement = 0-          , spaceAtBottom = spaceAtBottom-          }-{-# SCC getEvensOrOdds #-}---(!) :: PrimMonad m => DoubleBuffer (PrimState m) -> Int -> m Double-(!) buf offset = do-  index <- if spaceAtBottom buf-    then do-      capacity_ <- getCapacity buf-      count_ <- getCount buf-      pure $! capacity_ - count_ + offset-    else pure offset-  vec <- getVector buf-  MUVector.read vec index--getCount :: PrimMonad m => DoubleBuffer (PrimState m) -> m Int-getCount = readURef . count--getSpace :: PrimMonad m => DoubleBuffer (PrimState m) -> m Int-getSpace buf@DoubleBuffer{..} = (-) <$> getCapacity buf <*> getCount buf--isEmpty :: PrimMonad m => DoubleBuffer (PrimState m) -> m Bool-isEmpty buf = (== 0) <$> getCount buf--isSorted :: PrimMonad m => DoubleBuffer (PrimState m) -> m Bool-isSorted = readURef . sorted---- | Sorts the active region-sort :: PrimMonad m => DoubleBuffer (PrimState m) -> m ()-sort buf@DoubleBuffer{..} = do-  sorted_ <- isSorted buf-  unless sorted_ $ do-    capacity_ <- getCapacity buf-    count_ <- getCount buf-    let (start, end) = if spaceAtBottom-          then (capacity_ - count_, capacity_)-          else (0, count_)-    vec <- getVector buf-    sortByBounds compare vec start end-    writeURef sorted True-{-# SCC sort #-}---- | Merges the incoming sorted buffer into this sorted buffer.-mergeSortIn :: (PrimMonad m, HasCallStack) => DoubleBuffer (PrimState m) -> DoubleBuffer (PrimState m) -> m ()-mergeSortIn this bufIn = do-  sort this-  sort bufIn--  thatBuf <- getVector bufIn-  bufInLen <- getCount bufIn--  ensureSpace this bufInLen-  count_ <- getCount this-  let totalLength = count_ + bufInLen--  thisBuf <- getVector this--  if spaceAtBottom this-    then do -- scan up, insert at bottom-      capacity_ <- getCapacity this-      bufInCapacity_ <- getCapacity bufIn-      inSs <- takeSnapshot bufIn-      let i = capacity_ - count_-      let j = bufInCapacity_ - bufInLen-      let targetStart = capacity_ - totalLength-      let k = targetStart-      mergeUpwards thisBuf thatBuf capacity_ bufInCapacity_ i j k-    else do -- scan down, insert at top-      let i = count_ - 1-      let j = bufInLen - 1-      let k = totalLength-      mergeDownwards thisBuf thatBuf i j (k - 1)--  modifyURef (count this) (+ bufInLen)-  writeURef (sorted this) True-  pure ()-  where-    mergeUpwards thisBuf thatBuf capacity_ bufInCapacity_ = go-      where-        go !i !j !k-          -- for loop ended-          | k >= capacity_ = pure ()-          -- both valid-          | i < capacity_ && j < bufInCapacity_ = do-            iVal <- MUVector.read thisBuf i-            jVal <- MUVector.read thatBuf j-            if iVal <= jVal-              then MUVector.unsafeWrite thisBuf k iVal >> go (i + 1) j (k + 1)-              else MUVector.unsafeWrite thisBuf k jVal >> go i (j + 1) (k + 1)-          -- i is valid-          | i < capacity_ = do-            MUVector.unsafeWrite thisBuf k =<< MUVector.read thisBuf i-            go (i + 1) j (k + 1)-          -- j is valid-          | j < bufInCapacity_ = do-            MUVector.unsafeWrite thisBuf k =<< MUVector.read thatBuf j-            go i (j + 1) (k + 1)-          -- neither is valid, break;-          | otherwise = pure ()-    mergeDownwards thisBuf thatBuf !i !j !k-      -- for loop ended-      | k < 0 = pure ()-      -- both valid-      | i >= 0 && j >= 0 = do-        iVal <- MUVector.read thisBuf i-        jVal <- MUVector.read thatBuf j-        if iVal >= jVal-          then do-            MUVector.unsafeWrite thisBuf k iVal >> continue (i - 1) j (k - 1)-          else do-            MUVector.unsafeWrite thisBuf k jVal >> continue i (j - 1) (k - 1)-      | i >= 0 = do-        MUVector.unsafeWrite thisBuf k =<< MUVector.read thisBuf i-        continue (i - 1) j (k - 1)-      | j >= 0 = do-        MUVector.unsafeWrite thisBuf k =<< MUVector.read thatBuf j-        continue i (j - 1) (k - 1)-      -- neither is valid, break;-      | otherwise = pure ()-      where-        continue = mergeDownwards thisBuf thatBuf-{-# SCC mergeSortIn #-}--trimCount :: PrimMonad m => DoubleBuffer (PrimState m) -> Int -> m ()-trimCount DoubleBuffer{..} newCount = modifyURef count (\oldCount -> if newCount < oldCount then newCount else oldCount)
− src/DataSketches/Quantiles/RelativeErrorQuantile/Internal/InequalitySearch.hs
@@ -1,121 +0,0 @@-module DataSketches.Quantiles.RelativeErrorQuantile.Internal.InequalitySearch where--import Control.Monad.Primitive-import Data.Vector.Generic.Mutable (MVector)-import qualified Data.Vector.Generic.Mutable as MV--data (:<) = (:<)-data (:<=) = (:<=)-data (:>) = (:>)-data (:>=) = (:>=)--- JavaDoc copypasta--- --- This provides efficient, unique and unambiguous binary searching for inequality comparison criteria---  for ordered arrays of values that may include duplicate values. The inequality criteria include---  <, >, ==, >=, <=. All the inequality criteria use the same search algorithm.---  (Although == is not an inequality, it is included for convenience.)----  In order to make the searching unique and unambiguous, we modified the traditional binary---  search algorithm to search for adjacent pairs of values <i>{A, B}</i> in the values array---  instead of just a single value, where <i>A</i> and <i>B</i> are the array indicies of two---  adjacent values in the array. For all the search criteria, if the algorithm reaches the ends of---  the search range, the algorithm calls the <i>resolve()</i> method to determine what to---   return to the caller. If the key value cannot be resolved, it returns a -1 to the caller.----  Given an array of values <i>arr[]</i> and the search key value <i>v</i>, the algorithms for---  the searching criteria are as follows:</p>--- ---  <li><b>LT:</b> Find the highest ranked adjacent pair <i>{A, B}</i> such that:<br>---  <i>arr[A] &lt; v &le; arr[B]</i>. The normal return is the index <i>A</i>.---  </li>---  <li><b>LE:</b>  Find the highest ranked adjacent pair <i>{A, B}</i> such that:<br>---  <i>arr[A] &le; v &lt; arr[B]</i>. The normal return is the index <i>A</i>.---  </li>---  <li><b>EQ:</b>  Find the adjacent pair <i>{A, B}</i> such that:<br>---  <i>arr[A] &le; v &le; arr[B]</i>. The normal return is the index <i>A</i> or <i>B</i> whichever---  equals <i>v</i>, otherwise it returns -1.---  </li>---  <li><b>GE:</b>  Find the lowest ranked adjacent pair <i>{A, B}</i> such that:<br>---  <i>arr[A] &lt; v &le; arr[B]</i>. The normal return is the index <i>B</i>.---  </li>---  <li><b>GT:</b>  Find the lowest ranked adjacent pair <i>{A, B}</i> such that:<br>---  <i>arr[A] &le; v &lt; arr[B]</i>. The normal return is the index <i>B</i>.---  </li>---  </ul>-class InequalitySearch s where-  inequalityCompare :: Ord a-    => s-    -> a -    -- ^ V-    -> a-    -- ^ A-    -> a-    -- ^ B-    -> Ordering-    -- ^ 'GT' means we must search higher in the array, 'LT' means we must-    -- search lower in the array, or `EQ`, which means we have found -    -- the correct bounding pair.-  getIndex -    :: (PrimMonad m, MVector v a, Ord a) -    => s -    -> v (PrimState m) a -    -> Int -    -> Int -    -> a -    -> m Int-  resolve -    :: s -    -> Int -- Vector length-    -> (Int, Int) -    -- ^ Final low index, high index (lo, hi)-    -> (Int, Int) -    -- ^ Initial search region (low, high)-    -> Int-    -- ^ A thing--instance InequalitySearch (:<) where-  inequalityCompare _ v a b -    | v <= a = LT-    | b < v = GT-    | otherwise = EQ-  getIndex _ _ a _ _ = pure a-  resolve _ vl (lo, hi) (low, high) = if lo >= high then high else vl--instance InequalitySearch (:<=) where-  inequalityCompare _ v a b-    | v < a = LT-    | b <= v = GT-    | otherwise = EQ-  getIndex _ _ a _ _ = pure a-  resolve _ vl (lo, hi) (low, high) = if lo >= high then high else vl --instance InequalitySearch (:>) where-  inequalityCompare _ v a b-    | v < a = LT-    | b <= v = GT-    | otherwise = EQ-  getIndex _ _ _ b _ = pure b-  resolve _ vl (lo, hi) (low, high) = if hi <= low then low else vl--instance InequalitySearch (:>=) where-  inequalityCompare _ v a b-    | v <= a = LT-    | b < v = GT-    | otherwise = EQ-  getIndex _ _ _ b _ = pure b-  resolve _ vl (lo, hi) (low, high) = if hi <= low then low else vl--find :: (InequalitySearch s, PrimMonad m, MVector v a, Ord a) => s -> v (PrimState m) a -> Int -> Int -> a -> m Int-find strat v low high x = go low (high - 1)-  where-    go lo hi -      | lo <= hi && lo < high = do-          let mid = lo + ((hi - lo) `div` 2)-          midV <- MV.read v mid-          midV' <- MV.read v (mid + 1)-          case inequalityCompare strat x midV midV' of-            LT -> go lo (mid - 1)-            EQ -> getIndex strat v mid (mid + 1) x-            GT -> go (mid + 1) hi-      | otherwise = pure $! resolve strat (MV.length v) (lo, hi) (low, high)-{-# INLINE find #-}
− src/DataSketches/Quantiles/RelativeErrorQuantile/Internal/URef.hs
@@ -1,49 +0,0 @@-module DataSketches.Quantiles.RelativeErrorQuantile.Internal.URef where--import Control.Monad.Primitive-import qualified Data.Vector.Unboxed.Mutable as MUVector-import Data.Vector.Unboxed (Unbox)---- | An unboxed reference. This works like an 'IORef', but the data is--- stored in a bytearray instead of a heap object, avoiding--- significant allocation overhead in some cases. For a concrete--- example, see this Stack Overflow question:--- <https://stackoverflow.com/questions/27261813/why-is-my-little-stref-int-require-allocating-gigabytes>.------ The first parameter is the state token type, the same as would be--- used for the 'ST' monad. If you're using an 'IO'-based monad, you--- can use the convenience 'IOURef' type synonym instead.------ @since 0.0.2.0-newtype URef s a = URef (MUVector.MVector s a)---- | Helpful type synonym for using a 'URef' from an 'IO'-based stack.------ @since 0.0.2.0-type IOURef = URef (PrimState IO)---- | Create a new 'URef'------ @since 0.0.2.0-newURef :: (PrimMonad m, Unbox a) => a -> m (URef (PrimState m) a)-newURef a = fmap URef (MUVector.replicate 1 a)---- | Read the value in a 'URef'------ @since 0.0.2.0-readURef :: (PrimMonad m, Unbox a) => URef (PrimState m) a -> m a-readURef (URef v) = MUVector.read v 0---- | Write a value into a 'URef'. Note that this action is strict, and--- will force evalution of the value.------ @since 0.0.2.0-writeURef :: (PrimMonad m, Unbox a) => URef (PrimState m) a -> a -> m ()-writeURef (URef v) = MUVector.unsafeWrite v 0---- | Modify a value in a 'URef'. Note that this action is strict, and--- will force evaluation of the result value.------ @since 0.0.2.0-modifyURef :: (PrimMonad m, Unbox a) => URef (PrimState m) a -> (a -> a) -> m ()-modifyURef u f = readURef u >>= writeURef u . f
− src/DataSketches/Quantiles/RelativeErrorQuantile/Types.hs
@@ -1,29 +0,0 @@-module DataSketches.Quantiles.RelativeErrorQuantile.Types where-import Control.Monad.Primitive-import qualified DataSketches.Quantiles.RelativeErrorQuantile.Internal.InequalitySearch as IS--data Criterion = (:<) | (:<=)-  deriving (Show, Eq)--instance IS.InequalitySearch Criterion where-  inequalityCompare c = case c of-    (:<) -> IS.inequalityCompare (IS.:<)-    (:<=) -> IS.inequalityCompare(IS.:<=)-  resolve c = case c of-    (:<) -> IS.resolve (IS.:<)-    (:<=) -> IS.resolve (IS.:<=)-  getIndex c = case c of-    (:<) -> IS.getIndex (IS.:<)-    (:<=) -> IS.getIndex (IS.:<=)---data RankAccuracy -  = HighRanksAreAccurate -  -- ^ High ranks are prioritized for better accuracy.-  | LowRanksAreAccurate-  -- ^ Low ranks are prioritized for better accuracy-  deriving (Show, Eq)--class TakeSnapshot a where-  data Snapshot a-  takeSnapshot :: PrimMonad m => a (PrimState m) -> m (Snapshot a)
test/RelativeErrorQuantileSpec.hs view
@@ -8,6 +8,7 @@ import Control.Monad.Primitive import DataSketches.Quantiles.RelativeErrorQuantile import DataSketches.Quantiles.RelativeErrorQuantile.Types+import DataSketches.Quantiles.RelativeErrorQuantile.Internal import DataSketches.Quantiles.RelativeErrorQuantile.Internal.Auxiliary import Data.List hiding (insert) import Data.Maybe (fromJust, isJust)