Skip to content

insertGlobal hashes inputs twice #8

@Bodigrim

Description

@Bodigrim

insertGlobal calls calculateHash and invokes lookup, which calculateHash again. Hashing could be relatively expensive for large inputs, it would be great to avoid doing it twice.

insertGlobal ba# = do
GlobalSymbolTable gsymtab sipkey <- globalSymbolTable
let !key = calculateHash sipkey ba#
-- SAFETY: If the table IORef contested,
-- this might trigger `weak` creation for the same bytestring from multiple threads
-- at the same time.
-- But finalization is idempotent, and only when a thread finally wins the Compare-and-Swap
-- will its `weak` pointer be inserted (or alternatively another previously-inserted `ba` returned).
-- So once this function returns, we can be sure we've returned a deduplicated ByteArray
!weak <- mkWeakSymbol ba# (removeGlobal key)
IORef.atomicModifyIORef' gsymtab $ \table ->
case lookup ba# sipkey table of
Just ba -> (table, ba)
Nothing ->
(insert key weak table, ByteArray ba#)

lookup ba# sipkey (SymbolTable table) = do
let !key = calculateHash sipkey ba#
weaks <- IntMap.lookup (hashToInt key) table
Foldable.find (\other -> other == ByteArray ba#) (aliveWeaks weaks)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions