FraudBlocklistPreCheck.java
package com.datastructures.hashing.bloomfilter.applied;
import com.datastructures.hashing.bloomfilter.classic.BloomFilter;
/**
* A fraud/account-blocklist pre-check: wraps a {@link BloomFilter} of known
* fraudulent CPFs/account IDs so a caller can skip a real database/service round trip for the
* common case of a clean ID, without ever risking a wrongly-skipped check on a genuinely blocked
* one.
*
* <p><b>The asymmetry this class exists to make safe:</b> {@link #mightBeBlocked} can only ever
* answer in one of two ways. {@code false} is a guaranteed-correct "definitely not on the
* blocklist" — a Bloom filter never false-negatives, so the caller can skip the real check
* entirely and save the round trip. {@code true} means "possibly on the blocklist" — it could be
* a false positive, so the caller MUST still confirm against the real source of truth (the
* fraud/blocklist service or database) before acting on it, e.g. before actually declining a
* transaction. This class only ever saves work on the negative path; it is never itself the
* authority on whether an ID is blocked.
*/
public final class FraudBlocklistPreCheck {
private final BloomFilter<String> blockedIds;
public FraudBlocklistPreCheck(int expectedBlockedIds, double falsePositiveRate) {
this.blockedIds = new BloomFilter<>(expectedBlockedIds, falsePositiveRate);
}
/** Registers {@code id} as known-fraudulent in the pre-check filter. */
public void block(String id) {
blockedIds.add(id);
}
/**
* {@code false}: {@code id} is definitely not on the blocklist — safe to skip the real
* DB/service round trip entirely. {@code true}: {@code id} might be on the blocklist (this
* could be a false positive) — the caller must still confirm against the real source of
* truth before treating it as actually blocked.
*/
public boolean mightBeBlocked(String id) {
return blockedIds.mightContain(id);
}
}