{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE MagicHash #-}
module Data.HashTable.ST.Cuckoo
( HashTable
, new
, newSized
, delete
, lookup
, insert
, mutate
, mutateST
, mapM_
, foldM
, lookupIndex
, nextByIndex
) where
#if !MIN_VERSION_base(4,8,0)
import Control.Applicative
#endif
import Control.Monad hiding
(foldM,
mapM_)
import Control.Monad.ST (ST)
import Data.Bits
import Data.Hashable hiding
(hash)
import qualified Data.Hashable as H
import Data.Int
import Data.Maybe
import Data.Primitive.Array
import Data.STRef
import GHC.Exts
import Prelude hiding
(lookup,
mapM_,
read)
import qualified Data.HashTable.Class as C
import Data.HashTable.Internal.CacheLine
import Data.HashTable.Internal.CheapPseudoRandomBitStream
import Data.HashTable.Internal.IntArray (Elem)
import qualified Data.HashTable.Internal.IntArray as U
import Data.HashTable.Internal.Utils
#ifdef DEBUG
import System.IO
#endif
newtype HashTable s k v = HT (STRef s (HashTable_ s k v))
data HashTable_ s k v = HashTable
{ HashTable_ s k v -> Int
_size :: {-# UNPACK #-} !Int
, HashTable_ s k v -> BitStream s
_rng :: {-# UNPACK #-} !(BitStream s)
, HashTable_ s k v -> IntArray s
_hashes :: {-# UNPACK #-} !(U.IntArray s)
, HashTable_ s k v -> MutableArray s k
_keys :: {-# UNPACK #-} !(MutableArray s k)
, HashTable_ s k v -> MutableArray s v
_values :: {-# UNPACK #-} !(MutableArray s v)
, HashTable_ s k v -> Int
_maxAttempts :: {-# UNPACK #-} !Int
}
instance C.HashTable HashTable where
new :: ST s (HashTable s k v)
new = ST s (HashTable s k v)
forall s k v. ST s (HashTable s k v)
new
newSized :: Int -> ST s (HashTable s k v)
newSized = Int -> ST s (HashTable s k v)
forall s k v. Int -> ST s (HashTable s k v)
newSized
insert :: HashTable s k v -> k -> v -> ST s ()
insert = HashTable s k v -> k -> v -> ST s ()
forall k s v.
(Eq k, Hashable k) =>
HashTable s k v -> k -> v -> ST s ()
insert
delete :: HashTable s k v -> k -> ST s ()
delete = HashTable s k v -> k -> ST s ()
forall k s v. (Hashable k, Eq k) => HashTable s k v -> k -> ST s ()
delete
lookup :: HashTable s k v -> k -> ST s (Maybe v)
lookup = HashTable s k v -> k -> ST s (Maybe v)
forall k s v.
(Eq k, Hashable k) =>
HashTable s k v -> k -> ST s (Maybe v)
lookup
foldM :: (a -> (k, v) -> ST s a) -> a -> HashTable s k v -> ST s a
foldM = (a -> (k, v) -> ST s a) -> a -> HashTable s k v -> ST s a
forall a k v s.
(a -> (k, v) -> ST s a) -> a -> HashTable s k v -> ST s a
foldM
mapM_ :: ((k, v) -> ST s b) -> HashTable s k v -> ST s ()
mapM_ = ((k, v) -> ST s b) -> HashTable s k v -> ST s ()
forall k v s b. ((k, v) -> ST s b) -> HashTable s k v -> ST s ()
mapM_
lookupIndex :: HashTable s k v -> k -> ST s (Maybe Word)
lookupIndex = HashTable s k v -> k -> ST s (Maybe Word)
forall k s v.
(Hashable k, Eq k) =>
HashTable s k v -> k -> ST s (Maybe Word)
lookupIndex
nextByIndex :: HashTable s k v -> Word -> ST s (Maybe (Word, k, v))
nextByIndex = HashTable s k v -> Word -> ST s (Maybe (Word, k, v))
forall s k v. HashTable s k v -> Word -> ST s (Maybe (Word, k, v))
nextByIndex
computeOverhead :: HashTable s k v -> ST s Double
computeOverhead = HashTable s k v -> ST s Double
forall s k v. HashTable s k v -> ST s Double
computeOverhead
mutate :: HashTable s k v -> k -> (Maybe v -> (Maybe v, a)) -> ST s a
mutate = HashTable s k v -> k -> (Maybe v -> (Maybe v, a)) -> ST s a
forall k s v a.
(Eq k, Hashable k) =>
HashTable s k v -> k -> (Maybe v -> (Maybe v, a)) -> ST s a
mutate
mutateST :: HashTable s k v -> k -> (Maybe v -> ST s (Maybe v, a)) -> ST s a
mutateST = HashTable s k v -> k -> (Maybe v -> ST s (Maybe v, a)) -> ST s a
forall k s v a.
(Eq k, Hashable k) =>
HashTable s k v -> k -> (Maybe v -> ST s (Maybe v, a)) -> ST s a
mutateST
instance Show (HashTable s k v) where
show :: HashTable s k v -> String
show HashTable s k v
_ = String
"<HashTable>"
new :: ST s (HashTable s k v)
new :: ST s (HashTable s k v)
new = Int -> ST s (HashTable_ s k v)
forall s k v. Int -> ST s (HashTable_ s k v)
newSizedReal Int
2 ST s (HashTable_ s k v)
-> (HashTable_ s k v -> ST s (HashTable s k v))
-> ST s (HashTable s k v)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= HashTable_ s k v -> ST s (HashTable s k v)
forall s k v. HashTable_ s k v -> ST s (HashTable s k v)
newRef
{-# INLINE new #-}
newSized :: Int -> ST s (HashTable s k v)
newSized :: Int -> ST s (HashTable s k v)
newSized Int
n = do
let n' :: Int
n' = (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
numElemsInCacheLine Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
numElemsInCacheLine
let k :: Int
k = Int -> Int
nextBestPrime (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$ Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
ceiling (Double -> Int) -> Double -> Int
forall a b. (a -> b) -> a -> b
$ Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n' Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
maxLoad
Int -> ST s (HashTable_ s k v)
forall s k v. Int -> ST s (HashTable_ s k v)
newSizedReal Int
k ST s (HashTable_ s k v)
-> (HashTable_ s k v -> ST s (HashTable s k v))
-> ST s (HashTable s k v)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= HashTable_ s k v -> ST s (HashTable s k v)
forall s k v. HashTable_ s k v -> ST s (HashTable s k v)
newRef
{-# INLINE newSized #-}
insert :: (Eq k, Hashable k) => HashTable s k v -> k -> v -> ST s ()
insert :: HashTable s k v -> k -> v -> ST s ()
insert HashTable s k v
ht !k
k !v
v = HashTable s k v -> ST s (HashTable_ s k v)
forall s k v. HashTable s k v -> ST s (HashTable_ s k v)
readRef HashTable s k v
ht ST s (HashTable_ s k v) -> (HashTable_ s k v -> ST s ()) -> ST s ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \HashTable_ s k v
h -> HashTable_ s k v -> k -> v -> ST s (HashTable_ s k v)
forall k s v.
(Eq k, Hashable k) =>
HashTable_ s k v -> k -> v -> ST s (HashTable_ s k v)
insert' HashTable_ s k v
h k
k v
v ST s (HashTable_ s k v) -> (HashTable_ s k v -> ST s ()) -> ST s ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= HashTable s k v -> HashTable_ s k v -> ST s ()
forall s k v. HashTable s k v -> HashTable_ s k v -> ST s ()
writeRef HashTable s k v
ht
mutate :: (Eq k, Hashable k) =>
HashTable s k v
-> k
-> (Maybe v -> (Maybe v, a))
-> ST s a
mutate :: HashTable s k v -> k -> (Maybe v -> (Maybe v, a)) -> ST s a
mutate HashTable s k v
htRef !k
k !Maybe v -> (Maybe v, a)
f = HashTable s k v -> k -> (Maybe v -> ST s (Maybe v, a)) -> ST s a
forall k s v a.
(Eq k, Hashable k) =>
HashTable s k v -> k -> (Maybe v -> ST s (Maybe v, a)) -> ST s a
mutateST HashTable s k v
htRef k
k ((Maybe v, a) -> ST s (Maybe v, a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((Maybe v, a) -> ST s (Maybe v, a))
-> (Maybe v -> (Maybe v, a)) -> Maybe v -> ST s (Maybe v, a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe v -> (Maybe v, a)
f)
{-# INLINE mutate #-}
mutateST :: (Eq k, Hashable k) =>
HashTable s k v
-> k
-> (Maybe v -> ST s (Maybe v, a))
-> ST s a
mutateST :: HashTable s k v -> k -> (Maybe v -> ST s (Maybe v, a)) -> ST s a
mutateST HashTable s k v
htRef !k
k !Maybe v -> ST s (Maybe v, a)
f = do
HashTable_ s k v
ht <- HashTable s k v -> ST s (HashTable_ s k v)
forall s k v. HashTable s k v -> ST s (HashTable_ s k v)
readRef HashTable s k v
htRef
(HashTable_ s k v
newHt, a
a) <- HashTable_ s k v
-> k
-> (Maybe v -> ST s (Maybe v, a))
-> ST s (HashTable_ s k v, a)
forall k s v a.
(Eq k, Hashable k) =>
HashTable_ s k v
-> k
-> (Maybe v -> ST s (Maybe v, a))
-> ST s (HashTable_ s k v, a)
mutate' HashTable_ s k v
ht k
k Maybe v -> ST s (Maybe v, a)
f
HashTable s k v -> HashTable_ s k v -> ST s ()
forall s k v. HashTable s k v -> HashTable_ s k v -> ST s ()
writeRef HashTable s k v
htRef HashTable_ s k v
newHt
a -> ST s a
forall (m :: * -> *) a. Monad m => a -> m a
return a
a
{-# INLINE mutateST #-}
computeOverhead :: HashTable s k v -> ST s Double
computeOverhead :: HashTable s k v -> ST s Double
computeOverhead HashTable s k v
htRef = HashTable s k v -> ST s (HashTable_ s k v)
forall s k v. HashTable s k v -> ST s (HashTable_ s k v)
readRef HashTable s k v
htRef ST s (HashTable_ s k v)
-> (HashTable_ s k v -> ST s Double) -> ST s Double
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= HashTable_ s k v -> ST s Double
forall b s k v. Fractional b => HashTable_ s k v -> ST s b
work
where
work :: HashTable_ s k v -> ST s b
work (HashTable Int
sz BitStream s
_ IntArray s
_ MutableArray s k
_ MutableArray s v
_ Int
_) = do
Int
nFilled <- (Int -> (k, v) -> ST s Int) -> Int -> HashTable s k v -> ST s Int
forall a k v s.
(a -> (k, v) -> ST s a) -> a -> HashTable s k v -> ST s a
foldM Int -> (k, v) -> ST s Int
forall (m :: * -> *) a p. (Monad m, Num a) => a -> p -> m a
f Int
0 HashTable s k v
htRef
let oh :: Int
oh = (Int
totSz Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
hashCodesPerWord)
Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* (Int
totSz Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
nFilled)
Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
12
b -> ST s b
forall (m :: * -> *) a. Monad m => a -> m a
return (b -> ST s b) -> b -> ST s b
forall a b. (a -> b) -> a -> b
$! Int -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
oh::Int) b -> b -> b
forall a. Fractional a => a -> a -> a
/ Int -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
nFilled
where
hashCodesPerWord :: Int
hashCodesPerWord = (Int -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize (Int
0 :: Int)) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
16
totSz :: Int
totSz = Int
numElemsInCacheLine Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
sz
f :: a -> p -> m a
f !a
a p
_ = a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> m a) -> a -> m a
forall a b. (a -> b) -> a -> b
$! a
aa -> a -> a
forall a. Num a => a -> a -> a
+a
1
delete :: (Hashable k, Eq k) =>
HashTable s k v
-> k
-> ST s ()
delete :: HashTable s k v -> k -> ST s ()
delete HashTable s k v
htRef k
k = HashTable s k v -> ST s (HashTable_ s k v)
forall s k v. HashTable s k v -> ST s (HashTable_ s k v)
readRef HashTable s k v
htRef ST s (HashTable_ s k v) -> (HashTable_ s k v -> ST s ()) -> ST s ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= HashTable_ s k v -> ST s ()
forall s v. HashTable_ s k v -> ST s ()
go
where
go :: HashTable_ s k v -> ST s ()
go ht :: HashTable_ s k v
ht@(HashTable Int
sz BitStream s
_ IntArray s
_ MutableArray s k
_ MutableArray s v
_ Int
_) = do
(Int, Elem)
_ <- HashTable_ s k v
-> Bool -> k -> Int -> Int -> Int -> Int -> ST s (Int, Elem)
forall k s v.
(Hashable k, Eq k) =>
HashTable_ s k v
-> Bool -> k -> Int -> Int -> Int -> Int -> ST s (Int, Elem)
delete' HashTable_ s k v
ht Bool
False k
k Int
b1 Int
b2 Int
h1 Int
h2
() -> ST s ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
where
h1 :: Int
h1 = k -> Int
forall k. Hashable k => k -> Int
hash1 k
k
h2 :: Int
h2 = k -> Int
forall k. Hashable k => k -> Int
hash2 k
k
b1 :: Int
b1 = Int -> Int -> Int
whichLine Int
h1 Int
sz
b2 :: Int
b2 = Int -> Int -> Int
whichLine Int
h2 Int
sz
lookup :: (Eq k, Hashable k) =>
HashTable s k v
-> k
-> ST s (Maybe v)
lookup :: HashTable s k v -> k -> ST s (Maybe v)
lookup HashTable s k v
htRef k
k = do
HashTable_ s k v
ht <- HashTable s k v -> ST s (HashTable_ s k v)
forall s k v. HashTable s k v -> ST s (HashTable_ s k v)
readRef HashTable s k v
htRef
HashTable_ s k v -> k -> ST s (Maybe v)
forall k s v.
(Eq k, Hashable k) =>
HashTable_ s k v -> k -> ST s (Maybe v)
lookup' HashTable_ s k v
ht k
k
{-# INLINE lookup #-}
lookup' :: (Eq k, Hashable k) =>
HashTable_ s k v
-> k
-> ST s (Maybe v)
lookup' :: HashTable_ s k v -> k -> ST s (Maybe v)
lookup' (HashTable Int
sz BitStream s
_ IntArray s
hashes MutableArray s k
keys MutableArray s v
values Int
_) !k
k = do
Int
idx1 <- MutableArray s k -> IntArray s -> k -> Int -> Elem -> ST s Int
forall k s.
Eq k =>
MutableArray s k -> IntArray s -> k -> Int -> Elem -> ST s Int
searchOne MutableArray s k
keys IntArray s
hashes k
k Int
b1 Elem
he1
if Int
idx1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0
then do
v
v <- MutableArray (PrimState (ST s)) v -> Int -> ST s v
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> m a
readArray MutableArray s v
MutableArray (PrimState (ST s)) v
values Int
idx1
Maybe v -> ST s (Maybe v)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe v -> ST s (Maybe v)) -> Maybe v -> ST s (Maybe v)
forall a b. (a -> b) -> a -> b
$! v -> Maybe v
forall a. a -> Maybe a
Just v
v
else do
Int
idx2 <- MutableArray s k -> IntArray s -> k -> Int -> Elem -> ST s Int
forall k s.
Eq k =>
MutableArray s k -> IntArray s -> k -> Int -> Elem -> ST s Int
searchOne MutableArray s k
keys IntArray s
hashes k
k Int
b2 Elem
he2
if Int
idx2 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0
then do
v
v <- MutableArray (PrimState (ST s)) v -> Int -> ST s v
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> m a
readArray MutableArray s v
MutableArray (PrimState (ST s)) v
values Int
idx2
Maybe v -> ST s (Maybe v)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe v -> ST s (Maybe v)) -> Maybe v -> ST s (Maybe v)
forall a b. (a -> b) -> a -> b
$! v -> Maybe v
forall a. a -> Maybe a
Just v
v
else
Maybe v -> ST s (Maybe v)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe v
forall a. Maybe a
Nothing
where
h1 :: Int
h1 = k -> Int
forall k. Hashable k => k -> Int
hash1 k
k
h2 :: Int
h2 = k -> Int
forall k. Hashable k => k -> Int
hash2 k
k
he1 :: Elem
he1 = Int -> Elem
hashToElem Int
h1
he2 :: Elem
he2 = Int -> Elem
hashToElem Int
h2
b1 :: Int
b1 = Int -> Int -> Int
whichLine Int
h1 Int
sz
b2 :: Int
b2 = Int -> Int -> Int
whichLine Int
h2 Int
sz
{-# INLINE lookup' #-}
searchOne :: (Eq k) =>
MutableArray s k
-> U.IntArray s
-> k
-> Int
-> Elem
-> ST s Int
searchOne :: MutableArray s k -> IntArray s -> k -> Int -> Elem -> ST s Int
searchOne !MutableArray s k
keys !IntArray s
hashes !k
k !Int
b0 !Elem
h = Int -> ST s Int
go Int
b0
where
go :: Int -> ST s Int
go !Int
b = do
String -> ST s ()
forall s. String -> ST s ()
debug (String -> ST s ()) -> String -> ST s ()
forall a b. (a -> b) -> a -> b
$ String
"searchOne: go/" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
b String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"/" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Elem -> String
forall a. Show a => a -> String
show Elem
h
Int
idx <- IntArray s -> Int -> Elem -> ST s Int
forall s. IntArray s -> Int -> Elem -> ST s Int
cacheLineSearch IntArray s
hashes Int
b Elem
h
String -> ST s ()
forall s. String -> ST s ()
debug (String -> ST s ()) -> String -> ST s ()
forall a b. (a -> b) -> a -> b
$ String
"searchOne: cacheLineSearch returned " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
idx
case Int
idx of
-1 -> Int -> ST s Int
forall (m :: * -> *) a. Monad m => a -> m a
return (-Int
1)
Int
_ -> do
k
k' <- MutableArray (PrimState (ST s)) k -> Int -> ST s k
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> m a
readArray MutableArray s k
MutableArray (PrimState (ST s)) k
keys Int
idx
if k
k k -> k -> Bool
forall a. Eq a => a -> a -> Bool
== k
k'
then Int -> ST s Int
forall (m :: * -> *) a. Monad m => a -> m a
return Int
idx
else do
let !idx' :: Int
idx' = Int
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
if Int -> Bool
isCacheLineAligned Int
idx'
then Int -> ST s Int
forall (m :: * -> *) a. Monad m => a -> m a
return (-Int
1)
else Int -> ST s Int
go Int
idx'
{-# INLINE searchOne #-}
foldM :: (a -> (k,v) -> ST s a)
-> a
-> HashTable s k v
-> ST s a
foldM :: (a -> (k, v) -> ST s a) -> a -> HashTable s k v -> ST s a
foldM a -> (k, v) -> ST s a
f a
seed0 HashTable s k v
htRef = HashTable s k v -> ST s (HashTable_ s k v)
forall s k v. HashTable s k v -> ST s (HashTable_ s k v)
readRef HashTable s k v
htRef ST s (HashTable_ s k v) -> (HashTable_ s k v -> ST s a) -> ST s a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (a -> (k, v) -> ST s a) -> a -> HashTable_ s k v -> ST s a
forall a k v s.
(a -> (k, v) -> ST s a) -> a -> HashTable_ s k v -> ST s a
foldMWork a -> (k, v) -> ST s a
f a
seed0
{-# INLINE foldM #-}
foldMWork :: (a -> (k,v) -> ST s a)
-> a
-> HashTable_ s k v
-> ST s a
foldMWork :: (a -> (k, v) -> ST s a) -> a -> HashTable_ s k v -> ST s a
foldMWork a -> (k, v) -> ST s a
f a
seed0 (HashTable Int
sz BitStream s
_ IntArray s
hashes MutableArray s k
keys MutableArray s v
values Int
_) = Int -> a -> ST s a
go Int
0 a
seed0
where
totSz :: Int
totSz = Int
numElemsInCacheLine Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
sz
go :: Int -> a -> ST s a
go !Int
i !a
seed | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
totSz = a -> ST s a
forall (m :: * -> *) a. Monad m => a -> m a
return a
seed
| Bool
otherwise = do
Elem
h <- IntArray s -> Int -> ST s Elem
forall s. IntArray s -> Int -> ST s Elem
U.readArray IntArray s
hashes Int
i
if Elem
h Elem -> Elem -> Bool
forall a. Eq a => a -> a -> Bool
/= Elem
emptyMarker
then do
k
k <- MutableArray (PrimState (ST s)) k -> Int -> ST s k
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> m a
readArray MutableArray s k
MutableArray (PrimState (ST s)) k
keys Int
i
v
v <- MutableArray (PrimState (ST s)) v -> Int -> ST s v
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> m a
readArray MutableArray s v
MutableArray (PrimState (ST s)) v
values Int
i
!a
seed' <- a -> (k, v) -> ST s a
f a
seed (k
k,v
v)
Int -> a -> ST s a
go (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) a
seed'
else
Int -> a -> ST s a
go (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) a
seed
{-# INLINE foldMWork #-}
mapM_ :: ((k,v) -> ST s a)
-> HashTable s k v
-> ST s ()
mapM_ :: ((k, v) -> ST s a) -> HashTable s k v -> ST s ()
mapM_ (k, v) -> ST s a
f HashTable s k v
htRef = HashTable s k v -> ST s (HashTable_ s k v)
forall s k v. HashTable s k v -> ST s (HashTable_ s k v)
readRef HashTable s k v
htRef ST s (HashTable_ s k v) -> (HashTable_ s k v -> ST s ()) -> ST s ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ((k, v) -> ST s a) -> HashTable_ s k v -> ST s ()
forall k v s a. ((k, v) -> ST s a) -> HashTable_ s k v -> ST s ()
mapMWork (k, v) -> ST s a
f
{-# INLINE mapM_ #-}
mapMWork :: ((k,v) -> ST s a)
-> HashTable_ s k v
-> ST s ()
mapMWork :: ((k, v) -> ST s a) -> HashTable_ s k v -> ST s ()
mapMWork (k, v) -> ST s a
f (HashTable Int
sz BitStream s
_ IntArray s
hashes MutableArray s k
keys MutableArray s v
values Int
_) = Int -> ST s ()
go Int
0
where
totSz :: Int
totSz = Int
numElemsInCacheLine Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
sz
go :: Int -> ST s ()
go !Int
i | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
totSz = () -> ST s ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
| Bool
otherwise = do
Elem
h <- IntArray s -> Int -> ST s Elem
forall s. IntArray s -> Int -> ST s Elem
U.readArray IntArray s
hashes Int
i
if Elem
h Elem -> Elem -> Bool
forall a. Eq a => a -> a -> Bool
/= Elem
emptyMarker
then do
k
k <- MutableArray (PrimState (ST s)) k -> Int -> ST s k
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> m a
readArray MutableArray s k
MutableArray (PrimState (ST s)) k
keys Int
i
v
v <- MutableArray (PrimState (ST s)) v -> Int -> ST s v
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> m a
readArray MutableArray s v
MutableArray (PrimState (ST s)) v
values Int
i
a
_ <- (k, v) -> ST s a
f (k
k,v
v)
Int -> ST s ()
go (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)
else
Int -> ST s ()
go (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)
{-# INLINE mapMWork #-}
newSizedReal :: Int -> ST s (HashTable_ s k v)
newSizedReal :: Int -> ST s (HashTable_ s k v)
newSizedReal Int
nbuckets = do
let !ntotal :: Int
ntotal = Int
nbuckets Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
numElemsInCacheLine
let !maxAttempts :: Int
maxAttempts = Int
12 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (Word -> Int
log2 (Word -> Int) -> Word -> Int
forall a b. (a -> b) -> a -> b
$ Int -> Word
forall a. Enum a => Int -> a
toEnum Int
nbuckets)
String -> ST s ()
forall s. String -> ST s ()
debug (String -> ST s ()) -> String -> ST s ()
forall a b. (a -> b) -> a -> b
$ String
"creating cuckoo hash table with " String -> ShowS
forall a. [a] -> [a] -> [a]
++
Int -> String
forall a. Show a => a -> String
show Int
nbuckets String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" buckets having " String -> ShowS
forall a. [a] -> [a] -> [a]
++
Int -> String
forall a. Show a => a -> String
show Int
ntotal String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" total slots"
BitStream s
rng <- ST s (BitStream s)
forall s. ST s (BitStream s)
newBitStream
IntArray s
hashes <- Int -> ST s (IntArray s)
forall s. Int -> ST s (IntArray s)
U.newArray Int
ntotal
MutableArray s k
keys <- Int -> k -> ST s (MutableArray (PrimState (ST s)) k)
forall (m :: * -> *) a.
PrimMonad m =>
Int -> a -> m (MutableArray (PrimState m) a)
newArray Int
ntotal k
forall a. HasCallStack => a
undefined
MutableArray s v
values <- Int -> v -> ST s (MutableArray (PrimState (ST s)) v)
forall (m :: * -> *) a.
PrimMonad m =>
Int -> a -> m (MutableArray (PrimState m) a)
newArray Int
ntotal v
forall a. HasCallStack => a
undefined
HashTable_ s k v -> ST s (HashTable_ s k v)
forall (m :: * -> *) a. Monad m => a -> m a
return (HashTable_ s k v -> ST s (HashTable_ s k v))
-> HashTable_ s k v -> ST s (HashTable_ s k v)
forall a b. (a -> b) -> a -> b
$! Int
-> BitStream s
-> IntArray s
-> MutableArray s k
-> MutableArray s v
-> Int
-> HashTable_ s k v
forall s k v.
Int
-> BitStream s
-> IntArray s
-> MutableArray s k
-> MutableArray s v
-> Int
-> HashTable_ s k v
HashTable Int
nbuckets BitStream s
rng IntArray s
hashes MutableArray s k
keys MutableArray s v
values Int
maxAttempts
insert' :: (Eq k, Hashable k) =>
HashTable_ s k v
-> k
-> v
-> ST s (HashTable_ s k v)
insert' :: HashTable_ s k v -> k -> v -> ST s (HashTable_ s k v)
insert' HashTable_ s k v
ht k
k v
v = do
String -> ST s ()
forall s. String -> ST s ()
debug String
"insert': begin"
Maybe (k, v)
mbX <- HashTable_ s k v -> k -> v -> ST s (Maybe (k, v))
forall k s v.
(Eq k, Hashable k) =>
HashTable_ s k v -> k -> v -> ST s (Maybe (k, v))
updateOrFail HashTable_ s k v
ht k
k v
v
HashTable_ s k v
z <- ST s (HashTable_ s k v)
-> ((k, v) -> ST s (HashTable_ s k v))
-> Maybe (k, v)
-> ST s (HashTable_ s k v)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (HashTable_ s k v -> ST s (HashTable_ s k v)
forall (m :: * -> *) a. Monad m => a -> m a
return HashTable_ s k v
ht)
(\(k
k',v
v') -> HashTable_ s k v -> k -> v -> ST s (HashTable_ s k v)
forall k s v.
(Eq k, Hashable k) =>
HashTable_ s k v -> k -> v -> ST s (HashTable_ s k v)
grow HashTable_ s k v
ht k
k' v
v')
Maybe (k, v)
mbX
String -> ST s ()
forall s. String -> ST s ()
debug String
"insert': end"
HashTable_ s k v -> ST s (HashTable_ s k v)
forall (m :: * -> *) a. Monad m => a -> m a
return HashTable_ s k v
z
{-# INLINE insert #-}
mutate' :: (Eq k, Hashable k) =>
HashTable_ s k v
-> k
-> (Maybe v -> ST s (Maybe v, a))
-> ST s (HashTable_ s k v, a)
mutate' :: HashTable_ s k v
-> k
-> (Maybe v -> ST s (Maybe v, a))
-> ST s (HashTable_ s k v, a)
mutate' ht :: HashTable_ s k v
ht@(HashTable Int
sz BitStream s
_ IntArray s
hashes MutableArray s k
keys MutableArray s v
values Int
_) !k
k !Maybe v -> ST s (Maybe v, a)
f = do
!(Maybe v
maybeVal, Int
idx, Int
_hashCode) <- ST s (Maybe v, Int, Int)
lookupSlot
!(Maybe v, a)
fRes <- Maybe v -> ST s (Maybe v, a)
f Maybe v
maybeVal
case (Maybe v
maybeVal, (Maybe v, a)
fRes) of
(Maybe v
Nothing, (Maybe v
Nothing, a
a)) -> (HashTable_ s k v, a) -> ST s (HashTable_ s k v, a)
forall (m :: * -> *) a. Monad m => a -> m a
return (HashTable_ s k v
ht, a
a)
(Just v
_v, (Just v
v', a
a)) -> do
MutableArray (PrimState (ST s)) v -> Int -> v -> ST s ()
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> a -> m ()
writeArray MutableArray s v
MutableArray (PrimState (ST s)) v
values Int
idx v
v'
(HashTable_ s k v, a) -> ST s (HashTable_ s k v, a)
forall (m :: * -> *) a. Monad m => a -> m a
return (HashTable_ s k v
ht, a
a)
(Just v
_v, (Maybe v
Nothing, a
a)) -> do
HashTable_ s k v -> Int -> ST s ()
forall k s v.
(Eq k, Hashable k) =>
HashTable_ s k v -> Int -> ST s ()
deleteFromSlot HashTable_ s k v
ht Int
idx
(HashTable_ s k v, a) -> ST s (HashTable_ s k v, a)
forall (m :: * -> *) a. Monad m => a -> m a
return (HashTable_ s k v
ht, a
a)
(Maybe v
Nothing, (Just v
v', a
a)) -> do
HashTable_ s k v
newHt <- v -> ST s (HashTable_ s k v)
insertNew v
v'
(HashTable_ s k v, a) -> ST s (HashTable_ s k v, a)
forall (m :: * -> *) a. Monad m => a -> m a
return (HashTable_ s k v
newHt, a
a)
where
h1 :: Int
h1 = k -> Int
forall k. Hashable k => k -> Int
hash1 k
k
h2 :: Int
h2 = k -> Int
forall k. Hashable k => k -> Int
hash2 k
k
b1 :: Int
b1 = Int -> Int -> Int
whichLine Int
h1 Int
sz
b2 :: Int
b2 = Int -> Int -> Int
whichLine Int
h2 Int
sz
he1 :: Elem
he1 = Int -> Elem
hashToElem Int
h1
he2 :: Elem
he2 = Int -> Elem
hashToElem Int
h2
lookupSlot :: ST s (Maybe v, Int, Int)
lookupSlot = do
Int
idx1 <- MutableArray s k -> IntArray s -> k -> Int -> Elem -> ST s Int
forall k s.
Eq k =>
MutableArray s k -> IntArray s -> k -> Int -> Elem -> ST s Int
searchOne MutableArray s k
keys IntArray s
hashes k
k Int
b1 Elem
he1
if Int
idx1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0
then do
v
v <- MutableArray (PrimState (ST s)) v -> Int -> ST s v
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> m a
readArray MutableArray s v
MutableArray (PrimState (ST s)) v
values Int
idx1
(Maybe v, Int, Int) -> ST s (Maybe v, Int, Int)
forall (m :: * -> *) a. Monad m => a -> m a
return (v -> Maybe v
forall a. a -> Maybe a
Just v
v, Int
idx1, Int
h1)
else do
Int
idx2 <- MutableArray s k -> IntArray s -> k -> Int -> Elem -> ST s Int
forall k s.
Eq k =>
MutableArray s k -> IntArray s -> k -> Int -> Elem -> ST s Int
searchOne MutableArray s k
keys IntArray s
hashes k
k Int
b2 Elem
he2
if Int
idx2 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0
then do
v
v <- MutableArray (PrimState (ST s)) v -> Int -> ST s v
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> m a
readArray MutableArray s v
MutableArray (PrimState (ST s)) v
values Int
idx2
(Maybe v, Int, Int) -> ST s (Maybe v, Int, Int)
forall (m :: * -> *) a. Monad m => a -> m a
return (v -> Maybe v
forall a. a -> Maybe a
Just v
v, Int
idx2, Int
h2)
else do
(Maybe v, Int, Int) -> ST s (Maybe v, Int, Int)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe v
forall a. Maybe a
Nothing, -Int
1, -Int
1)
insertNew :: v -> ST s (HashTable_ s k v)
insertNew v
v = do
Int
idxE1 <- IntArray s -> Int -> Elem -> ST s Int
forall s. IntArray s -> Int -> Elem -> ST s Int
cacheLineSearch IntArray s
hashes Int
b1 Elem
emptyMarker
if Int
idxE1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0
then do
HashTable_ s k v -> Int -> Elem -> k -> v -> ST s ()
forall k s v.
(Eq k, Hashable k) =>
HashTable_ s k v -> Int -> Elem -> k -> v -> ST s ()
insertIntoSlot HashTable_ s k v
ht Int
idxE1 Elem
he1 k
k v
v
HashTable_ s k v -> ST s (HashTable_ s k v)
forall (m :: * -> *) a. Monad m => a -> m a
return HashTable_ s k v
ht
else do
Int
idxE2 <- IntArray s -> Int -> Elem -> ST s Int
forall s. IntArray s -> Int -> Elem -> ST s Int
cacheLineSearch IntArray s
hashes Int
b2 Elem
emptyMarker
if Int
idxE2 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0
then do
HashTable_ s k v -> Int -> Elem -> k -> v -> ST s ()
forall k s v.
(Eq k, Hashable k) =>
HashTable_ s k v -> Int -> Elem -> k -> v -> ST s ()
insertIntoSlot HashTable_ s k v
ht Int
idxE2 Elem
he2 k
k v
v
HashTable_ s k v -> ST s (HashTable_ s k v)
forall (m :: * -> *) a. Monad m => a -> m a
return HashTable_ s k v
ht
else do
Maybe (k, v)
result <- HashTable_ s k v
-> Int -> Int -> Int -> Int -> k -> v -> ST s (Maybe (k, v))
forall k s v.
(Hashable k, Eq k) =>
HashTable_ s k v
-> Int -> Int -> Int -> Int -> k -> v -> ST s (Maybe (k, v))
cuckooOrFail HashTable_ s k v
ht Int
h1 Int
h2 Int
b1 Int
b2 k
k v
v
ST s (HashTable_ s k v)
-> ((k, v) -> ST s (HashTable_ s k v))
-> Maybe (k, v)
-> ST s (HashTable_ s k v)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (HashTable_ s k v -> ST s (HashTable_ s k v)
forall (m :: * -> *) a. Monad m => a -> m a
return HashTable_ s k v
ht)
(\(k
k', v
v') -> do
HashTable_ s k v
newHt <- HashTable_ s k v -> k -> v -> ST s (HashTable_ s k v)
forall k s v.
(Eq k, Hashable k) =>
HashTable_ s k v -> k -> v -> ST s (HashTable_ s k v)
grow HashTable_ s k v
ht k
k' v
v'
HashTable_ s k v -> ST s (HashTable_ s k v)
forall (m :: * -> *) a. Monad m => a -> m a
return HashTable_ s k v
newHt)
Maybe (k, v)
result
{-# INLINE mutate' #-}
deleteFromSlot :: (Eq k, Hashable k) =>
HashTable_ s k v
-> Int
-> ST s ()
deleteFromSlot :: HashTable_ s k v -> Int -> ST s ()
deleteFromSlot _ht :: HashTable_ s k v
_ht@(HashTable Int
_ BitStream s
_ IntArray s
hashes MutableArray s k
keys MutableArray s v
values Int
_) Int
idx = do
IntArray s -> Int -> Elem -> ST s ()
forall s. IntArray s -> Int -> Elem -> ST s ()
U.writeArray IntArray s
hashes Int
idx Elem
emptyMarker
MutableArray (PrimState (ST s)) k -> Int -> k -> ST s ()
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> a -> m ()
writeArray MutableArray s k
MutableArray (PrimState (ST s)) k
keys Int
idx k
forall a. HasCallStack => a
undefined
MutableArray (PrimState (ST s)) v -> Int -> v -> ST s ()
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> a -> m ()
writeArray MutableArray s v
MutableArray (PrimState (ST s)) v
values Int
idx v
forall a. HasCallStack => a
undefined
{-# INLINE deleteFromSlot #-}
insertIntoSlot :: (Eq k, Hashable k) =>
HashTable_ s k v
-> Int
-> Elem
-> k
-> v
-> ST s ()
insertIntoSlot :: HashTable_ s k v -> Int -> Elem -> k -> v -> ST s ()
insertIntoSlot _ht :: HashTable_ s k v
_ht@(HashTable Int
_ BitStream s
_ IntArray s
hashes MutableArray s k
keys MutableArray s v
values Int
_) Int
idx Elem
he k
k v
v = do
IntArray s -> Int -> Elem -> ST s ()
forall s. IntArray s -> Int -> Elem -> ST s ()
U.writeArray IntArray s
hashes Int
idx Elem
he
MutableArray (PrimState (ST s)) k -> Int -> k -> ST s ()
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> a -> m ()
writeArray MutableArray s k
MutableArray (PrimState (ST s)) k
keys Int
idx k
k
MutableArray (PrimState (ST s)) v -> Int -> v -> ST s ()
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> a -> m ()
writeArray MutableArray s v
MutableArray (PrimState (ST s)) v
values Int
idx v
v
{-# INLINE insertIntoSlot #-}
updateOrFail :: (Eq k, Hashable k) =>
HashTable_ s k v
-> k
-> v
-> ST s (Maybe (k,v))
updateOrFail :: HashTable_ s k v -> k -> v -> ST s (Maybe (k, v))
updateOrFail ht :: HashTable_ s k v
ht@(HashTable Int
sz BitStream s
_ IntArray s
hashes MutableArray s k
keys MutableArray s v
values Int
_) k
k v
v = do
String -> ST s ()
forall s. String -> ST s ()
debug (String -> ST s ()) -> String -> ST s ()
forall a b. (a -> b) -> a -> b
$ String
"updateOrFail: begin: sz = " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
sz
String -> ST s ()
forall s. String -> ST s ()
debug (String -> ST s ()) -> String -> ST s ()
forall a b. (a -> b) -> a -> b
$ String
" h1=" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
h1 String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
", h2=" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
h2
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
", b1=" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
b1 String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
", b2=" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
b2
(Int
didx, Elem
hashCode) <- HashTable_ s k v
-> Bool -> k -> Int -> Int -> Int -> Int -> ST s (Int, Elem)
forall k s v.
(Hashable k, Eq k) =>
HashTable_ s k v
-> Bool -> k -> Int -> Int -> Int -> Int -> ST s (Int, Elem)
delete' HashTable_ s k v
ht Bool
True k
k Int
b1 Int
b2 Int
h1 Int
h2
String -> ST s ()
forall s. String -> ST s ()
debug (String -> ST s ()) -> String -> ST s ()
forall a b. (a -> b) -> a -> b
$ String
"delete' returned (" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
didx String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"," String -> ShowS
forall a. [a] -> [a] -> [a]
++ Elem -> String
forall a. Show a => a -> String
show Elem
hashCode String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
if Int
didx Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0
then do
IntArray s -> Int -> Elem -> ST s ()
forall s. IntArray s -> Int -> Elem -> ST s ()
U.writeArray IntArray s
hashes Int
didx Elem
hashCode
MutableArray (PrimState (ST s)) k -> Int -> k -> ST s ()
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> a -> m ()
writeArray MutableArray s k
MutableArray (PrimState (ST s)) k
keys Int
didx k
k
MutableArray (PrimState (ST s)) v -> Int -> v -> ST s ()
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> a -> m ()
writeArray MutableArray s v
MutableArray (PrimState (ST s)) v
values Int
didx v
v
Maybe (k, v) -> ST s (Maybe (k, v))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (k, v)
forall a. Maybe a
Nothing
else ST s (Maybe (k, v))
cuckoo
where
h1 :: Int
h1 = k -> Int
forall k. Hashable k => k -> Int
hash1 k
k
h2 :: Int
h2 = k -> Int
forall k. Hashable k => k -> Int
hash2 k
k
b1 :: Int
b1 = Int -> Int -> Int
whichLine Int
h1 Int
sz
b2 :: Int
b2 = Int -> Int -> Int
whichLine Int
h2 Int
sz
cuckoo :: ST s (Maybe (k, v))
cuckoo = do
String -> ST s ()
forall s. String -> ST s ()
debug String
"cuckoo: calling cuckooOrFail"
Maybe (k, v)
result <- HashTable_ s k v
-> Int -> Int -> Int -> Int -> k -> v -> ST s (Maybe (k, v))
forall k s v.
(Hashable k, Eq k) =>
HashTable_ s k v
-> Int -> Int -> Int -> Int -> k -> v -> ST s (Maybe (k, v))
cuckooOrFail HashTable_ s k v
ht Int
h1 Int
h2 Int
b1 Int
b2 k
k v
v
String -> ST s ()
forall s. String -> ST s ()
debug (String -> ST s ()) -> String -> ST s ()
forall a b. (a -> b) -> a -> b
$ String
"cuckoo: cuckooOrFail returned " String -> ShowS
forall a. [a] -> [a] -> [a]
++
(if Maybe (k, v) -> Bool
forall a. Maybe a -> Bool
isJust Maybe (k, v)
result then String
"Just _" else String
"Nothing")
ST s (Maybe (k, v))
-> ((k, v) -> ST s (Maybe (k, v)))
-> Maybe (k, v)
-> ST s (Maybe (k, v))
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Maybe (k, v) -> ST s (Maybe (k, v))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (k, v)
forall a. Maybe a
Nothing)
(Maybe (k, v) -> ST s (Maybe (k, v))
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (k, v) -> ST s (Maybe (k, v)))
-> ((k, v) -> Maybe (k, v)) -> (k, v) -> ST s (Maybe (k, v))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (k, v) -> Maybe (k, v)
forall a. a -> Maybe a
Just)
Maybe (k, v)
result
{-# INLINE updateOrFail #-}
delete' :: (Hashable k, Eq k) =>
HashTable_ s k v
-> Bool
-> k
-> Int
-> Int
-> Int
-> Int
-> ST s (Int, Elem)
delete' :: HashTable_ s k v
-> Bool -> k -> Int -> Int -> Int -> Int -> ST s (Int, Elem)
delete' (HashTable Int
_ BitStream s
_ IntArray s
hashes MutableArray s k
keys MutableArray s v
values Int
_) !Bool
updating !k
k Int
b1 Int
b2 Int
h1 Int
h2 = do
String -> ST s ()
forall s. String -> ST s ()
debug (String -> ST s ()) -> String -> ST s ()
forall a b. (a -> b) -> a -> b
$ String
"delete' b1=" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
b1
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" b2=" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
b2
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" h1=" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
h1
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" h2=" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
h2
IntArray s -> Int -> ST s ()
forall s. IntArray s -> Int -> ST s ()
prefetchWrite IntArray s
hashes Int
b2
let !he1 :: Elem
he1 = Int -> Elem
hashToElem Int
h1
let !he2 :: Elem
he2 = Int -> Elem
hashToElem Int
h2
Int
idx1 <- MutableArray s k -> IntArray s -> k -> Int -> Elem -> ST s Int
forall k s.
Eq k =>
MutableArray s k -> IntArray s -> k -> Int -> Elem -> ST s Int
searchOne MutableArray s k
keys IntArray s
hashes k
k Int
b1 Elem
he1
if Int
idx1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0
then do
Int
idx2 <- MutableArray s k -> IntArray s -> k -> Int -> Elem -> ST s Int
forall k s.
Eq k =>
MutableArray s k -> IntArray s -> k -> Int -> Elem -> ST s Int
searchOne MutableArray s k
keys IntArray s
hashes k
k Int
b2 Elem
he2
if Int
idx2 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0
then if Bool
updating
then do
String -> ST s ()
forall s. String -> ST s ()
debug (String -> ST s ()) -> String -> ST s ()
forall a b. (a -> b) -> a -> b
$ String
"delete': looking for empty element"
Int
idxE1 <- IntArray s -> Int -> Elem -> ST s Int
forall s. IntArray s -> Int -> Elem -> ST s Int
cacheLineSearch IntArray s
hashes Int
b1 Elem
emptyMarker
String -> ST s ()
forall s. String -> ST s ()
debug (String -> ST s ()) -> String -> ST s ()
forall a b. (a -> b) -> a -> b
$ String
"delete': idxE1 was " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
idxE1
if Int
idxE1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0
then (Int, Elem) -> ST s (Int, Elem)
forall (m :: * -> *) a. Monad m => a -> m a
return (Int
idxE1, Elem
he1)
else do
Int
idxE2 <- IntArray s -> Int -> Elem -> ST s Int
forall s. IntArray s -> Int -> Elem -> ST s Int
cacheLineSearch IntArray s
hashes Int
b2 Elem
emptyMarker
String -> ST s ()
forall s. String -> ST s ()
debug (String -> ST s ()) -> String -> ST s ()
forall a b. (a -> b) -> a -> b
$ String
"delete': idxE2 was " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
idxE1
if Int
idxE2 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0
then (Int, Elem) -> ST s (Int, Elem)
forall (m :: * -> *) a. Monad m => a -> m a
return (Int
idxE2, Elem
he2)
else (Int, Elem) -> ST s (Int, Elem)
forall (m :: * -> *) a. Monad m => a -> m a
return (-Int
1, Elem
0)
else (Int, Elem) -> ST s (Int, Elem)
forall (m :: * -> *) a. Monad m => a -> m a
return (-Int
1, Elem
0)
else Int -> Elem -> ST s (Int, Elem)
forall b. Int -> b -> ST s (Int, b)
deleteIt Int
idx2 Elem
he2
else Int -> Elem -> ST s (Int, Elem)
forall b. Int -> b -> ST s (Int, b)
deleteIt Int
idx1 Elem
he1
where
deleteIt :: Int -> b -> ST s (Int, b)
deleteIt !Int
idx !b
h = do
if Bool -> Bool
not Bool
updating
then do
IntArray s -> Int -> Elem -> ST s ()
forall s. IntArray s -> Int -> Elem -> ST s ()
U.writeArray IntArray s
hashes Int
idx Elem
emptyMarker
MutableArray (PrimState (ST s)) k -> Int -> k -> ST s ()
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> a -> m ()
writeArray MutableArray s k
MutableArray (PrimState (ST s)) k
keys Int
idx k
forall a. HasCallStack => a
undefined
MutableArray (PrimState (ST s)) v -> Int -> v -> ST s ()
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> a -> m ()
writeArray MutableArray s v
MutableArray (PrimState (ST s)) v
values Int
idx v
forall a. HasCallStack => a
undefined
else () -> ST s ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
(Int, b) -> ST s (Int, b)
forall (m :: * -> *) a. Monad m => a -> m a
return ((Int, b) -> ST s (Int, b)) -> (Int, b) -> ST s (Int, b)
forall a b. (a -> b) -> a -> b
$! (Int
idx, b
h)
{-# INLINE delete' #-}
cuckooOrFail :: (Hashable k, Eq k) =>
HashTable_ s k v
-> Int
-> Int
-> Int
-> Int
-> k
-> v
-> ST s (Maybe (k,v))
cuckooOrFail :: HashTable_ s k v
-> Int -> Int -> Int -> Int -> k -> v -> ST s (Maybe (k, v))
cuckooOrFail (HashTable Int
sz BitStream s
rng IntArray s
hashes MutableArray s k
keys MutableArray s v
values Int
maxAttempts0)
!Int
h1_0 !Int
h2_0 !Int
b1_0 !Int
b2_0 !k
k0 !v
v0 = do
String -> ST s ()
forall s. String -> ST s ()
debug (String -> ST s ()) -> String -> ST s ()
forall a b. (a -> b) -> a -> b
$ String
"cuckooOrFail h1_0=" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
h1_0
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" h2_0=" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
h2_0
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" b1_0=" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
b1_0
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" b2_0=" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
b2_0
!Word
lineChoice <- BitStream s -> ST s Word
forall s. BitStream s -> ST s Word
getNextBit BitStream s
rng
String -> ST s ()
forall s. String -> ST s ()
debug (String -> ST s ()) -> String -> ST s ()
forall a b. (a -> b) -> a -> b
$ String
"chose line " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Word -> String
forall a. Show a => a -> String
show Word
lineChoice
let (!Int
b, !Int
h) = if Word
lineChoice Word -> Word -> Bool
forall a. Eq a => a -> a -> Bool
== Word
0 then (Int
b1_0, Int
h1_0) else (Int
b2_0, Int
h2_0)
Int -> Int -> k -> v -> Int -> ST s (Maybe (k, v))
forall a.
(Eq a, Num a) =>
Int -> Int -> k -> v -> a -> ST s (Maybe (k, v))
go Int
b Int
h k
k0 v
v0 Int
maxAttempts0
where
randomIdx :: b -> ST s b
randomIdx !b
b = do
!Word
z <- Int -> BitStream s -> ST s Word
forall s. Int -> BitStream s -> ST s Word
getNBits Int
cacheLineIntBits BitStream s
rng
b -> ST s b
forall (m :: * -> *) a. Monad m => a -> m a
return (b -> ST s b) -> b -> ST s b
forall a b. (a -> b) -> a -> b
$! b
b b -> b -> b
forall a. Num a => a -> a -> a
+ Word -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word
z
bumpIdx :: Int -> Int -> k -> v -> ST s (Elem, k, v)
bumpIdx !Int
idx !Int
h !k
k !v
v = do
let !he :: Elem
he = Int -> Elem
hashToElem Int
h
String -> ST s ()
forall s. String -> ST s ()
debug (String -> ST s ()) -> String -> ST s ()
forall a b. (a -> b) -> a -> b
$ String
"bumpIdx idx=" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
idx String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" h=" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
h
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" he=" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Elem -> String
forall a. Show a => a -> String
show Elem
he
!Elem
he' <- IntArray s -> Int -> ST s Elem
forall s. IntArray s -> Int -> ST s Elem
U.readArray IntArray s
hashes Int
idx
String -> ST s ()
forall s. String -> ST s ()
debug (String -> ST s ()) -> String -> ST s ()
forall a b. (a -> b) -> a -> b
$ String
"bumpIdx: he' was " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Elem -> String
forall a. Show a => a -> String
show Elem
he'
!k
k' <- MutableArray (PrimState (ST s)) k -> Int -> ST s k
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> m a
readArray MutableArray s k
MutableArray (PrimState (ST s)) k
keys Int
idx
v
v' <- MutableArray (PrimState (ST s)) v -> Int -> ST s v
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> m a
readArray MutableArray s v
MutableArray (PrimState (ST s)) v
values Int
idx
IntArray s -> Int -> Elem -> ST s ()
forall s. IntArray s -> Int -> Elem -> ST s ()
U.writeArray IntArray s
hashes Int
idx Elem
he
MutableArray (PrimState (ST s)) k -> Int -> k -> ST s ()
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> a -> m ()
writeArray MutableArray s k
MutableArray (PrimState (ST s)) k
keys Int
idx k
k
MutableArray (PrimState (ST s)) v -> Int -> v -> ST s ()
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> a -> m ()
writeArray MutableArray s v
MutableArray (PrimState (ST s)) v
values Int
idx v
v
String -> ST s ()
forall s. String -> ST s ()
debug (String -> ST s ()) -> String -> ST s ()
forall a b. (a -> b) -> a -> b
$ String
"bumped key with he'=" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Elem -> String
forall a. Show a => a -> String
show Elem
he'
(Elem, k, v) -> ST s (Elem, k, v)
forall (m :: * -> *) a. Monad m => a -> m a
return ((Elem, k, v) -> ST s (Elem, k, v))
-> (Elem, k, v) -> ST s (Elem, k, v)
forall a b. (a -> b) -> a -> b
$! (Elem
he', k
k', v
v')
otherHash :: Elem -> k -> Int
otherHash Elem
he k
k = if Int -> Elem
hashToElem Int
h1 Elem -> Elem -> Bool
forall a. Eq a => a -> a -> Bool
== Elem
he then Int
h2 else Int
h1
where
h1 :: Int
h1 = k -> Int
forall k. Hashable k => k -> Int
hash1 k
k
h2 :: Int
h2 = k -> Int
forall k. Hashable k => k -> Int
hash2 k
k
tryWrite :: Int -> Int -> k -> v -> a -> ST s (Maybe (k, v))
tryWrite !Int
b !Int
h k
k v
v a
maxAttempts = do
String -> ST s ()
forall s. String -> ST s ()
debug (String -> ST s ()) -> String -> ST s ()
forall a b. (a -> b) -> a -> b
$ String
"tryWrite b=" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
b String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" h=" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
h
Int
idx <- IntArray s -> Int -> Elem -> ST s Int
forall s. IntArray s -> Int -> Elem -> ST s Int
cacheLineSearch IntArray s
hashes Int
b Elem
emptyMarker
String -> ST s ()
forall s. String -> ST s ()
debug (String -> ST s ()) -> String -> ST s ()
forall a b. (a -> b) -> a -> b
$ String
"cacheLineSearch returned " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
idx
if Int
idx Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0
then do
IntArray s -> Int -> Elem -> ST s ()
forall s. IntArray s -> Int -> Elem -> ST s ()
U.writeArray IntArray s
hashes Int
idx (Elem -> ST s ()) -> Elem -> ST s ()
forall a b. (a -> b) -> a -> b
$! Int -> Elem
hashToElem Int
h
MutableArray (PrimState (ST s)) k -> Int -> k -> ST s ()
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> a -> m ()
writeArray MutableArray s k
MutableArray (PrimState (ST s)) k
keys Int
idx k
k
MutableArray (PrimState (ST s)) v -> Int -> v -> ST s ()
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> a -> m ()
writeArray MutableArray s v
MutableArray (PrimState (ST s)) v
values Int
idx v
v
Maybe (k, v) -> ST s (Maybe (k, v))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (k, v)
forall a. Maybe a
Nothing
else Int -> Int -> k -> v -> a -> ST s (Maybe (k, v))
go Int
b Int
h k
k v
v (a -> ST s (Maybe (k, v))) -> a -> ST s (Maybe (k, v))
forall a b. (a -> b) -> a -> b
$! a
maxAttempts a -> a -> a
forall a. Num a => a -> a -> a
- a
1
go :: Int -> Int -> k -> v -> a -> ST s (Maybe (k, v))
go !Int
b !Int
h !k
k v
v !a
maxAttempts | a
maxAttempts a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0 = Maybe (k, v) -> ST s (Maybe (k, v))
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (k, v) -> ST s (Maybe (k, v)))
-> Maybe (k, v) -> ST s (Maybe (k, v))
forall a b. (a -> b) -> a -> b
$! (k, v) -> Maybe (k, v)
forall a. a -> Maybe a
Just (k
k,v
v)
| Bool
otherwise = do
Int
idx <- Int -> ST s Int
forall b. Num b => b -> ST s b
randomIdx Int
b
(!Elem
he0', !k
k', v
v') <- Int -> Int -> k -> v -> ST s (Elem, k, v)
bumpIdx Int
idx Int
h k
k v
v
let !h' :: Int
h' = Elem -> k -> Int
forall k. Hashable k => Elem -> k -> Int
otherHash Elem
he0' k
k'
let !b' :: Int
b' = Int -> Int -> Int
whichLine Int
h' Int
sz
Int -> Int -> k -> v -> a -> ST s (Maybe (k, v))
tryWrite Int
b' Int
h' k
k' v
v' a
maxAttempts
grow :: (Eq k, Hashable k) =>
HashTable_ s k v
-> k
-> v
-> ST s (HashTable_ s k v)
grow :: HashTable_ s k v -> k -> v -> ST s (HashTable_ s k v)
grow (HashTable Int
sz BitStream s
_ IntArray s
hashes MutableArray s k
keys MutableArray s v
values Int
_) k
k0 v
v0 = do
HashTable_ s k v
newHt <- Int -> ST s (HashTable_ s k v)
grow' (Int -> ST s (HashTable_ s k v)) -> Int -> ST s (HashTable_ s k v)
forall a b. (a -> b) -> a -> b
$! Double -> Int -> Int
bumpSize Double
bumpFactor Int
sz
Maybe (k, v)
mbR <- HashTable_ s k v -> k -> v -> ST s (Maybe (k, v))
forall k s v.
(Eq k, Hashable k) =>
HashTable_ s k v -> k -> v -> ST s (Maybe (k, v))
updateOrFail HashTable_ s k v
newHt k
k0 v
v0
ST s (HashTable_ s k v)
-> ((k, v) -> ST s (HashTable_ s k v))
-> Maybe (k, v)
-> ST s (HashTable_ s k v)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (HashTable_ s k v -> ST s (HashTable_ s k v)
forall (m :: * -> *) a. Monad m => a -> m a
return HashTable_ s k v
newHt)
(\(k, v)
_ -> Int -> ST s (HashTable_ s k v)
grow' (Int -> ST s (HashTable_ s k v)) -> Int -> ST s (HashTable_ s k v)
forall a b. (a -> b) -> a -> b
$ Double -> Int -> Int
bumpSize Double
bumpFactor (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$ HashTable_ s k v -> Int
forall s k v. HashTable_ s k v -> Int
_size HashTable_ s k v
newHt)
Maybe (k, v)
mbR
where
grow' :: Int -> ST s (HashTable_ s k v)
grow' Int
newSz = do
String -> ST s ()
forall s. String -> ST s ()
debug (String -> ST s ()) -> String -> ST s ()
forall a b. (a -> b) -> a -> b
$ String
"growing table, oldsz = " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
sz String -> ShowS
forall a. [a] -> [a] -> [a]
++
String
", newsz=" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
newSz
HashTable_ s k v
newHt <- Int -> ST s (HashTable_ s k v)
forall s k v. Int -> ST s (HashTable_ s k v)
newSizedReal Int
newSz
Int -> HashTable_ s k v -> ST s (HashTable_ s k v)
rehash Int
newSz HashTable_ s k v
newHt
rehash :: Int -> HashTable_ s k v -> ST s (HashTable_ s k v)
rehash !Int
newSz !HashTable_ s k v
newHt = Int -> ST s (HashTable_ s k v)
go Int
0
where
totSz :: Int
totSz = Int
numElemsInCacheLine Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
sz
go :: Int -> ST s (HashTable_ s k v)
go !Int
i | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
totSz = HashTable_ s k v -> ST s (HashTable_ s k v)
forall (m :: * -> *) a. Monad m => a -> m a
return HashTable_ s k v
newHt
| Bool
otherwise = do
Elem
h <- IntArray s -> Int -> ST s Elem
forall s. IntArray s -> Int -> ST s Elem
U.readArray IntArray s
hashes Int
i
if (Elem
h Elem -> Elem -> Bool
forall a. Eq a => a -> a -> Bool
/= Elem
emptyMarker)
then do
k
k <- MutableArray (PrimState (ST s)) k -> Int -> ST s k
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> m a
readArray MutableArray s k
MutableArray (PrimState (ST s)) k
keys Int
i
v
v <- MutableArray (PrimState (ST s)) v -> Int -> ST s v
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> m a
readArray MutableArray s v
MutableArray (PrimState (ST s)) v
values Int
i
Maybe (k, v)
mbR <- HashTable_ s k v -> k -> v -> ST s (Maybe (k, v))
forall k s v.
(Eq k, Hashable k) =>
HashTable_ s k v -> k -> v -> ST s (Maybe (k, v))
updateOrFail HashTable_ s k v
newHt k
k v
v
ST s (HashTable_ s k v)
-> ((k, v) -> ST s (HashTable_ s k v))
-> Maybe (k, v)
-> ST s (HashTable_ s k v)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Int -> ST s (HashTable_ s k v)
go (Int -> ST s (HashTable_ s k v)) -> Int -> ST s (HashTable_ s k v)
forall a b. (a -> b) -> a -> b
$ Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
(\(k, v)
_ -> Int -> ST s (HashTable_ s k v)
grow' (Int -> ST s (HashTable_ s k v)) -> Int -> ST s (HashTable_ s k v)
forall a b. (a -> b) -> a -> b
$ Double -> Int -> Int
bumpSize Double
bumpFactor Int
newSz)
Maybe (k, v)
mbR
else Int -> ST s (HashTable_ s k v)
go (Int -> ST s (HashTable_ s k v)) -> Int -> ST s (HashTable_ s k v)
forall a b. (a -> b) -> a -> b
$ Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
hashPrime :: Int
hashPrime :: Int
hashPrime = if Int
wordSize Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
32 then Int
hashPrime32 else Int
hashPrime64
where
hashPrime32 :: Int
hashPrime32 = Int
0xedf2a025
hashPrime64 :: Int
hashPrime64 = Int
0x3971ca9c8b3722e9
hash1 :: Hashable k => k -> Int
hash1 :: k -> Int
hash1 = k -> Int
forall k. Hashable k => k -> Int
H.hash
{-# INLINE hash1 #-}
hash2 :: Hashable k => k -> Int
hash2 :: k -> Int
hash2 = Int -> k -> Int
forall a. Hashable a => Int -> a -> Int
H.hashWithSalt Int
hashPrime
{-# INLINE hash2 #-}
hashToElem :: Int -> Elem
hashToElem :: Int -> Elem
hashToElem !Int
h = Elem
out
where
!(I# Int#
lo#) = Int
h Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
U.elemMask
!m# :: Word#
m# = Int# -> Int# -> Word#
maskw# Int#
lo# Int#
0#
!nm# :: Word#
nm# = Word# -> Word#
not# Word#
m#
!r# :: Word#
r# = ((Int# -> Word#
int2Word# Int#
1#) Word# -> Word# -> Word#
`and#` Word#
m#) Word# -> Word# -> Word#
`or#` (Int# -> Word#
int2Word# Int#
lo# Word# -> Word# -> Word#
`and#` Word#
nm#)
!out :: Elem
out = Word# -> Elem
U.primWordToElem Word#
r#
{-# INLINE hashToElem #-}
emptyMarker :: Elem
emptyMarker :: Elem
emptyMarker = Elem
0
maxLoad :: Double
maxLoad :: Double
maxLoad = Double
0.88
bumpFactor :: Double
bumpFactor :: Double
bumpFactor = Double
0.73
debug :: String -> ST s ()
#ifdef DEBUG
debug s = unsafeIOToST (putStrLn s >> hFlush stdout)
#else
debug :: String -> ST s ()
debug String
_ = () -> ST s ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
#endif
{-# INLINE debug #-}
whichLine :: Int -> Int -> Int
whichLine :: Int -> Int -> Int
whichLine !Int
h !Int
sz = Int -> Int -> Int
whichBucket Int
h Int
sz Int -> Int -> Int
`iShiftL` Int
cacheLineIntBits
{-# INLINE whichLine #-}
newRef :: HashTable_ s k v -> ST s (HashTable s k v)
newRef :: HashTable_ s k v -> ST s (HashTable s k v)
newRef = (STRef s (HashTable_ s k v) -> HashTable s k v)
-> ST s (STRef s (HashTable_ s k v)) -> ST s (HashTable s k v)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM STRef s (HashTable_ s k v) -> HashTable s k v
forall s k v. STRef s (HashTable_ s k v) -> HashTable s k v
HT (ST s (STRef s (HashTable_ s k v)) -> ST s (HashTable s k v))
-> (HashTable_ s k v -> ST s (STRef s (HashTable_ s k v)))
-> HashTable_ s k v
-> ST s (HashTable s k v)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashTable_ s k v -> ST s (STRef s (HashTable_ s k v))
forall a s. a -> ST s (STRef s a)
newSTRef
{-# INLINE newRef #-}
writeRef :: HashTable s k v -> HashTable_ s k v -> ST s ()
writeRef :: HashTable s k v -> HashTable_ s k v -> ST s ()
writeRef (HT STRef s (HashTable_ s k v)
ref) HashTable_ s k v
ht = STRef s (HashTable_ s k v) -> HashTable_ s k v -> ST s ()
forall s a. STRef s a -> a -> ST s ()
writeSTRef STRef s (HashTable_ s k v)
ref HashTable_ s k v
ht
{-# INLINE writeRef #-}
readRef :: HashTable s k v -> ST s (HashTable_ s k v)
readRef :: HashTable s k v -> ST s (HashTable_ s k v)
readRef (HT STRef s (HashTable_ s k v)
ref) = STRef s (HashTable_ s k v) -> ST s (HashTable_ s k v)
forall s a. STRef s a -> ST s a
readSTRef STRef s (HashTable_ s k v)
ref
{-# INLINE readRef #-}
lookupIndex :: (Hashable k, Eq k) => HashTable s k v -> k -> ST s (Maybe Word)
lookupIndex :: HashTable s k v -> k -> ST s (Maybe Word)
lookupIndex HashTable s k v
htRef k
k =
do HashTable Int
sz BitStream s
_ IntArray s
hashes MutableArray s k
keys MutableArray s v
_ Int
_ <- HashTable s k v -> ST s (HashTable_ s k v)
forall s k v. HashTable s k v -> ST s (HashTable_ s k v)
readRef HashTable s k v
htRef
let !h1 :: Int
h1 = k -> Int
forall k. Hashable k => k -> Int
hash1 k
k
!h2 :: Int
h2 = k -> Int
forall k. Hashable k => k -> Int
hash2 k
k
!he1 :: Elem
he1 = Int -> Elem
hashToElem Int
h1
!he2 :: Elem
he2 = Int -> Elem
hashToElem Int
h2
!b1 :: Int
b1 = Int -> Int -> Int
whichLine Int
h1 Int
sz
!b2 :: Int
b2 = Int -> Int -> Int
whichLine Int
h2 Int
sz
Int
idx1 <- MutableArray s k -> IntArray s -> k -> Int -> Elem -> ST s Int
forall k s.
Eq k =>
MutableArray s k -> IntArray s -> k -> Int -> Elem -> ST s Int
searchOne MutableArray s k
keys IntArray s
hashes k
k Int
b1 Elem
he1
if Int
idx1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0
then Maybe Word -> ST s (Maybe Word)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Word -> ST s (Maybe Word))
-> Maybe Word -> ST s (Maybe Word)
forall a b. (a -> b) -> a -> b
$! (Word -> Maybe Word
forall a. a -> Maybe a
Just (Word -> Maybe Word) -> Word -> Maybe Word
forall a b. (a -> b) -> a -> b
$! Int -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
idx1)
else do Int
idx2 <- MutableArray s k -> IntArray s -> k -> Int -> Elem -> ST s Int
forall k s.
Eq k =>
MutableArray s k -> IntArray s -> k -> Int -> Elem -> ST s Int
searchOne MutableArray s k
keys IntArray s
hashes k
k Int
b2 Elem
he2
if Int
idx2 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0
then Maybe Word -> ST s (Maybe Word)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Word -> ST s (Maybe Word))
-> Maybe Word -> ST s (Maybe Word)
forall a b. (a -> b) -> a -> b
$! (Word -> Maybe Word
forall a. a -> Maybe a
Just (Word -> Maybe Word) -> Word -> Maybe Word
forall a b. (a -> b) -> a -> b
$! Int -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
idx2)
else Maybe Word -> ST s (Maybe Word)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Word
forall a. Maybe a
Nothing
nextByIndex :: HashTable s k v -> Word -> ST s (Maybe (Word,k,v))
nextByIndex :: HashTable s k v -> Word -> ST s (Maybe (Word, k, v))
nextByIndex HashTable s k v
htRef Word
i0 =
do HashTable Int
sz BitStream s
_ IntArray s
hashes MutableArray s k
keys MutableArray s v
values Int
_ <- HashTable s k v -> ST s (HashTable_ s k v)
forall s k v. HashTable s k v -> ST s (HashTable_ s k v)
readRef HashTable s k v
htRef
let totSz :: Int
totSz = Int
numElemsInCacheLine Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
sz
go :: Int -> ST s (Maybe (a, k, v))
go Int
i
| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
totSz = Maybe (a, k, v) -> ST s (Maybe (a, k, v))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (a, k, v)
forall a. Maybe a
Nothing
| Bool
otherwise =
do Elem
h <- IntArray s -> Int -> ST s Elem
forall s. IntArray s -> Int -> ST s Elem
U.readArray IntArray s
hashes Int
i
if Elem
h Elem -> Elem -> Bool
forall a. Eq a => a -> a -> Bool
== Elem
emptyMarker
then Int -> ST s (Maybe (a, k, v))
go (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)
else do k
k <- MutableArray (PrimState (ST s)) k -> Int -> ST s k
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> m a
readArray MutableArray s k
MutableArray (PrimState (ST s)) k
keys Int
i
v
v <- MutableArray (PrimState (ST s)) v -> Int -> ST s v
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> m a
readArray MutableArray s v
MutableArray (PrimState (ST s)) v
values Int
i
let !i' :: a
i' = Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
i
Maybe (a, k, v) -> ST s (Maybe (a, k, v))
forall (m :: * -> *) a. Monad m => a -> m a
return ((a, k, v) -> Maybe (a, k, v)
forall a. a -> Maybe a
Just (a
i',k
k,v
v))
Int -> ST s (Maybe (Word, k, v))
forall a. Num a => Int -> ST s (Maybe (a, k, v))
go (Word -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word
i0)