|
2 | 2 | {-# LANGUAGE ScopedTypeVariables #-}
|
3 | 3 | {-# LANGUAGE PatternGuards #-}
|
4 | 4 | {-# LANGUAGE RoleAnnotations #-}
|
| 5 | +{-# LANGUAGE TupleSections #-} |
5 | 6 | {-# LANGUAGE TypeFamilies #-}
|
6 | 7 | {-# OPTIONS_GHC -fno-full-laziness -funbox-strict-fields #-}
|
7 | 8 |
|
@@ -889,6 +890,62 @@ delete k0 m0 = go h0 k0 0 m0
|
889 | 890 | | otherwise = t
|
890 | 891 | {-# INLINABLE delete #-}
|
891 | 892 |
|
| 893 | +-- | /O(log n)/ Remove the mapping for the specified key from this map |
| 894 | +-- if present. Returns a tuple with the hashmap's change in size and the |
| 895 | +-- hashmap after the deletion. |
| 896 | +deleteInternal :: (Eq k, Hashable k) => k -> HashMap k v -> (Int, HashMap k v) |
| 897 | +deleteInternal k0 m0 = go h0 k0 0 m0 |
| 898 | + where |
| 899 | + h0 = hash k0 |
| 900 | + go !_ !_ !_ Empty = (0, Empty) |
| 901 | + go h k _ t@(Leaf hy (L ky _)) |
| 902 | + | hy == h && ky == k = (-1, Empty) |
| 903 | + | otherwise = (0, t) |
| 904 | + go h k s t@(BitmapIndexed b ary) |
| 905 | + | b .&. m == 0 = (0, t) |
| 906 | + | otherwise = |
| 907 | + let !st = A.index ary i |
| 908 | + (!sz, !st') = go h k (s+bitsPerSubkey) st |
| 909 | + in (sz,) (if st' `ptrEq` st |
| 910 | + then t |
| 911 | + else case st' of |
| 912 | + Empty | A.length ary == 1 -> Empty |
| 913 | + | A.length ary == 2 -> |
| 914 | + case (i, A.index ary 0, A.index ary 1) of |
| 915 | + (0, _, l) | isLeafOrCollision l -> l |
| 916 | + (1, l, _) | isLeafOrCollision l -> l |
| 917 | + _ -> bIndexed |
| 918 | + | otherwise -> bIndexed |
| 919 | + where |
| 920 | + bIndexed = BitmapIndexed (b .&. complement m) (A.delete ary i) |
| 921 | + l | isLeafOrCollision l && A.length ary == 1 -> l |
| 922 | + _ -> BitmapIndexed b (A.update ary i st')) |
| 923 | + where m = mask h s |
| 924 | + i = sparseIndex b m |
| 925 | + go h k s t@(Full ary) = |
| 926 | + let !st = A.index ary i |
| 927 | + (!sz, !st') = go h k (s+bitsPerSubkey) st |
| 928 | + in (sz,) (if st' `ptrEq` st |
| 929 | + then t |
| 930 | + else case st' of |
| 931 | + Empty -> |
| 932 | + let ary' = A.delete ary i |
| 933 | + bm = fullNodeMask .&. complement (1 `unsafeShiftL` i) |
| 934 | + in BitmapIndexed bm ary' |
| 935 | + _ -> Full (A.update ary i st')) |
| 936 | + where i = index h s |
| 937 | + go h k _ t@(Collision hy v) |
| 938 | + | h == hy = case indexOf k v of |
| 939 | + Just i |
| 940 | + | A.length v == 2 -> |
| 941 | + (-1,) (if i == 0 |
| 942 | + then Leaf h (A.index v 1) |
| 943 | + else Leaf h (A.index v 0)) |
| 944 | + | otherwise -> (-1, Collision h (A.delete v i)) |
| 945 | + Nothing -> (0, t) |
| 946 | + | otherwise = (0, t) |
| 947 | +{-# INLINABLE deleteInternal #-} |
| 948 | + |
892 | 949 | -- | /O(log n)/ Adjust the value tied to a given key in this map only
|
893 | 950 | -- if it is present. Otherwise, leave the map alone.
|
894 | 951 | adjust :: (Eq k, Hashable k) => (v -> v) -> k -> HashMap k v -> HashMap k v
|
|
0 commit comments