double GetWeightMultiplierPerSecond(
const std::map<std::string, std::string>& params) {
// Default value of the half life (in seconds) for computing time weighted
// percentiles. Every half life, the weight of all observations reduces by
// half. Lowering the half life would reduce the weight of older values
// faster.
int half_life_seconds = 60;
int32_t variations_value = 0;
auto it = params.find("HalfLifeSeconds");
if (it != params.end() && base::StringToInt(it->second, &variations_value) &&
variations_value >= 1) {
half_life_seconds = variations_value;
}
DCHECK_GT(half_life_seconds, 0);
return pow(0.5, 1.0 / half_life_seconds);
}
void ObservationBuffer::ComputeWeightedObservations(
const base::TimeTicks& begin_timestamp,
int32_t current_signal_strength,
std::vector<WeightedObservation>* weighted_observations,
double* total_weight) const {
base::TimeDelta time_since_sample_taken = now - observation.timestamp();
double time_weight =
pow(weight_multiplier_per_second_, time_since_sample_taken.InSeconds());
…
}
std::optional<int32_t> ObservationBuffer::GetPercentile(
base::TimeTicks begin_timestamp,
int32_t current_signal_strength,
int percentile,
size_t* observations_count) const {
……
// 此处的percentile值为50,即取中值
double desired_weight = percentile / 100.0 * total_weight;
double cumulative_weight_seen_so_far = 0.0;
for (const auto& weighted_observation : weighted_observations) {
cumulative_weight_seen_so_far += weighted_observation.weight;
if (cumulative_weight_seen_so_far >= desired_weight)
return weighted_observation.value;
}
// Computation may reach here due to floating point errors. This may happen
// if |percentile| was 100 (or close to 100), and |desired_weight| was
// slightly larger than |total_weight| (due to floating point errors).
// In this case, we return the highest |value| among all observations.
// This is same as value of the last observation in the sorted vector.
return weighted_observations.at(weighted_observations.size() - 1).value;
}
enum EffectiveConnectionType {
// Effective connection type reported when the network quality is unknown.
EFFECTIVE_CONNECTION_TYPE_UNKNOWN = 0,
// Effective connection type reported when the Internet is unreachable
// because the device does not have a connection (as reported by underlying
// platform APIs). Note that due to rare but potential bugs in the platform
// APIs, it is possible that effective connection type is reported as
// EFFECTIVE_CONNECTION_TYPE_OFFLINE. Callers must use caution when using
// acting on this.
EFFECTIVE_CONNECTION_TYPE_OFFLINE,
// Effective connection type reported when the network has the quality of a
// poor 2G connection.
EFFECTIVE_CONNECTION_TYPE_SLOW_2G,
// Effective connection type reported when the network has the quality of a
// faster 2G connection.
EFFECTIVE_CONNECTION_TYPE_2G,
// Effective connection type reported when the network has the quality of a 3G
// connection.
EFFECTIVE_CONNECTION_TYPE_3G,
// Effective connection type reported when the network has the quality of a 4G
// connection.
EFFECTIVE_CONNECTION_TYPE_4G,
// Last value of the effective connection type. This value is unused.
EFFECTIVE_CONNECTION_TYPE_LAST,
};