Skip to content

Commit d001d13

Browse files
committed
Make deleteSubTree properly self-recursive
1 parent 4e734aa commit d001d13

File tree

1 file changed

+44
-46
lines changed

1 file changed

+44
-46
lines changed

Data/HashMap/Internal.hs

Lines changed: 44 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,55 +1109,53 @@ delete' h0 k0 m0 = deleteSubTree h0 k0 0 m0
11091109
-- | This version of 'delete' can be used on subtrees when a the
11101110
-- corresponding 'Shift' argument is supplied.
11111111
deleteSubTree :: Eq k => Hash -> k -> Shift -> HashMap k v -> HashMap k v
1112-
deleteSubTree = go
1113-
where
1114-
go !_ !_ !_ Empty = Empty
1115-
go h k _ t@(Leaf hy (L ky _))
1116-
| hy == h && ky == k = Empty
1117-
| otherwise = t
1118-
go h k s t@(BitmapIndexed b ary)
1119-
| b .&. m == 0 = t
1120-
| otherwise =
1121-
let !st = A.index ary i
1122-
!st' = go h k (nextShift s) st
1123-
in if st' `ptrEq` st
1124-
then t
1125-
else case st' of
1126-
Empty | A.length ary == 1 -> Empty
1127-
| A.length ary == 2 ->
1128-
case (i, A.index ary 0, A.index ary 1) of
1129-
(0, _, l) | isLeafOrCollision l -> l
1130-
(1, l, _) | isLeafOrCollision l -> l
1131-
_ -> bIndexed
1132-
| otherwise -> bIndexed
1133-
where
1134-
bIndexed = BitmapIndexed (b .&. complement m) (A.delete ary i)
1135-
l | isLeafOrCollision l && A.length ary == 1 -> l
1136-
_ -> BitmapIndexed b (A.update ary i st')
1137-
where m = mask h s
1138-
i = sparseIndex b m
1139-
go h k s t@(Full ary) =
1140-
let !st = A.index ary i
1141-
!st' = go h k (nextShift s) st
1112+
deleteSubTree !_ !_ !_ Empty = Empty
1113+
deleteSubTree h k _ t@(Leaf hy (L ky _))
1114+
| hy == h && ky == k = Empty
1115+
| otherwise = t
1116+
deleteSubTree h k s t@(BitmapIndexed b ary)
1117+
| b .&. m == 0 = t
1118+
| otherwise =
1119+
let !st = A.index ary i
1120+
!st' = deleteSubTree h k (nextShift s) st
11421121
in if st' `ptrEq` st
11431122
then t
11441123
else case st' of
1145-
Empty ->
1146-
let ary' = A.delete ary i
1147-
bm = fullBitmap .&. complement (1 `unsafeShiftL` i)
1148-
in BitmapIndexed bm ary'
1149-
_ -> Full (updateFullArray ary i st')
1150-
where i = index h s
1151-
go h k _ t@(Collision hy v)
1152-
| h == hy = case indexOf k v of
1153-
Just i
1154-
| A.length v == 2 ->
1155-
if i == 0
1156-
then Leaf h (A.index v 1)
1157-
else Leaf h (A.index v 0)
1158-
| otherwise -> Collision h (A.delete v i)
1159-
Nothing -> t
1160-
| otherwise = t
1124+
Empty | A.length ary == 1 -> Empty
1125+
| A.length ary == 2 ->
1126+
case (i, A.index ary 0, A.index ary 1) of
1127+
(0, _, l) | isLeafOrCollision l -> l
1128+
(1, l, _) | isLeafOrCollision l -> l
1129+
_ -> bIndexed
1130+
| otherwise -> bIndexed
1131+
where
1132+
bIndexed = BitmapIndexed (b .&. complement m) (A.delete ary i)
1133+
l | isLeafOrCollision l && A.length ary == 1 -> l
1134+
_ -> BitmapIndexed b (A.update ary i st')
1135+
where m = mask h s
1136+
i = sparseIndex b m
1137+
deleteSubTree h k s t@(Full ary) =
1138+
let !st = A.index ary i
1139+
!st' = deleteSubTree h k (nextShift s) st
1140+
in if st' `ptrEq` st
1141+
then t
1142+
else case st' of
1143+
Empty ->
1144+
let ary' = A.delete ary i
1145+
bm = fullBitmap .&. complement (1 `unsafeShiftL` i)
1146+
in BitmapIndexed bm ary'
1147+
_ -> Full (updateFullArray ary i st')
1148+
where i = index h s
1149+
deleteSubTree h k _ t@(Collision hy v)
1150+
| h == hy = case indexOf k v of
1151+
Just i
1152+
| A.length v == 2 ->
1153+
if i == 0
1154+
then Leaf h (A.index v 1)
1155+
else Leaf h (A.index v 0)
1156+
| otherwise -> Collision h (A.delete v i)
1157+
Nothing -> t
1158+
| otherwise = t
11611159
{-# INLINABLE deleteSubTree #-}
11621160

11631161
-- | Delete optimized for the case when we know the key is in the map.

0 commit comments

Comments
 (0)