For algorithms like BoundedSum, the library assumes maxContributionsPerPartitions is 1. If a single privacy unit (e.g., a visitor) can contribute multiple times to the same partition (e.g., multiple visits in one day), you should pre-aggregate those values manually before calling addEntry().
This prevents the library from overestimating sensitivity and adding unnecessary noise. When pre-aggregating, ensure you adjust the upper bound of your BoundedSum to reflect the maximum possible cumulative amount a user can contribute to a single partition.
// For each visitor, pre-aggregate their spending for the day.
Map<String, Integer> visitorToDaySpending = new HashMap<>();
for (Visit v : boundedVisits.getVisitsForDay(d)) {
String visitorId = v.visitorId();
if (visitorToDaySpending.containsKey(visitorId)) {
int newAmount = visitorToDaySpending.get(visitorId) + v.eurosSpent();
visitorToDaySpending.put(visitorId, newAmount);
} else {
visitorToDaySpending.put(visitorId, v.eurosSpent());
}
}
// Then use the aggregated values in BoundedSum with an appropriate upper bound
private static final int MAX_EUROS_SPENT = 65; // Adjusted for cumulative spending
...
BoundedSum dpSum =
BoundedSum.builder()
.epsilon(LN_3)
.maxPartitionsContributed(MAX_CONTRIBUTED_DAYS)
.lower(MIN_EUROS_SPENT)
.upper(MAX_EUROS_SPENT)
.build();