Skip to content

Commit 32ebb33

Browse files
vrom911chshersh
authored andcommitted
[#30] Rewrite fromSortedList to use arrays (#51)
* [30] Rewrite fromSortedList to use arrays * Improve more * Use unsafeFreezeArray in adjust
1 parent 92b6021 commit 32ebb33

File tree

2 files changed

+25
-16
lines changed

2 files changed

+25
-16
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ The change log is available [on GitHub][2].
1111
Add `keys` function.
1212
* [#48](https://github.com/kowainik/typerep-map/issues/48):
1313
Add `adjust` function for `TypeRepMap` and `TMap`.
14+
* [#30](https://github.com/kowainik/typerep-map/issues/30):
15+
Rewrite `fromSortedList` to use `Array` and `MutableArray`
16+
instead of `IntMap`.
17+
1418

1519
# 0.2.0
1620

src/Data/TypeRepMap/Internal.hs

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,13 @@ module Data.TypeRepMap.Internal where
2323

2424
import Prelude hiding (lookup)
2525

26-
import Control.Monad.ST (runST)
26+
import Control.Monad.ST (ST, runST)
2727
import Control.Monad.Zip (mzip)
2828
import Data.Function (on)
29-
import Data.IntMap.Strict (IntMap)
3029
import Data.Kind (Type)
3130
import Data.List (intercalate, nubBy)
32-
import Data.Maybe (fromJust)
33-
import Data.Primitive.Array (Array, freezeArray, indexArray, mapArray', readArray, sizeofArray,
34-
thawArray, writeArray)
31+
import Data.Primitive.Array (Array, MutableArray, indexArray, mapArray', readArray, sizeofArray,
32+
thawArray, unsafeFreezeArray, writeArray)
3533
import Data.Primitive.PrimArray (PrimArray, indexPrimArray, sizeofPrimArray)
3634
import Data.Semigroup (Semigroup (..))
3735
import GHC.Base (Any, Int (..), Int#, (*#), (+#), (<#))
@@ -43,7 +41,6 @@ import Type.Reflection (SomeTypeRep (..), TypeRep, Typeable, typeRep, withTypeab
4341
import Type.Reflection.Unsafe (typeRepFingerprint)
4442
import Unsafe.Coerce (unsafeCoerce)
4543

46-
import qualified Data.IntMap.Strict as IM
4744
import qualified Data.Map.Strict as Map
4845
import qualified GHC.Exts as GHC (fromList, toList)
4946

@@ -183,7 +180,7 @@ adjust fun tr = case cachedBinarySearch (typeFp @a) (fingerprintAs tr) (fingerpr
183180
mutArr <- thawArray trAs 0 n
184181
a <- toAny . fun . fromAny <$> readArray mutArr i
185182
writeArray mutArr i a
186-
freezeArray mutArr 0 n
183+
unsafeFreezeArray mutArr
187184
{-# INLINE adjust #-}
188185

189186
{- | Map over the elements of a 'TypeRepMap'.
@@ -390,14 +387,22 @@ fromTriples kvs = TypeRepMap (GHC.fromList fpAs) (GHC.fromList fpBs) (GHC.fromLi
390387
----------------------------------------------------------------------------
391388

392389
fromSortedList :: forall a . [a] -> [a]
393-
fromSortedList l = IM.elems $ fst $ go 0 0 mempty (IM.fromList $ zip [0..] l)
390+
fromSortedList l = runST $ do
391+
let n = length l
392+
let arrOrigin = fromListN n l
393+
arrResult <- thawArray arrOrigin 0 n
394+
go n arrResult arrOrigin
395+
toList <$> unsafeFreezeArray arrResult
394396
where
395397
-- state monad could be used here, but it's another dependency
396-
go :: Int -> Int -> IntMap a -> IntMap a -> (IntMap a, Int)
397-
go i first result vector =
398-
if i >= IM.size vector
399-
then (result, first)
400-
else do
401-
let (newResult, newFirst) = go (2 * i + 1) first result vector
402-
let withCur = IM.insert i (fromJust $ IM.lookup newFirst vector) newResult
403-
go (2 * i + 2) (newFirst + 1) withCur vector
398+
go :: forall s . Int -> MutableArray s a -> Array a -> ST s ()
399+
go len result origin = () <$ loop 0 0
400+
where
401+
loop :: Int -> Int -> ST s Int
402+
loop i first =
403+
if i >= len
404+
then pure first
405+
else do
406+
newFirst <- loop (2 * i + 1) first
407+
writeArray result i (indexArray origin newFirst)
408+
loop (2 * i + 2) (newFirst + 1)

0 commit comments

Comments
 (0)