refactor: unify container presence checks #33192

pull l0rinc wants to merge 3 commits into bitcoin:master from l0rinc:l0rinc/count-vs-contains changing 53 files +160 −160
  1. l0rinc commented at 2:29 am on August 15, 2025: contributor

    Summary

    Instead of counting occurrences in sets and maps, the C++20 ::contains method expresses the intent unambiguously and can return early on first encounter.

    Context

    Applied clang‑tidy’s readability‑container‑contains check, though many cases required manual changes since tidy couldn’t fix them automatically.

    Changes

    The changes made here were:

    From To
    m.find(k) == m.end() !m.contains(k)
    m.find(k) != m.end() m.contains(k)
    m.count(k) m.contains(k)
    !m.count(k) !m.contains(k)
    m.count(k) == 0 !m.contains(k)
    m.count(k) != 1 !m.contains(k)
    m.count(k) == 1 m.contains(k)
    m.count(k) < 1 !m.contains(k)
    m.count(k) > 0 m.contains(k)
    m.count(k) != 0 m.contains(k)

    Note that == 1/!= 1/< 1 only apply to simple maps/sets and had to be changed manually.

    There are many other cases that could have been changed, but we’ve reverted most of those to reduce conflict with other open PRs.


    0rm -rfd build && \
    1cmake -B build \
    2  -DCMAKE_C_COMPILER="$(brew --prefix llvm)/bin/clang" \
    3  -DCMAKE_CXX_COMPILER="$(brew --prefix llvm)/bin/clang++" \
    4  -DCMAKE_OSX_SYSROOT="$(xcrun --show-sdk-path)" \
    5  -DCMAKE_C_FLAGS="-target arm64-apple-macos11" \
    6  -DCMAKE_CXX_FLAGS="-target arm64-apple-macos11" \
    7  -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DBUILD_BENCH=ON -DBUILD_FUZZ_BINARY=ON -DBUILD_FOR_FUZZING=ON
    8
    9 "$(brew --prefix llvm)/bin/run-clang-tidy" -quiet -p build -j$(nproc) -checks='-*,readability-container-contains' | grep -v 'clang-tidy'
    

    Note: this is a take 2 of #33094 with fewer contentious changes.

  2. DrahtBot added the label Refactoring on Aug 15, 2025
  3. DrahtBot commented at 2:29 am on August 15, 2025: contributor

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/33192.

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    ACK optout21, Raimo33, janb84, pablomartin4btc
    Concept ACK glozow

    If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #33591 (Cluster mempool followups by sdaftuar)
    • #33540 (argsman, cli: GNU-style command-line option parsing (allows options after non-option arguments) by pablomartin4btc)
    • #31860 (init: Take lock on blocks directory in BlockManager ctor by TheCharlatan)
    • #29641 (scripted-diff: Use LogInfo over LogPrintf [WIP, NOMERGE, DRAFT] by maflcko)
    • #28676 (Cluster mempool implementation by sdaftuar)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

    LLM Linter (✨ experimental)

    Possible typos and grammar issues:

    • enqure -> ensure [spelling error in comment “Serialization uses xpub -> keypath to enqure key uniqueness”]

    drahtbot_id_5_m

  4. janb84 commented at 8:53 am on August 15, 2025: contributor

    ACK f70d2c7faa8f7d724e146e4c409de9c6778b7299

    Hope this PR is now seen as valuable enough, still stand behind my last ACK reasons.

    Q: Am I correct to conclude that the omission of the clang-tidy change is because of the limited scope of this PR? Any idea how we could work to get that rule included e.g. by some Linter ?


    Old but still valid reasons to ACK this PR. This PR refactors the code to use the more modern contains() method. In my opinion this PR increased the readability of the code and removes the ambiguity of the intention of the count() methods used. With this change, the intent to enforce that exactly one item is/ is not present or just a presence check will be more obvious. (count() vs contains()).

    The argument NOT to change the code because of the risk losing the original behaviour is an indication to me that the refactor is needed to remove the ambiguity and more clearly communicate the intent of the code.

    • code review ✅
    • build & tested ✅
  5. optout21 commented at 6:06 am on August 31, 2025: none

    ACK f70d2c7faa8f7d724e146e4c409de9c6778b7299

    Re-reviewed; this is a subset of #33097, comments from there still apply:

    • The changes increase code readability, as ‘contains’ expresses the code logic / intent more specifically
    • It also results in higher performance, due to potential early exit. The improvement is probably negligible though.
    • Changes are localized (each to a single line), local impact only

    (I’ve reviewed the proposed changed, but didn’t look for other potential changes)

  6. Raimo33 commented at 8:36 pm on September 6, 2025: none

    ACK f70d2c7faa8f7d724e146e4c409de9c6778b7299

    This is a no brainer for me. It makes code easier to read and therefore mantain. Also, as already mentioned, for multisets and multimaps, ::contains will avoid extra iterations with early exits. The changes are relatively trivial so very little surface for subtle errors.

  7. pablomartin4btc commented at 6:43 pm on September 21, 2025: member

    ACK f70d2c7faa8f7d724e146e4c409de9c6778b7299

    Even the split into 3 commits was present in previous attempt (https://github.com/bitcoin/bitcoin/pull/33094), I didn’t have the chance to check it there, it helps a lot in reviewing so many files.

  8. glozow commented at 7:51 pm on September 25, 2025: member
    Apologies, this needs rebase for #33230. I decided to merge it first since it’s a functional change and has already gone through a reACK cycle. This one is also very straightforward to rebase.
  9. refactor: unify container presence checks - find
    The changes made here were:
    
    | From                   | To               |
    |------------------------|------------------|
    | `m.find(k) == m.end()` | `!m.contains(k)` |
    | `m.find(k) != m.end()` | `m.contains(k)`  |
    3a73e9e808
  10. refactor: unify container presence checks - trivial counts
    The changes made here were:
    
    | From              | To               |
    |-------------------|------------------|
    | `m.count(k)`      | `m.contains(k)`  |
    | `!m.count(k)`     | `!m.contains(k)` |
    | `m.count(k) == 0` | `!m.contains(k)` |
    | `m.count(k) != 0` | `m.contains(k)`  |
    | `m.count(k) > 0`  | `m.contains(k)`  |
    
    The commit contains the trivial, mechanical refactors where it doesn't matter if the container can have multiple elements or not
    
    Co-authored-by: Jan B <608446+janb84@users.noreply.github.com>
    b25879394e
  11. refactor: unify container presence checks - non-trivial counts
    The changes made here were:
    
    | From              | To               |
    |-------------------|------------------|
    | `m.count(k) == 1` | `m.contains(k)`  |
    | `m.count(k) != 1` | `!m.contains(k)` |
    | `m.count(k) < 1`  | `!m.contains(k)` |
    
    * `mapInfo` is instance of `std::unordered_map` and can only contain 0 or 1 value for a given key;
    * similarly, `g_enabled_filter_types` and `setClientRules` are both `std::set` instances;
    * lastly, while `mapTxSpends` is `std::unordered_multimap` that could potentially hold multiple values, having a size less than 1 means that the value is missing.
    
    `QMap<WalletModel*, WalletView*> mapWalletViews` values were also migrated manually.
    
    Co-authored-by: pablomartin4btc <pablomartin4btc@gmail.com>
    Co-authored-by: fanquake <fanquake@gmail.com>
    d870caca33
  12. l0rinc force-pushed on Sep 25, 2025
  13. l0rinc renamed this:
    refactor: unify container presence checks (without PR conflicts)
    refactor: unify container presence checks
    on Sep 25, 2025
  14. optout21 commented at 10:00 am on September 29, 2025: none
    reACK d870caca33ac9f0fdd76969a7341535c5722417e (prev)
  15. DrahtBot requested review from janb84 on Sep 29, 2025
  16. DrahtBot requested review from pablomartin4btc on Sep 29, 2025
  17. DrahtBot requested review from glozow on Sep 29, 2025
  18. Raimo33 commented at 1:19 pm on September 29, 2025: none
    reACK d870caca33ac9f0fdd76969a7341535c5722417e
  19. janb84 commented at 1:24 pm on September 29, 2025: contributor

    reACK d870caca33ac9f0fdd76969a7341535c5722417e

    changes since last ACK:

    • rebase
  20. pablomartin4btc approved
  21. pablomartin4btc commented at 11:42 pm on October 5, 2025: member

    re-ACK d870caca33ac9f0fdd76969a7341535c5722417e

    In 2nd commit (b25879394ed1d6182d123787e8c03ae38bf884d1) did you miss the counts changes on src/rpc/client.cpp or was it intentional? (Sorry if I missed a reason).

    https://github.com/l0rinc/bitcoin/blob/f70d2c7faa8f7d724e146e4c409de9c6778b7299/src/rpc/client.cpp#L332-L343

  22. l0rinc commented at 11:48 pm on October 5, 2025: contributor
    thanks for the reviews. I have reverted conflicting changes. It’s better to be lightweight and not conflict with other PRs, it’s not critical to be exhaustive with the replaces just that the ones we have are correct.

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2025-10-10 15:13 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me