- fix one performance bug: we weren't updating the bucket count when
expanding the hash table, so too many expansions were happening.
- slight improvement to hashString: if we use foldl rather than foldr,
the resulting code uses an accumulating parameter and runs in linear
stack space.
import Data.Tuple ( fst )
import Data.Bits
import Data.Maybe
import Data.Tuple ( fst )
import Data.Bits
import Data.Maybe
-import Data.List ( maximumBy, filter, length, concat )
+import Data.List ( maximumBy, filter, length, concat, foldl )
import Data.Int ( Int32 )
#if defined(__GLASGOW_HASKELL__)
import Data.Int ( Int32 )
#if defined(__GLASGOW_HASKELL__)
-- which seems to give reasonable results.
--
hashString :: String -> Int32
-- which seems to give reasonable results.
--
hashString :: String -> Int32
-hashString = fromIntegral . foldr f 0
- where f c m = ord c + (m * 128) `rem` fromIntegral prime
+hashString = fromIntegral . foldl f 0
+ where f m c = ord c + (m * 128) `rem` fromIntegral prime
-- | A prime larger than the maximum hash table size
prime :: Int32
-- | A prime larger than the maximum hash table size
prime :: Int32
table@HT{ dir=dir,
split=split,
max_bucket=max,
table@HT{ dir=dir,
split=split,
max_bucket=max,
mask2=mask2 } = do
let
oldsegment = split `shiftR` sEGMENT_SHIFT
mask2=mask2 } = do
let
oldsegment = split `shiftR` sEGMENT_SHIFT
--
let table' =
if (split+1) < max
--
let table' =
if (split+1) < max
- then table{ split = split+1 }
+ then table{ split = split+1,
+ bcount = bcount+1 }
-- we've expanded all the buckets in this table, so start from
-- the beginning again.
else table{ split = 0,
-- we've expanded all the buckets in this table, so start from
-- the beginning again.
else table{ split = 0,
max_bucket = max * 2,
mask1 = mask2,
mask2 = mask2 `shiftL` 1 .|. 1 }
max_bucket = max * 2,
mask1 = mask2,
mask2 = mask2 `shiftL` 1 .|. 1 }