Skip to content

Optimization idea for submapBitmapIndexed #414

@sjakobi

Description

@sjakobi

-- | \(O(\min n m))\) Checks if a bitmap indexed node is a submap of another.
submapBitmapIndexed :: (HashMap k v1 -> HashMap k v2 -> Bool) -> Bitmap -> A.Array (HashMap k v1) -> Bitmap -> A.Array (HashMap k v2) -> Bool
submapBitmapIndexed comp !b1 !ary1 !b2 !ary2 = subsetBitmaps && go 0 0 (b1Orb2 .&. negate b1Orb2)
where
go :: Int -> Int -> Bitmap -> Bool
go !i !j !m
| m > b1Orb2 = True
-- In case a key is both in ary1 and ary2, check ary1[i] <= ary2[j] and
-- increment the indices i and j.
| b1Andb2 .&. m /= 0 = comp (A.index ary1 i) (A.index ary2 j) &&
go (i+1) (j+1) (m `unsafeShiftL` 1)
-- In case a key occurs in ary1, but not ary2, only increment index j.
| b2 .&. m /= 0 = go i (j+1) (m `unsafeShiftL` 1)
-- In case a key neither occurs in ary1 nor ary2, continue.
| otherwise = go i j (m `unsafeShiftL` 1)
b1Andb2 = b1 .&. b2
b1Orb2 = b1 .|. b2
subsetBitmaps = b1Orb2 == b2
{-# INLINABLE submapBitmapIndexed #-}

Currently the bit mask used to check for subkeys that appear in both maps is incremented by one. It might be more efficient to use countTrailingZeros to check only the bits that actually overlap, similar to the code in unionArraysBy introduced in #395.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions