-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | An approximate streaming (constant space) unique object counter
--   
--   This package provides an approximate streaming (constant space) unique
--   object counter.
--   
--   See the original paper for details:
--   <a>http://algo.inria.fr/flajolet/Publications/FlFuGaMe07.pdf</a>
--   
--   Notably it can be used to approximate a set of several billion
--   elements with 1-2% inaccuracy in around 1.5k of memory.
@package hyperloglog
@version 0.4.2


module Data.HyperLogLog.Config
numBuckets :: Integer -> Int
smallRange :: Integer -> Double
interRange :: Double
rawFact :: Integer -> Double
alpha :: Integer -> Double
bucketMask :: Integer -> Word32
type Rank = Int8
calcBucket :: Integer -> Word32 -> Int
calcRank :: Integer -> Word32 -> Int8
lim32 :: Double


-- | This package provides an approximate streaming (constant space) unique
--   object counter.
--   
--   See the original paper for details:
--   <a>http://algo.inria.fr/flajolet/Publications/FlFuGaMe07.pdf</a>
module Data.HyperLogLog.Type

-- | Initialize a new counter:
--   
--   <pre>
--   &gt;&gt;&gt; runHyperLogLog (mempty :: HyperLogLog 3) == V.fromList [0,0,0,0,0,0,0,0]
--   True
--   </pre>
--   
--   Please note how you specify a counter size with the <tt>n</tt>
--   invocation. Sizes of up to 16 are valid, with 7 being a likely good
--   minimum for decent accuracy.
--   
--   Let's count a list of unique items and get the latest estimate:
--   
--   <pre>
--   &gt;&gt;&gt; size (foldr insert mempty [1..10] :: HyperLogLog 4)
--   Approximate {_confidence = 0.9972, _lo = 2, _estimate = 9, _hi = 17}
--   </pre>
--   
--   Note how <a>insert</a> can be used to add new observations to the
--   approximate counter.
newtype HyperLogLog p
HyperLogLog :: Vector Rank -> HyperLogLog p
[runHyperLogLog] :: HyperLogLog p -> Vector Rank
class HasHyperLogLog a p | a -> p
hyperLogLog :: HasHyperLogLog a p => Lens' a (HyperLogLog p)

-- | Approximate size of our set
size :: Reifies p Integer => HyperLogLog p -> Approximate Int64
insert :: (Reifies s Integer, Serial a) => a -> HyperLogLog s -> HyperLogLog s

-- | Insert a value that has already been hashed by whatever user defined
--   hash function you want.
insertHash :: Reifies s Integer => Word32 -> HyperLogLog s -> HyperLogLog s
intersectionSize :: Reifies p Integer => [HyperLogLog p] -> Approximate Int64
cast :: forall p q. (Reifies p Integer, Reifies q Integer) => HyperLogLog p -> Maybe (HyperLogLog q)

-- | If two types <tt>p</tt> and <tt>q</tt> reify the same configuration,
--   then we can coerce between <tt><a>HyperLogLog</a> p</tt> and
--   <tt><a>HyperLogLog</a> q</tt>. We do this by building a hole in the
--   <tt>nominal</tt> role for the configuration parameter.
coerceConfig :: forall p q. (Reifies p Integer, Reifies q Integer) => Maybe (Coercion (HyperLogLog p) (HyperLogLog q))
instance forall k (p :: k). Control.DeepSeq.NFData (Data.HyperLogLog.Type.HyperLogLog p)
instance forall k (p :: k). GHC.Generics.Generic (Data.HyperLogLog.Type.HyperLogLog p)
instance forall k (p :: k). GHC.Show.Show (Data.HyperLogLog.Type.HyperLogLog p)
instance forall k (p :: k). GHC.Classes.Eq (Data.HyperLogLog.Type.HyperLogLog p)
instance forall k (p :: k). Data.HyperLogLog.Type.HasHyperLogLog (Data.HyperLogLog.Type.HyperLogLog p) p
instance forall k (p :: k). Data.Serialize.Serialize (Data.HyperLogLog.Type.HyperLogLog p)
instance forall k (p :: k). Data.Bytes.Serial.Serial (Data.HyperLogLog.Type.HyperLogLog p)
instance forall k (p :: k). Data.Binary.Class.Binary (Data.HyperLogLog.Type.HyperLogLog p)
instance forall k (p :: k). GHC.Base.Semigroup (Data.HyperLogLog.Type.HyperLogLog p)
instance forall k (p :: k). Data.Reflection.Reifies p GHC.Integer.Type.Integer => GHC.Base.Monoid (Data.HyperLogLog.Type.HyperLogLog p)


-- | See the original paper for details:
--   <a>http://algo.inria.fr/flajolet/Publications/FlFuGaMe07.pdf</a>
module Data.HyperLogLog

-- | Initialize a new counter:
--   
--   <pre>
--   &gt;&gt;&gt; runHyperLogLog (mempty :: HyperLogLog 3) == V.fromList [0,0,0,0,0,0,0,0]
--   True
--   </pre>
--   
--   Please note how you specify a counter size with the <tt>n</tt>
--   invocation. Sizes of up to 16 are valid, with 7 being a likely good
--   minimum for decent accuracy.
--   
--   Let's count a list of unique items and get the latest estimate:
--   
--   <pre>
--   &gt;&gt;&gt; size (foldr insert mempty [1..10] :: HyperLogLog 4)
--   Approximate {_confidence = 0.9972, _lo = 2, _estimate = 9, _hi = 17}
--   </pre>
--   
--   Note how <a>insert</a> can be used to add new observations to the
--   approximate counter.
data HyperLogLog p
class HasHyperLogLog a p | a -> p
hyperLogLog :: HasHyperLogLog a p => Lens' a (HyperLogLog p)

-- | Approximate size of our set
size :: Reifies p Integer => HyperLogLog p -> Approximate Int64
intersectionSize :: Reifies p Integer => [HyperLogLog p] -> Approximate Int64
insert :: (Reifies s Integer, Serial a) => a -> HyperLogLog s -> HyperLogLog s

-- | Insert a value that has already been hashed by whatever user defined
--   hash function you want.
insertHash :: Reifies s Integer => Word32 -> HyperLogLog s -> HyperLogLog s
cast :: forall p q. (Reifies p Integer, Reifies q Integer) => HyperLogLog p -> Maybe (HyperLogLog q)

-- | If two types <tt>p</tt> and <tt>q</tt> reify the same configuration,
--   then we can coerce between <tt><a>HyperLogLog</a> p</tt> and
--   <tt><a>HyperLogLog</a> q</tt>. We do this by building a hole in the
--   <tt>nominal</tt> role for the configuration parameter.
coerceConfig :: forall p q. (Reifies p Integer, Reifies q Integer) => Maybe (Coercion (HyperLogLog p) (HyperLogLog q))
