@@ -320,6 +320,7 @@ import Utils.Containers.Internal.Prelude hiding
320
320
(lookup , map , filter , foldr , foldl , foldl' , null )
321
321
import Prelude ()
322
322
323
+ import Data.IntSet.Internal (IntSet )
323
324
import qualified Data.IntSet.Internal as IntSet
324
325
import Data.IntSet.Internal.IntTreeCommons
325
326
( Key
@@ -335,7 +336,7 @@ import Data.IntSet.Internal.IntTreeCommons
335
336
, i2w
336
337
, Order (.. )
337
338
)
338
- import Utils.Containers.Internal.BitUtil (shiftLL , shiftRL , iShiftRL )
339
+ import Utils.Containers.Internal.BitUtil (shiftLL , shiftRL , iShiftRL , wordSize )
339
340
import Utils.Containers.Internal.StrictPair
340
341
341
342
#ifdef __GLASGOW_HASKELL__
@@ -402,20 +403,11 @@ data IntMap a = Bin {-# UNPACK #-} !Prefix
402
403
-- See Note [Okasaki-Gill] for how the implementation here relates to the one in
403
404
-- Okasaki and Gill's paper.
404
405
405
- -- Some stuff from "Data.IntSet.Internal", for 'restrictKeys' and
406
- -- 'withoutKeys' to use.
407
- type IntSetPrefix = Int
408
- type IntSetBitMap = Word
409
-
410
406
#ifdef __GLASGOW_HASKELL__
411
407
-- | @since 0.6.6
412
408
deriving instance Lift a => Lift (IntMap a )
413
409
#endif
414
410
415
- bitmapOf :: Int -> IntSetBitMap
416
- bitmapOf x = shiftLL 1 (x .&. IntSet. suffixBitMask)
417
- {-# INLINE bitmapOf #-}
418
-
419
411
{- -------------------------------------------------------------------
420
412
Operators
421
413
--------------------------------------------------------------------}
@@ -1196,7 +1188,7 @@ differenceWithKey f m1 m2
1196
1188
-- @
1197
1189
--
1198
1190
-- @since 0.5.8
1199
- withoutKeys :: IntMap a -> IntSet. IntSet -> IntMap a
1191
+ withoutKeys :: IntMap a -> IntSet -> IntMap a
1200
1192
withoutKeys t1@ (Bin p1 l1 r1) t2@ (IntSet. Bin p2 l2 r2) = case treeTreeBranch p1 p2 of
1201
1193
ABL -> binCheckLeft p1 (withoutKeys l1 t2) r1
1202
1194
ABR -> binCheckRight p1 l1 (withoutKeys r1 t2)
@@ -1205,49 +1197,26 @@ withoutKeys t1@(Bin p1 l1 r1) t2@(IntSet.Bin p2 l2 r2) = case treeTreeBranch p1
1205
1197
EQL -> bin p1 (withoutKeys l1 l2) (withoutKeys r1 r2)
1206
1198
NOM -> t1
1207
1199
where
1208
- withoutKeys t1@ (Bin p1 _ _) (IntSet. Tip p2 bm2) =
1209
- let px1 = unPrefix p1
1210
- minbit = bitmapOf (px1 .&. (px1- 1 ))
1211
- lt_minbit = minbit - 1
1212
- maxbit = bitmapOf (px1 .|. (px1- 1 ))
1213
- gt_maxbit = (- maxbit) `xor` maxbit
1214
- -- TODO(wrengr): should we manually inline/unroll 'updatePrefix'
1215
- -- and 'withoutBM' here, in order to avoid redundant case analyses?
1216
- in updatePrefix p2 t1 $ withoutBM (bm2 .|. lt_minbit .|. gt_maxbit)
1200
+ withoutKeys t1@ (Bin _ _ _) (IntSet. Tip p2 bm2) = withoutKeysTip t1 p2 bm2
1217
1201
withoutKeys t1@ (Bin _ _ _) IntSet. Nil = t1
1218
1202
withoutKeys t1@ (Tip k1 _) t2
1219
1203
| k1 `IntSet.member` t2 = Nil
1220
1204
| otherwise = t1
1221
1205
withoutKeys Nil _ = Nil
1222
1206
1223
-
1224
- updatePrefix
1225
- :: IntSetPrefix -> IntMap a -> (IntMap a -> IntMap a ) -> IntMap a
1226
- updatePrefix ! kp t@ (Bin p l r) f
1227
- | unPrefix p .&. IntSet. suffixBitMask /= 0 =
1228
- if unPrefix p .&. IntSet. prefixBitMask == kp then f t else t
1229
- | nomatch kp p = t
1230
- | left kp p = binCheckLeft p (updatePrefix kp l f) r
1231
- | otherwise = binCheckRight p l (updatePrefix kp r f)
1232
- updatePrefix kp t@ (Tip kx _) f
1233
- | kx .&. IntSet. prefixBitMask == kp = f t
1234
- | otherwise = t
1235
- updatePrefix _ Nil _ = Nil
1236
-
1237
-
1238
- withoutBM :: IntSetBitMap -> IntMap a -> IntMap a
1239
- withoutBM 0 t = t
1240
- withoutBM bm (Bin p l r) =
1241
- let leftBits = bitmapOf (unPrefix p) - 1
1242
- bmL = bm .&. leftBits
1243
- bmR = bm `xor` bmL -- = (bm .&. complement leftBits)
1244
- in bin p (withoutBM bmL l) (withoutBM bmR r)
1245
- withoutBM bm t@ (Tip k _)
1246
- -- TODO(wrengr): need we manually inline 'IntSet.Member' here?
1247
- | k `IntSet.member` IntSet. Tip (k .&. IntSet. prefixBitMask) bm = Nil
1248
- | otherwise = t
1249
- withoutBM _ Nil = Nil
1250
-
1207
+ withoutKeysTip :: IntMap a -> Int -> IntSet. BitMap -> IntMap a
1208
+ withoutKeysTip t@ (Bin p l r) ! p2 ! bm2
1209
+ | IntSet. suffixOf (unPrefix p) /= 0 =
1210
+ if IntSet. prefixOf (unPrefix p) == p2
1211
+ then restrictBM t (complement bm2)
1212
+ else t
1213
+ | nomatch p2 p = t
1214
+ | left p2 p = binCheckLeft p (withoutKeysTip l p2 bm2) r
1215
+ | otherwise = binCheckRight p l (withoutKeysTip r p2 bm2)
1216
+ withoutKeysTip t@ (Tip kx _) ! p2 ! bm2
1217
+ | IntSet. prefixOf kx == p2 && IntSet. bitmapOf kx .&. bm2 /= 0 = Nil
1218
+ | otherwise = t
1219
+ withoutKeysTip Nil ! _ ! _ = Nil
1251
1220
1252
1221
{- -------------------------------------------------------------------
1253
1222
Intersection
@@ -1270,58 +1239,63 @@ intersection m1 m2
1270
1239
-- @
1271
1240
--
1272
1241
-- @since 0.5.8
1273
- restrictKeys :: IntMap a -> IntSet. IntSet -> IntMap a
1242
+ restrictKeys :: IntMap a -> IntSet -> IntMap a
1274
1243
restrictKeys t1@ (Bin p1 l1 r1) t2@ (IntSet. Bin p2 l2 r2) = case treeTreeBranch p1 p2 of
1275
1244
ABL -> restrictKeys l1 t2
1276
1245
ABR -> restrictKeys r1 t2
1277
1246
BAL -> restrictKeys t1 l2
1278
1247
BAR -> restrictKeys t1 r2
1279
1248
EQL -> bin p1 (restrictKeys l1 l2) (restrictKeys r1 r2)
1280
1249
NOM -> Nil
1281
- restrictKeys t1@ (Bin p1 _ _) (IntSet. Tip p2 bm2) =
1282
- let px1 = unPrefix p1
1283
- minbit = bitmapOf (px1 .&. (px1- 1 ))
1284
- ge_minbit = complement (minbit - 1 )
1285
- maxbit = bitmapOf (px1 .|. (px1- 1 ))
1286
- le_maxbit = maxbit .|. (maxbit - 1 )
1287
- -- TODO(wrengr): should we manually inline/unroll 'lookupPrefix'
1288
- -- and 'restrictBM' here, in order to avoid redundant case analyses?
1289
- in restrictBM (bm2 .&. ge_minbit .&. le_maxbit) (lookupPrefix p2 t1)
1250
+ restrictKeys t1@ (Bin _ _ _) (IntSet. Tip p2 bm2) = restrictKeysTip t1 p2 bm2
1290
1251
restrictKeys (Bin _ _ _) IntSet. Nil = Nil
1291
1252
restrictKeys t1@ (Tip k1 _) t2
1292
1253
| k1 `IntSet.member` t2 = t1
1293
1254
| otherwise = Nil
1294
1255
restrictKeys Nil _ = Nil
1295
1256
1296
-
1297
- -- | \(O(\min(n,W))\). Restrict to the sub-map with all keys matching
1298
- -- a key prefix.
1299
- lookupPrefix :: IntSetPrefix -> IntMap a -> IntMap a
1300
- lookupPrefix ! kp t@ (Bin p l r)
1301
- | unPrefix p .&. IntSet. suffixBitMask /= 0 =
1302
- if unPrefix p .&. IntSet. prefixBitMask == kp then t else Nil
1303
- | nomatch kp p = Nil
1304
- | left kp p = lookupPrefix kp l
1305
- | otherwise = lookupPrefix kp r
1306
- lookupPrefix kp t@ (Tip kx _)
1307
- | (kx .&. IntSet. prefixBitMask) == kp = t
1308
- | otherwise = Nil
1309
- lookupPrefix _ Nil = Nil
1310
-
1311
-
1312
- restrictBM :: IntSetBitMap -> IntMap a -> IntMap a
1313
- restrictBM 0 _ = Nil
1314
- restrictBM bm (Bin p l r) =
1315
- let leftBits = bitmapOf (unPrefix p) - 1
1316
- bmL = bm .&. leftBits
1317
- bmR = bm `xor` bmL -- = (bm .&. complement leftBits)
1318
- in bin p (restrictBM bmL l) (restrictBM bmR r)
1319
- restrictBM bm t@ (Tip k _)
1320
- -- TODO(wrengr): need we manually inline 'IntSet.Member' here?
1321
- | k `IntSet.member` IntSet. Tip (k .&. IntSet. prefixBitMask) bm = t
1322
- | otherwise = Nil
1323
- restrictBM _ Nil = Nil
1324
-
1257
+ restrictKeysTip :: IntMap a -> Int -> IntSet. BitMap -> IntMap a
1258
+ restrictKeysTip t@ (Bin p l r) ! p2 ! bm2
1259
+ | IntSet. suffixOf (unPrefix p) /= 0 =
1260
+ if IntSet. prefixOf (unPrefix p) == p2
1261
+ then restrictBM t bm2
1262
+ else Nil
1263
+ | nomatch p2 p = Nil
1264
+ | left p2 p = restrictKeysTip l p2 bm2
1265
+ | otherwise = restrictKeysTip r p2 bm2
1266
+ restrictKeysTip t@ (Tip kx _) ! p2 ! bm2
1267
+ | IntSet. prefixOf kx == p2 && IntSet. bitmapOf kx .&. bm2 /= 0 = t
1268
+ | otherwise = Nil
1269
+ restrictKeysTip Nil ! _ ! _ = Nil
1270
+
1271
+ -- Must be called on an IntMap whose keys fit in the given IntSet BitMap's Tip.
1272
+ -- Keeps keys that match the BitMap.
1273
+ -- Returns early as an optimization, i.e. if the tree can be entirely kept or
1274
+ -- discarded there is no need to recursively visit the children.
1275
+ restrictBM :: IntMap a -> IntSet. BitMap -> IntMap a
1276
+ restrictBM t@ (Bin p l r) ! bm
1277
+ | bm' == 0 = Nil
1278
+ | bm' == - 1 = t
1279
+ | otherwise = bin p (restrictBM l bm) (restrictBM r bm)
1280
+ where
1281
+ -- Here we care about the "submask" of bm corresponding the current Bin's
1282
+ -- range. So we create bm', where this submask is at the lowest position and
1283
+ -- and all other bits are set to the highest bit of the submask (using an
1284
+ -- arithmetric shiftR). Now bm' is 0 when the submask is empty and -1 when
1285
+ -- the submask is full.
1286
+ px = IntSet. suffixOf (unPrefix p)
1287
+ px1 = px - 1
1288
+ min_ = px .&. px1
1289
+ max_ = px .|. px1
1290
+ sh = (wordSize - 1 ) - max_
1291
+ bm' = (w2i bm `unsafeShiftL` sh) `unsafeShiftR` (sh + min_)
1292
+ restrictBM t@ (Tip k _) ! bm
1293
+ | IntSet. bitmapOf k .&. bm /= 0 = t
1294
+ | otherwise = Nil
1295
+ restrictBM Nil ! _ = Nil
1296
+
1297
+ w2i :: Word -> Int
1298
+ w2i = fromIntegral
1325
1299
1326
1300
-- | \(O(\min(n, m \log \frac{2^W}{m})), m \leq n\).
1327
1301
-- The intersection with a combining function.
@@ -3194,7 +3168,7 @@ assocs = toAscList
3194
3168
-- > keysSet (fromList [(5,"a"), (3,"b")]) == Data.IntSet.fromList [3,5]
3195
3169
-- > keysSet empty == Data.IntSet.empty
3196
3170
3197
- keysSet :: IntMap a -> IntSet. IntSet
3171
+ keysSet :: IntMap a -> IntSet
3198
3172
keysSet Nil = IntSet. Nil
3199
3173
keysSet (Tip kx _) = IntSet. singleton kx
3200
3174
keysSet (Bin p l r)
@@ -3212,7 +3186,7 @@ keysSet (Bin p l r)
3212
3186
-- > fromSet (\k -> replicate k 'a') (Data.IntSet.fromList [3, 5]) == fromList [(5,"aaaaa"), (3,"aaa")]
3213
3187
-- > fromSet undefined Data.IntSet.empty == empty
3214
3188
3215
- fromSet :: (Key -> a ) -> IntSet. IntSet -> IntMap a
3189
+ fromSet :: (Key -> a ) -> IntSet -> IntMap a
3216
3190
fromSet _ IntSet. Nil = Nil
3217
3191
fromSet f (IntSet. Bin p l r) = Bin p (fromSet f l) (fromSet f r)
3218
3192
fromSet f (IntSet. Tip kx bm) = buildTree f kx bm (IntSet. suffixBitMask + 1 )
0 commit comments