refactor: unify container presence checks #33192

pull l0rinc wants to merge 3 commits into bitcoin:master from l0rinc:l0rinc/count-vs-contains changing 63 files +184 −184
  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 sedited, janb84, optout21, pablomartin4btc
    Concept ACK glozow
    Stale ACK Raimo33

    If your review is incorrectly listed, please copy-paste <!–meta-tag:bot-skip–> into the comment that the bot should ignore.

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #bitcoin-core/gui/872 (Menu action to export a watchonly wallet by achow101)
    • #33540 (argsman, cli: GNU-style command-line option parsing (allows options after non-option arguments) by pablomartin4btc)
    • #33034 (wallet: Store transactions in a separate sqlite table by achow101)
    • #33032 (wallet, test: Replace MockableDatabase with in-memory SQLiteDatabase by achow101)
    • #33018 (coins: remove SetFresh method from CCoinsCacheEntry by andrewtoth)
    • #32763 (wallet: Replace CWalletTx::mapValue and vOrderForm with explicit class members by achow101)
    • #32489 (wallet: Add exportwatchonlywallet RPC to export a watchonly version of a wallet by achow101)
    • #31860 (init: Take lock on blocks directory in BlockManager ctor by sedited)
    • #31713 (miniscript refactor: Remove unique_ptr-indirection by hodlinator)
    • #26781 (Release LockData::dd_mutex before calling *_detected functions by hebasto)

    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.

  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: contributor

    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: contributor

    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. l0rinc force-pushed on Sep 25, 2025
  10. l0rinc renamed this:
    refactor: unify container presence checks (without PR conflicts)
    refactor: unify container presence checks
    on Sep 25, 2025
  11. optout21 commented at 10:00 am on September 29, 2025: contributor
    reACK d870caca33ac9f0fdd76969a7341535c5722417e (prev)
  12. DrahtBot requested review from janb84 on Sep 29, 2025
  13. DrahtBot requested review from pablomartin4btc on Sep 29, 2025
  14. DrahtBot requested review from glozow on Sep 29, 2025
  15. Raimo33 commented at 1:19 pm on September 29, 2025: contributor
    reACK d870caca33ac9f0fdd76969a7341535c5722417e
  16. janb84 commented at 1:24 pm on September 29, 2025: contributor

    reACK d870caca33ac9f0fdd76969a7341535c5722417e

    changes since last ACK:

    • rebase
  17. pablomartin4btc approved
  18. 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

  19. 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.
  20. l0rinc commented at 3:10 pm on October 23, 2025: contributor
    rfm
  21. maflcko commented at 3:16 pm on October 23, 2025: member
    I like the changes, but I am not sure how hard it will be to rebase the conflicts. Maybe this can wait until they are merged, and then this one can go after?
  22. l0rinc commented at 3:17 pm on October 23, 2025: contributor
    thanks, would it help if I reverted the conflicting line again?
  23. achow101 commented at 5:21 pm on October 24, 2025: member

    rfm

    I don’t think so. This PR lacks (conceptual) review from senior contributors. It’s also mostly a stylistic change which we generally do not care about doing. This also conflicts with cluster mempool which is a project that I think we want to be avoiding conflicts with in general at this point.

  24. glozow commented at 3:54 pm on October 28, 2025: member
    As mentioned previously, I don’t think we should make people rebase for this change, particularly if it’s just for style. Maybe reduce the conflicts or close the PR?
  25. DrahtBot added the label Needs rebase on Oct 28, 2025
  26. l0rinc force-pushed on Oct 28, 2025
  27. l0rinc force-pushed on Oct 28, 2025
  28. l0rinc commented at 10:05 pm on October 28, 2025: contributor

    Thanks for the feedback, I have reverted the mining and mempool related coflicting changes and rebased in a separate commit to simplify review.

    I agree that these refactors shouldn’t conflict with other important changes, it’s why I have reopened this in the first place.

  29. DrahtBot removed the label Needs rebase on Oct 28, 2025
  30. maflcko commented at 7:05 am on October 30, 2025: member

    I don’t think you did. The conflicts are still there and the DrahtBot summary is correct. You can also try it locally:

     0# git checkout b97db6f06185a1d63828f958b33a7e6780aee73c && git merge 1ae9fd3f7a4fddc786e9921e7fc2af41ab96bf9a 
     1HEAD is now at b97db6f061 refactor: unify container presence checks - non-trivial counts
     2Auto-merging src/init.cpp
     3Auto-merging src/net_processing.cpp
     4Auto-merging src/node/interfaces.cpp
     5Auto-merging src/node/miner.cpp
     6Auto-merging src/rpc/mempool.cpp
     7Auto-merging src/test/fuzz/mini_miner.cpp
     8CONFLICT (content): Merge conflict in src/test/fuzz/mini_miner.cpp
     9Auto-merging src/test/fuzz/policy_estimator.cpp
    10Auto-merging src/test/fuzz/rpc.cpp
    11Auto-merging src/test/miner_tests.cpp
    12Auto-merging src/test/miniminer_tests.cpp
    13Auto-merging src/test/util/setup_common.cpp
    14Auto-merging src/test/util/txmempool.cpp
    15Auto-merging src/test/util/txmempool.h
    16Auto-merging src/txmempool.cpp
    17CONFLICT (content): Merge conflict in src/txmempool.cpp
    18Auto-merging src/txmempool.h
    19Auto-merging src/validation.cpp
    20Auto-merging test/functional/test_runner.py
    21Automatic merge failed; fix conflicts and then commit the result.
    
  31. l0rinc force-pushed on Oct 30, 2025
  32. l0rinc commented at 8:16 am on October 30, 2025: contributor
    Thanks, looks like a missed a few manual undos. Reverted the 3 remaining files that seem related to the cluster mempool work and verified that it merges cleanly with #33629 and https://github.com/bitcoin/bitcoin/pull/33591
  33. l0rinc commented at 4:10 pm on October 31, 2025: contributor
    DrahtBot conflict list was updated, no more cluster memool conflict, ready for review again!
  34. janb84 commented at 8:05 pm on October 31, 2025: contributor

    re ACK 21cff12b0e6dc58fb8c66543bbd713796d9941ae

    I still think this a good idea, it may be a “style change” but the increased clarity will decrease bugs and mental load when reading the code.

    changes since last ack:

    • reduced code changes to not hit cluster mempool.
  35. DrahtBot requested review from pablomartin4btc on Oct 31, 2025
  36. DrahtBot requested review from optout21 on Oct 31, 2025
  37. optout21 commented at 5:21 am on November 1, 2025: contributor

    reACK d9319b06cf82664d55f255387a348135fd7f91c7

    (was reACK 21cff12b0e6dc58fb8c66543bbd713796d9941ae)

  38. DrahtBot added the label Needs rebase on Dec 2, 2025
  39. l0rinc force-pushed on Dec 3, 2025
  40. l0rinc force-pushed on Dec 3, 2025
  41. 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)`  |
    8bb9219b63
  42. l0rinc force-pushed on Dec 3, 2025
  43. DrahtBot added the label CI failed on Dec 3, 2025
  44. l0rinc commented at 12:34 pm on December 3, 2025: contributor

    Now that #33629 and #33591 and #33960 were merged, I have rebased (in a separate push) and reconverted the remaining count and find instances to contains - see the new additions: https://github.com/bitcoin/bitcoin/compare/d8c25aa8f726d26e1bf042342fda160f73811699..d9319b06cf82664d55f255387a348135fd7f91c7

    Thanks for the reviewers so far, re-reviews would be appreciated.

  45. 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>
    039307554e
  46. 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) == 0` | `!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>
    d9319b06cf
  47. l0rinc force-pushed on Dec 3, 2025
  48. DrahtBot removed the label Needs rebase on Dec 3, 2025
  49. DrahtBot removed the label CI failed on Dec 3, 2025
  50. sedited approved
  51. sedited commented at 8:46 pm on December 3, 2025: contributor
    ACK d9319b06cf82664d55f255387a348135fd7f91c7
  52. DrahtBot requested review from janb84 on Dec 3, 2025
  53. janb84 commented at 10:39 am on December 4, 2025: contributor

    re ACK d9319b06cf82664d55f255387a348135fd7f91c7

    0bool PeerManagerImpl::IsBlockRequested(const uint256& hash)
    1{
    2    return mapBlocksInFlight.count(hash);
    3 }
    

    “Ah returns a count => int , oh no it’s bool”

    VS

    0bool PeerManagerImpl::IsBlockRequested(const uint256& hash)
    1{
    2    return mapBlocksInFlight.contains(hash);
    3}
    

    “ah does it contain X => yes/no "

    Clearly the intent is better conveyed. I’m still a big proponent of this change.

  54. pablomartin4btc commented at 9:23 pm on December 11, 2025: member

    re-ACK d9319b06cf82664d55f255387a348135fd7f91c7

    Checked the diffs since my last review.


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-12-13 18:12 UTC

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