Skip to content

Commit c0d3976

Browse files
authored
Merge pull request #164 from ethercrow/smallarray
Use SmallArray#
2 parents 2aa9f86 + 74754b4 commit c0d3976

File tree

7 files changed

+38
-151
lines changed

7 files changed

+38
-151
lines changed

.travis.yml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,6 @@ before_cache:
1313

1414
matrix:
1515
include:
16-
- env: CABALVER=1.24 GHCVER=7.4.2
17-
compiler: ": #GHC 7.4.2"
18-
addons: {apt: {packages: [cabal-install-1.24,ghc-7.4.2], sources: [hvr-ghc]}}
19-
- env: CABALVER=1.24 GHCVER=7.6.3
20-
compiler: ": #GHC 7.6.3"
21-
addons: {apt: {packages: [cabal-install-1.24,ghc-7.6.3], sources: [hvr-ghc]}}
2216
- env: CABALVER=1.24 GHCVER=7.8.4
2317
compiler: ": #GHC 7.8.4"
2418
addons: {apt: {packages: [cabal-install-1.24,ghc-7.8.4], sources: [hvr-ghc]}}

Data/HashMap/Array.hs

Lines changed: 30 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,7 @@ import qualified Data.Traversable as Traversable
5353
import Control.Applicative (Applicative)
5454
#endif
5555
import Control.DeepSeq
56-
-- GHC 7.7 exports toList/fromList from GHC.Exts
57-
-- In order to avoid warnings on previous GHC versions, we provide
58-
-- an explicit import list instead of only hiding the offending symbols
59-
import GHC.Exts (Array#, Int(..), newArray#, readArray#, writeArray#,
60-
indexArray#, unsafeFreezeArray#, unsafeThawArray#,
61-
MutableArray#)
56+
import GHC.Exts(Int(..))
6257
import GHC.ST (ST(..))
6358

6459
#if __GLASGOW_HASKELL__ >= 709
@@ -67,9 +62,17 @@ import Prelude hiding (filter, foldr, length, map, read, traverse)
6762
import Prelude hiding (filter, foldr, length, map, read)
6863
#endif
6964

70-
#if __GLASGOW_HASKELL__ >= 702
71-
import GHC.Exts (sizeofArray#, copyArray#, thawArray#, sizeofMutableArray#,
72-
copyMutableArray#)
65+
#if __GLASGOW_HASKELL__ >= 710
66+
import GHC.Exts (SmallArray#, newSmallArray#, readSmallArray#, writeSmallArray#,
67+
indexSmallArray#, unsafeFreezeSmallArray#, unsafeThawSmallArray#,
68+
SmallMutableArray#, sizeofSmallArray#, copySmallArray#, thawSmallArray#,
69+
sizeofSmallMutableArray#, copySmallMutableArray#)
70+
71+
#else
72+
import GHC.Exts (Array#, newArray#, readArray#, writeArray#,
73+
indexArray#, unsafeFreezeArray#, unsafeThawArray#,
74+
MutableArray#, sizeofArray#, copyArray#, thawArray#,
75+
sizeofMutableArray#, copyMutableArray#)
7376
#endif
7477

7578
#if defined(ASSERTS)
@@ -78,6 +81,24 @@ import qualified Prelude
7881

7982
import Data.HashMap.Unsafe (runST)
8083

84+
85+
#if __GLASGOW_HASKELL__ >= 710
86+
type Array# a = SmallArray# a
87+
type MutableArray# a = SmallMutableArray# a
88+
89+
newArray# = newSmallArray#
90+
readArray# = readSmallArray#
91+
writeArray# = writeSmallArray#
92+
indexArray# = indexSmallArray#
93+
unsafeFreezeArray# = unsafeFreezeSmallArray#
94+
unsafeThawArray# = unsafeThawSmallArray#
95+
sizeofArray# = sizeofSmallArray#
96+
copyArray# = copySmallArray#
97+
thawArray# = thawSmallArray#
98+
sizeofMutableArray# = sizeofSmallMutableArray#
99+
copyMutableArray# = copySmallMutableArray#
100+
#endif
101+
81102
------------------------------------------------------------------------
82103

83104
#if defined(ASSERTS)
@@ -100,49 +121,31 @@ if not ((_lhs_) _op_ (_rhs_)) then error ("Data.HashMap.Array." ++ (_func_) ++ "
100121

101122
data Array a = Array {
102123
unArray :: !(Array# a)
103-
#if __GLASGOW_HASKELL__ < 702
104-
, length :: !Int
105-
#endif
106124
}
107125

108126
instance Show a => Show (Array a) where
109127
show = show . toList
110128

111-
#if __GLASGOW_HASKELL__ >= 702
112129
length :: Array a -> Int
113130
length ary = I# (sizeofArray# (unArray ary))
114131
{-# INLINE length #-}
115-
#endif
116132

117133
-- | Smart constructor
118134
array :: Array# a -> Int -> Array a
119-
#if __GLASGOW_HASKELL__ >= 702
120135
array ary _n = Array ary
121-
#else
122-
array = Array
123-
#endif
124136
{-# INLINE array #-}
125137

126138
data MArray s a = MArray {
127139
unMArray :: !(MutableArray# s a)
128-
#if __GLASGOW_HASKELL__ < 702
129-
, lengthM :: !Int
130-
#endif
131140
}
132141

133-
#if __GLASGOW_HASKELL__ >= 702
134142
lengthM :: MArray s a -> Int
135143
lengthM mary = I# (sizeofMutableArray# (unMArray mary))
136144
{-# INLINE lengthM #-}
137-
#endif
138145

139146
-- | Smart constructor
140147
marray :: MutableArray# s a -> Int -> MArray s a
141-
#if __GLASGOW_HASKELL__ >= 702
142148
marray mary _n = MArray mary
143-
#else
144-
marray = MArray
145-
#endif
146149
{-# INLINE marray #-}
147150

148151
------------------------------------------------------------------------
@@ -237,47 +240,21 @@ run2 k = runST (do
237240

238241
-- | Unsafely copy the elements of an array. Array bounds are not checked.
239242
copy :: Array e -> Int -> MArray s e -> Int -> Int -> ST s ()
240-
#if __GLASGOW_HASKELL__ >= 702
241243
copy !src !_sidx@(I# sidx#) !dst !_didx@(I# didx#) _n@(I# n#) =
242244
CHECK_LE("copy", _sidx + _n, length src)
243245
CHECK_LE("copy", _didx + _n, lengthM dst)
244246
ST $ \ s# ->
245247
case copyArray# (unArray src) sidx# (unMArray dst) didx# n# s# of
246248
s2 -> (# s2, () #)
247-
#else
248-
copy !src !sidx !dst !didx n =
249-
CHECK_LE("copy", sidx + n, length src)
250-
CHECK_LE("copy", didx + n, lengthM dst)
251-
copy_loop sidx didx 0
252-
where
253-
copy_loop !i !j !c
254-
| c >= n = return ()
255-
| otherwise = do b <- indexM src i
256-
write dst j b
257-
copy_loop (i+1) (j+1) (c+1)
258-
#endif
259249

260250
-- | Unsafely copy the elements of an array. Array bounds are not checked.
261251
copyM :: MArray s e -> Int -> MArray s e -> Int -> Int -> ST s ()
262-
#if __GLASGOW_HASKELL__ >= 702
263252
copyM !src !_sidx@(I# sidx#) !dst !_didx@(I# didx#) _n@(I# n#) =
264253
CHECK_BOUNDS("copyM: src", lengthM src, _sidx + _n - 1)
265254
CHECK_BOUNDS("copyM: dst", lengthM dst, _didx + _n - 1)
266255
ST $ \ s# ->
267256
case copyMutableArray# (unMArray src) sidx# (unMArray dst) didx# n# s# of
268257
s2 -> (# s2, () #)
269-
#else
270-
copyM !src !sidx !dst !didx n =
271-
CHECK_BOUNDS("copyM: src", lengthM src, sidx + n - 1)
272-
CHECK_BOUNDS("copyM: dst", lengthM dst, didx + n - 1)
273-
copy_loop sidx didx 0
274-
where
275-
copy_loop !i !j !c
276-
| c >= n = return ()
277-
| otherwise = do b <- read src i
278-
write dst j b
279-
copy_loop (i+1) (j+1) (c+1)
280-
#endif
281258

282259
-- | /O(n)/ Insert an element at the given position in this array,
283260
-- increasing its size by one.
@@ -352,18 +329,10 @@ undefinedElem = error "Data.HashMap.Array: Undefined element"
352329
{-# NOINLINE undefinedElem #-}
353330

354331
thaw :: Array e -> Int -> Int -> ST s (MArray s e)
355-
#if __GLASGOW_HASKELL__ >= 702
356332
thaw !ary !_o@(I# o#) !n@(I# n#) =
357333
CHECK_LE("thaw", _o + n, length ary)
358334
ST $ \ s -> case thawArray# (unArray ary) o# n# s of
359335
(# s2, mary# #) -> (# s2, marray mary# n #)
360-
#else
361-
thaw !ary !o !n =
362-
CHECK_LE("thaw", o + n, length ary)
363-
do mary <- new_ n
364-
copy ary o mary 0 n
365-
return mary
366-
#endif
367336
{-# INLINE thaw #-}
368337

369338
-- | /O(n)/ Delete an element at the given position in this array,

Data/HashMap/Base.hs

Lines changed: 1 addition & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
{-# LANGUAGE BangPatterns, CPP, DeriveDataTypeable, MagicHash #-}
22
{-# LANGUAGE ScopedTypeVariables #-}
33
{-# LANGUAGE PatternGuards #-}
4-
#if __GLASGOW_HASKELL__ >= 708
54
{-# LANGUAGE RoleAnnotations #-}
65
{-# LANGUAGE TypeFamilies #-}
7-
#endif
86
{-# OPTIONS_GHC -fno-full-laziness -funbox-strict-fields #-}
97

108
module Data.HashMap.Base
@@ -104,7 +102,7 @@ import Data.Semigroup (Semigroup((<>)))
104102
#endif
105103
import Control.DeepSeq (NFData(rnf))
106104
import Control.Monad.ST (ST)
107-
import Data.Bits ((.&.), (.|.), complement)
105+
import Data.Bits ((.&.), (.|.), complement, popCount)
108106
import Data.Data hiding (Typeable)
109107
import qualified Data.Foldable as Foldable
110108
import qualified Data.List as L
@@ -115,18 +113,13 @@ import Text.Read hiding (step)
115113
import qualified Data.HashMap.Array as A
116114
import qualified Data.Hashable as H
117115
import Data.Hashable (Hashable)
118-
import Data.HashMap.PopCount (popCount)
119116
import Data.HashMap.Unsafe (runST)
120117
import Data.HashMap.UnsafeShift (unsafeShiftL, unsafeShiftR)
121118
import Data.HashMap.List (isPermutationBy, unorderedCompare)
122119
import Data.Typeable (Typeable)
123120

124-
#if __GLASGOW_HASKELL__ >= 707
125121
import GHC.Exts (isTrue#)
126-
#endif
127-
#if __GLASGOW_HASKELL__ >= 708
128122
import qualified GHC.Exts as Exts
129-
#endif
130123

131124
#if MIN_VERSION_base(4,9,0)
132125
import Data.Functor.Classes
@@ -162,9 +155,7 @@ data HashMap k v
162155
| Collision !Hash !(A.Array (Leaf k v))
163156
deriving (Typeable)
164157

165-
#if __GLASGOW_HASKELL__ >= 708
166158
type role HashMap nominal representational
167-
#endif
168159

169160
instance (NFData k, NFData v) => NFData (HashMap k v) where
170161
rnf Empty = ()
@@ -1319,28 +1310,7 @@ update16With' ary idx f = update16 ary idx $! f (A.index ary idx)
13191310
-- array is not checked.
13201311
clone16 :: A.Array e -> ST s (A.MArray s e)
13211312
clone16 ary =
1322-
#if __GLASGOW_HASKELL__ >= 702
13231313
A.thaw ary 0 16
1324-
#else
1325-
do mary <- A.new_ 16
1326-
A.indexM ary 0 >>= A.write mary 0
1327-
A.indexM ary 1 >>= A.write mary 1
1328-
A.indexM ary 2 >>= A.write mary 2
1329-
A.indexM ary 3 >>= A.write mary 3
1330-
A.indexM ary 4 >>= A.write mary 4
1331-
A.indexM ary 5 >>= A.write mary 5
1332-
A.indexM ary 6 >>= A.write mary 6
1333-
A.indexM ary 7 >>= A.write mary 7
1334-
A.indexM ary 8 >>= A.write mary 8
1335-
A.indexM ary 9 >>= A.write mary 9
1336-
A.indexM ary 10 >>= A.write mary 10
1337-
A.indexM ary 11 >>= A.write mary 11
1338-
A.indexM ary 12 >>= A.write mary 12
1339-
A.indexM ary 13 >>= A.write mary 13
1340-
A.indexM ary 14 >>= A.write mary 14
1341-
A.indexM ary 15 >>= A.write mary 15
1342-
return mary
1343-
#endif
13441314

13451315
------------------------------------------------------------------------
13461316
-- Bit twiddling
@@ -1375,18 +1345,12 @@ fullNodeMask = complement (complement 0 `unsafeShiftL` maxChildren)
13751345
-- | Check if two the two arguments are the same value. N.B. This
13761346
-- function might give false negatives (due to GC moving objects.)
13771347
ptrEq :: a -> a -> Bool
1378-
#if __GLASGOW_HASKELL__ < 707
1379-
ptrEq x y = reallyUnsafePtrEquality# x y ==# 1#
1380-
#else
13811348
ptrEq x y = isTrue# (reallyUnsafePtrEquality# x y ==# 1#)
1382-
#endif
13831349
{-# INLINE ptrEq #-}
13841350

1385-
#if __GLASGOW_HASKELL__ >= 708
13861351
------------------------------------------------------------------------
13871352
-- IsList instance
13881353
instance (Eq k, Hashable k) => Exts.IsList (HashMap k v) where
13891354
type Item (HashMap k v) = (k, v)
13901355
fromList = fromList
13911356
toList = toList
1392-
#endif

Data/HashMap/Lazy.hs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
{-# LANGUAGE CPP #-}
2-
3-
#if __GLASGOW_HASKELL__ >= 702
42
{-# LANGUAGE Trustworthy #-}
5-
#endif
63

74
------------------------------------------------------------------------
85
-- |

Data/HashMap/PopCount.hs

Lines changed: 0 additions & 19 deletions
This file was deleted.

Data/HashMap/Strict.hs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
{-# LANGUAGE BangPatterns, CPP, PatternGuards #-}
2-
3-
#if __GLASGOW_HASKELL__ >= 702
42
{-# LANGUAGE Trustworthy #-}
5-
#endif
63

74
------------------------------------------------------------------------
85
-- |

unordered-containers.cabal

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ category: Data
2020
build-type: Simple
2121
cabal-version: >=1.8
2222
extra-source-files: CHANGES.md
23-
tested-with: GHC==8.0.1, GHC==7.10.3, GHC==7.8.4, GHC==7.6.3, GHC==7.4.2
23+
tested-with: GHC==8.0.1, GHC==7.10.3, GHC==7.8.4
2424

2525
flag debug
2626
description: Enable debug support
@@ -35,7 +35,6 @@ library
3535
Data.HashMap.Array
3636
Data.HashMap.Base
3737
Data.HashMap.List
38-
Data.HashMap.PopCount
3938
Data.HashMap.Unsafe
4039
Data.HashMap.UnsafeShift
4140

@@ -44,17 +43,11 @@ library
4443
deepseq >= 1.1,
4544
hashable >= 1.0.1.1 && < 1.3
4645

47-
if impl(ghc < 7.4)
48-
c-sources: cbits/popc.c
49-
50-
ghc-options: -Wall -O2
51-
if impl(ghc >= 6.8)
52-
ghc-options: -fwarn-tabs
53-
if impl(ghc >= 6.12)
54-
-- This is absolutely essential for correctness due to the
55-
-- referential-transparency-breaking mutability in unsafeInsertWith. See
56-
-- #147 and GHC #13615 for details.
57-
ghc-options: -feager-blackholing
46+
ghc-options: -Wall -O2 -fwarn-tabs -ferror-spans
47+
-- This is absolutely essential for correctness due to the
48+
-- referential-transparency-breaking mutability in unsafeInsertWith. See
49+
-- #147 and GHC #13615 for details.
50+
ghc-options: -feager-blackholing
5851
if flag(debug)
5952
cpp-options: -DASSERTS
6053

@@ -174,7 +167,6 @@ benchmark benchmarks
174167
Data.HashMap.Array
175168
Data.HashMap.Base
176169
Data.HashMap.Lazy
177-
Data.HashMap.PopCount
178170
Data.HashMap.Strict
179171
Data.HashMap.Unsafe
180172
Data.HashMap.UnsafeShift
@@ -195,14 +187,7 @@ benchmark benchmarks
195187
mtl,
196188
random
197189

198-
if impl(ghc < 7.4)
199-
c-sources: cbits/popc.c
200-
201-
ghc-options: -Wall -O2 -rtsopts
202-
if impl(ghc >= 6.8)
203-
ghc-options: -fwarn-tabs
204-
if impl(ghc > 6.10)
205-
ghc-options: -fregs-graph
190+
ghc-options: -Wall -O2 -rtsopts -fwarn-tabs -ferror-spans
206191
if flag(debug)
207192
cpp-options: -DASSERTS
208193

0 commit comments

Comments
 (0)