Cheapest Cache TTL Meeting a Freshness SLA
Problem Statement
Choose the largest cache TTL (to save the most cost) such that the fraction of served responses that are stale stays within a freshness SLA, given a trace of requests and underlying-data change times.
Background
A cached entry created at time t is valid until t + ttl. For a request stream (sorted times), the cache serves a key from cache if a valid entry exists (created within ttl of now and after the last data change for that key); otherwise it recomputes and creates a fresh entry. A served-from-cache response is stale if the underlying data changed after the cached entry was created. We are given, per request, whether serving it from a cache of a given ttl would be stale — abstracted as: for candidate ttl values, a function tells us the stale fraction. Concretely: given candidates (sorted ascending ttl values) and a parallel list stale_fraction (the resulting stale fraction at each ttl, non-decreasing in ttl), return the largest ttl whose stale fraction <= sla. If even the smallest exceeds sla, return -1.
Your Task
def best_ttl(candidates, stale_fraction, sla):
- candidates: ascending ttl values; stale_fraction[i] corresponds to candidates[i] and is non-decreasing.
- Return the largest qualifying ttl, or -1.
Input Format
- candidates (list of ints, ascending), stale_fraction (list of floats, non-decreasing), sla (float).
Output Format
- An int (a ttl) or -1.
Sample
print(best_ttl([10, 60, 300], [0.0, 0.02, 0.2], 0.05))
Output:
60
Example
print(best_ttl([10, 60, 300], [0.0, 0.02, 0.2], 0.05))
60
- We identify the valid range of TTLs by checking which candidates have a stale fraction . The fractions are , so indices 0 and 1 qualify, while index 2 () does not.
- To find the largest valid TTL efficiently, we perform a binary search on the sorted
candidateslist , aiming to find the rightmost index where the condition holds. - In the first step, we check the middle element at index 1: the stale fraction is , which is . Since this is valid, we record
60as a potential answer and search the right half for a larger valid TTL. - In the next step, we check the new middle element at index 2: the stale fraction is , which is . This is invalid, so we discard this right half and stop searching further right.
- The search concludes with the last recorded valid candidate, which is the largest TTL meeting the SLA.
- The final output is 60
Constraints
stale_fractionis non-decreasing in ttl, so qualifying ttls form a prefix.- Return the largest ttl with
stale_fraction <= sla(binary search the prefix). - Return
-1if none qualify.