blob: 81f2cb815801b9d44ca25bab6933f5ff3e8158da [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/privacy_budget/encountered_surface_tracker.h"
#include <vector>
#include "base/rand_util.h"
#include "base/time/time.h"
#include "chrome/browser/privacy_budget/identifiability_study_state.h"
#include "third_party/blink/public/common/privacy_budget/identifiable_surface.h"
namespace {
uint64_t hash(uint64_t x) {
// This is should be a reasonable and fast reversible hash.
// Based a bit on https://naml.us/post/inverse-of-a-hash-function/
x = x * 88388617; // calculate as (x<<23)+(x<<3)+x
x = x ^ (x >> 31);
x = x * 257; // calculate as (x<<8)+x
x = x ^ (x >> 13);
x = x * 769; // calculate as (x<<9)+(x<<8)+x
x = x ^ (x >> 23);
x = x * 127; // calculate as (x<<7)-x
return x;
}
} // namespace
const unsigned EncounteredSurfaceTracker::kMaxTrackedSurfaces;
EncounteredSurfaceTracker::EncounteredSurfaceTracker() {
Reset();
}
EncounteredSurfaceTracker::~EncounteredSurfaceTracker() = default;
void EncounteredSurfaceTracker::Reset() {
seed_ = base::RandUint64();
surfaces_.clear();
}
bool EncounteredSurfaceTracker::IsNewEncounter(uint64_t source_id,
uint64_t surface) {
if (blink::IdentifiableSurface::FromMetricHash(surface).GetType() ==
blink::IdentifiableSurface::Type::kReservedInternal)
return false;
HashKey key = hash(surface ^ seed_);
auto it = surfaces_.find(key);
if (it == surfaces_.end()) {
if (surfaces_.size() >= kMaxTrackedSurfaces &&
key <= surfaces_.begin()->first) {
return false;
}
// We need to add an entry for this surface, possibly bumping an entry out.
surfaces_.insert(std::make_pair(key, base::flat_set<uint64_t>{source_id}));
if (surfaces_.size() > kMaxTrackedSurfaces) {
// Remove the smallest
surfaces_.erase(surfaces_.begin());
}
return true;
}
if (it->second.contains(source_id))
return false;
it->second.insert(source_id);
return true;
}