blob: 50e708eda07ac123a1cfdaafaf7e7adee74eb810 [file] [log] [blame]
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/preloading/prefetch/prefetch_servable_state.h"
#include "base/check_op.h"
#include "base/notreached.h"
#include "content/browser/preloading/prefetch/prefetch_container.h"
#include "content/browser/preloading/prefetch/prefetch_match_resolver.h"
namespace content {
CONTENT_EXPORT std::ostream& operator<<(std::ostream& ostream,
PrefetchServableState servable_state) {
switch (servable_state) {
case PrefetchServableState::kNotServable:
return ostream << "NotServable";
case PrefetchServableState::kServable:
return ostream << "Servable";
case PrefetchServableState::kShouldBlockUntilHeadReceived:
return ostream << "ShouldBlockUntilHeadReceived";
case PrefetchServableState::kShouldBlockUntilEligibilityGot:
return ostream << "ShouldBlockUntilEligibilityGot";
}
}
PrefetchMatchResolverAction::PrefetchMatchResolverAction(
ActionKind kind,
PrefetchContainer::LoadState prefetch_container_load_state,
std::optional<bool> is_expired)
: kind_(kind),
prefetch_container_load_state_(prefetch_container_load_state),
is_expired_(is_expired) {
CHECK_EQ(is_expired.has_value(), kind == ActionKind::kMaybeServe);
}
PrefetchMatchResolverAction::~PrefetchMatchResolverAction() = default;
PrefetchServableState PrefetchMatchResolverAction::ToServableState() const {
switch (kind_) {
case ActionKind::kDrop:
return PrefetchServableState::kNotServable;
case ActionKind::kWait:
switch (prefetch_container_load_state_) {
case PrefetchContainer::LoadState::kNotStarted:
case PrefetchContainer::LoadState::kEligible:
return PrefetchServableState::kShouldBlockUntilEligibilityGot;
case PrefetchContainer::LoadState::kStarted:
return PrefetchServableState::kShouldBlockUntilHeadReceived;
case PrefetchContainer::LoadState::kDeterminedHead:
case PrefetchContainer::LoadState::kCompleted:
case PrefetchContainer::LoadState::kFailedHeldback:
case PrefetchContainer::LoadState::kFailedIneligible:
case PrefetchContainer::LoadState::kFailedDeterminedHead:
case PrefetchContainer::LoadState::kFailed:
NOTREACHED();
}
case ActionKind::kMaybeServe:
if (is_expired_.value()) {
return PrefetchServableState::kNotServable;
} else {
return PrefetchServableState::kServable;
}
}
}
int GetCodeOfPrefetchServableStateAndPrefetchMatchResolverActionForDebug(
PrefetchServableState servable_state,
const PrefetchMatchResolverAction& match_resolver_action) {
// The integers below are only for tentative metrics, and are introduced to
// decouple the metrics values from the underlying enum values.
int servable_state_int;
switch (servable_state) {
case PrefetchServableState::kShouldBlockUntilEligibilityGot:
servable_state_int = 1;
break;
case PrefetchServableState::kShouldBlockUntilHeadReceived:
servable_state_int = 2;
break;
case PrefetchServableState::kServable:
servable_state_int = 3;
break;
case PrefetchServableState::kNotServable:
servable_state_int = 4;
break;
}
int action_kind_int;
switch (match_resolver_action.kind()) {
case PrefetchMatchResolverAction::ActionKind::kDrop:
action_kind_int = 1;
break;
case PrefetchMatchResolverAction::ActionKind::kWait:
action_kind_int = 2;
break;
case PrefetchMatchResolverAction::ActionKind::kMaybeServe:
action_kind_int = 3;
break;
}
int action_prefetch_container_load_state_int;
switch (match_resolver_action.prefetch_container_load_state()) {
case PrefetchContainer::LoadState::kNotStarted:
action_prefetch_container_load_state_int = 1;
break;
case PrefetchContainer::LoadState::kEligible:
action_prefetch_container_load_state_int = 2;
break;
case PrefetchContainer::LoadState::kStarted:
action_prefetch_container_load_state_int = 3;
break;
case PrefetchContainer::LoadState::kDeterminedHead:
action_prefetch_container_load_state_int = 4;
break;
case PrefetchContainer::LoadState::kCompleted:
action_prefetch_container_load_state_int = 5;
break;
case PrefetchContainer::LoadState::kFailedHeldback:
action_prefetch_container_load_state_int = 6;
break;
case PrefetchContainer::LoadState::kFailedIneligible:
action_prefetch_container_load_state_int = 7;
break;
case PrefetchContainer::LoadState::kFailedDeterminedHead:
action_prefetch_container_load_state_int = 8;
break;
case PrefetchContainer::LoadState::kFailed:
action_prefetch_container_load_state_int = 9;
break;
}
int action_is_expired;
if (!match_resolver_action.is_expired().has_value()) {
action_is_expired = 1;
} else if (!match_resolver_action.is_expired().value()) {
action_is_expired = 2;
} else {
action_is_expired = 3;
}
return servable_state_int * 1000 + action_kind_int * 100 +
action_prefetch_container_load_state_int * 10 + action_is_expired;
}
int GetCodeOfPotentialCandidateCollectResultAndServableStateAndMatcherAction(
PrefetchPotentialCandidateCollectResult collect_result,
PrefetchServableState servable_state,
const PrefetchMatchResolverAction& match_resolver_action) {
return static_cast<int>(collect_result) * 10000 +
GetCodeOfPrefetchServableStateAndPrefetchMatchResolverActionForDebug(
servable_state, match_resolver_action);
}
int GetCodeOfPotentialCandidateServingResultAndServableStateAndMatcherAction(
PrefetchPotentialCandidateServingResult serving_result,
PrefetchServableState servable_state,
const PrefetchMatchResolverAction& match_resolver_action) {
return static_cast<int>(serving_result) * 10000 +
GetCodeOfPrefetchServableStateAndPrefetchMatchResolverActionForDebug(
servable_state, match_resolver_action);
}
} // namespace content