broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    T=x['total']
    k=x['workers']
    if k<=0 or T<0: return None
    base,extra=divmod(T,k)
    w=[]
    start=0
    for i in range(k):
        size=base+(1 if i<extra else 0)
        if size>0: w.append([start,start+size-1])
        start+=size
    for ev in x['events']:
        if ev[0]=='data':
            i,n=ev[1],ev[2]
            if not 0<=i<len(w) or n<0 or w[i][0]+n>w[i][1]+1: return None
            w[i][0]+=n
        elif ev[0]=='steal':
            i=ev[1]
            if not 0<=i<len(w) or w[i][0]<=w[i][1]: continue
            j=None
            for t in range(len(w)):
                if j is None or w[t][1]-w[t][0]>w[j][1]-w[j][0]: j=t
            rem=w[j][1]-w[j][0]+1
            if rem<2: continue
            cut=w[j][0]+(rem+1)//2
            w[i]=[cut,w[j][1]]
            w[j][1]=cut-1
    return ['bytes=%d-%d'%(c,e) for c,e in w]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('pending-header-filter fixture 0', json.loads(json.dumps(solve({'events':[],'total':11,'workers':3}))), json.loads(json.dumps(['bytes=0-3','bytes=4-7','bytes=8-10'])))
check('pending-header-filter fixture 1', json.loads(json.dumps(solve({'events':[],'total':2,'workers':4}))), json.loads(json.dumps(['bytes=0-0','bytes=1-1'])))
check('pending-header-filter fixture 2', json.loads(json.dumps(solve({'events':[],'total':0,'workers':2}))), json.loads(json.dumps([])))
check('pending-header-filter fixture 3', json.loads(json.dumps(solve({'events':[],'total':5,'workers':0}))), json.loads(json.dumps(None)))
check('pending-header-filter fixture 4', json.loads(json.dumps(solve({'events':[['data',0,5],['data',1,6]],'total':10,'workers':2}))), json.loads(json.dumps(None)))
check('pending-header-filter fixture 5', json.loads(json.dumps(solve({'events':[['data',0,5],['data',1,3]],'total':10,'workers':2}))), json.loads(json.dumps(['bytes=8-9'])))
check('pending-header-filter fixture 6', json.loads(json.dumps(solve({'events':[['data',-1,2]],'total':10,'workers':2}))), json.loads(json.dumps(None)))
check('pending-header-filter fixture 7', json.loads(json.dumps(solve({'events':[['data',0,5],['steal',0]],'total':10,'workers':2}))), json.loads(json.dumps(['bytes=8-9','bytes=5-7'])))
check('pending-header-filter fixture 8', json.loads(json.dumps(solve({'events':[['steal',0]],'total':10,'workers':2}))), json.loads(json.dumps(['bytes=0-4','bytes=5-9'])))
check('pending-header-filter fixture 9', json.loads(json.dumps(solve({'events':[['data',0,4],['steal',0]],'total':10,'workers':2}))), json.loads(json.dumps(['bytes=4-4','bytes=5-9'])))
check('pending-header-filter fixture 10', json.loads(json.dumps(solve({'events':[['data',0,4],['data',2,1],['steal',0]],'total':12,'workers':3}))), json.loads(json.dumps(['bytes=6-7','bytes=4-5','bytes=9-11'])))
check('pending-header-filter fixture 11', json.loads(json.dumps(solve({'events':[['data',2,4],['steal',2]],'total':12,'workers':3}))), json.loads(json.dumps(['bytes=0-1','bytes=4-7','bytes=2-3'])))
check('pending-header-filter fixture 12', json.loads(json.dumps(solve({'events':[['data',0,2],['data',1,1],['steal',0]],'total':4,'workers':2}))), json.loads(json.dumps(['bytes=3-3'])))
check('pending-header-filter fixture 13', json.loads(json.dumps(solve({'events':[['data',0,-1]],'total':10,'workers':2}))), json.loads(json.dumps(None)))
check('pending-header-filter fixture 14', json.loads(json.dumps(solve({'events':[],'total':4*N,'workers':2}))), json.loads(json.dumps(["bytes=0-%d"%(2*N-1),"bytes=%d-%d"%(2*N,4*N-1)])))
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    T=x['total']
    k=x['workers']
    if k<=0 or T<0: return None
    base,extra=divmod(T,k)
    w=[]
    start=0
    for i in range(k):
        size=base+(1 if i<extra else 0)
        if size>0: w.append([start,start+size-1])
        start+=size
    for ev in x['events']:
        if ev[0]=='data':
            i,n=ev[1],ev[2]
            if not 0<=i<len(w) or n<0 or w[i][0]+n>w[i][1]+1: return None
            w[i][0]+=n
        elif ev[0]=='steal':
            i=ev[1]
            if not 0<=i<len(w) or w[i][0]<=w[i][1]: continue
            j=None
            for t in range(len(w)):
                if j is None or w[t][1]-w[t][0]>w[j][1]-w[j][0]: j=t
            rem=w[j][1]-w[j][0]+1
            if rem<2: continue
            cut=w[j][0]+(rem+1)//2
            w[i]=[cut,w[j][1]]
            w[j][1]=cut-1
    return ['bytes=%d-%d'%(c,e) for c,e in w if c<e]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('pending-header-filter fixture 0', json.loads(json.dumps(solve({'events':[],'total':11,'workers':3}))), json.loads(json.dumps(['bytes=0-3','bytes=4-7','bytes=8-10'])))
check('pending-header-filter fixture 1', json.loads(json.dumps(solve({'events':[],'total':2,'workers':4}))), json.loads(json.dumps(['bytes=0-0','bytes=1-1'])))
check('pending-header-filter fixture 2', json.loads(json.dumps(solve({'events':[],'total':0,'workers':2}))), json.loads(json.dumps([])))
check('pending-header-filter fixture 3', json.loads(json.dumps(solve({'events':[],'total':5,'workers':0}))), json.loads(json.dumps(None)))
check('pending-header-filter fixture 4', json.loads(json.dumps(solve({'events':[['data',0,5],['data',1,6]],'total':10,'workers':2}))), json.loads(json.dumps(None)))
check('pending-header-filter fixture 5', json.loads(json.dumps(solve({'events':[['data',0,5],['data',1,3]],'total':10,'workers':2}))), json.loads(json.dumps(['bytes=8-9'])))
check('pending-header-filter fixture 6', json.loads(json.dumps(solve({'events':[['data',-1,2]],'total':10,'workers':2}))), json.loads(json.dumps(None)))
check('pending-header-filter fixture 7', json.loads(json.dumps(solve({'events':[['data',0,5],['steal',0]],'total':10,'workers':2}))), json.loads(json.dumps(['bytes=8-9','bytes=5-7'])))
check('pending-header-filter fixture 8', json.loads(json.dumps(solve({'events':[['steal',0]],'total':10,'workers':2}))), json.loads(json.dumps(['bytes=0-4','bytes=5-9'])))
check('pending-header-filter fixture 9', json.loads(json.dumps(solve({'events':[['data',0,4],['steal',0]],'total':10,'workers':2}))), json.loads(json.dumps(['bytes=4-4','bytes=5-9'])))
check('pending-header-filter fixture 10', json.loads(json.dumps(solve({'events':[['data',0,4],['data',2,1],['steal',0]],'total':12,'workers':3}))), json.loads(json.dumps(['bytes=6-7','bytes=4-5','bytes=9-11'])))
check('pending-header-filter fixture 11', json.loads(json.dumps(solve({'events':[['data',2,4],['steal',2]],'total':12,'workers':3}))), json.loads(json.dumps(['bytes=0-1','bytes=4-7','bytes=2-3'])))
check('pending-header-filter fixture 12', json.loads(json.dumps(solve({'events':[['data',0,2],['data',1,1],['steal',0]],'total':4,'workers':2}))), json.loads(json.dumps(['bytes=3-3'])))
check('pending-header-filter fixture 13', json.loads(json.dumps(solve({'events':[['data',0,-1]],'total':10,'workers':2}))), json.loads(json.dumps(None)))
check('pending-header-filter fixture 14', json.loads(json.dumps(solve({'events':[],'total':4*N,'workers':2}))), json.loads(json.dumps(["bytes=0-%d"%(2*N-1),"bytes=%d-%d"%(2*N,4*N-1)])))
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
A parallel downloader splits a representation into worker ranges and rebalances idle workers: finished workers do not emit inverted Range headers.

x has total length, worker count and events. Initial segments follow array-split sizing: base=total//workers, the first total%workers workers get one extra byte; zero-size segments are dropped and later worker indices refer to the surviving list. Each segment is [cursor,end]. data(i,n) advances worker i by n>=0 accepted bytes; an invalid or negative index, negative n or overrun past its end returns null. steal(i) is ignored unless i is a valid finished worker; the victim is the worker with the most remaining bytes (lowest index on ties); a victim with fewer than2 remaining bytes is left alone; otherwise the victim keeps the first ceil(rem/2) bytes and the thief takes the rest. Return Range header values for unfinished workers in worker order. workers<=0 or negative total returns null.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    idx=x['index']
    T=x['total']
    if not idx or T<=0: return None
    reqs=[]
    H=x['header_end']
    if H>0 and not any(a<=0 and H-1<=b for a,b in x['cached']): reqs.append([0,H-1])
    k=-1
    for i,(tm,off) in enumerate(idx):
        if tm<x['seek']: k=i
    o=idx[max(k,0)][1]
    if o>=T: return None
    e=min(T-1,o+x['window']-1)
    cur=o
    for a,b in sorted(x['cached']):
        if b<cur or a>e: continue
        if a>cur: reqs.append([cur,a-1])
        cur=max(cur,b+1)
    if cur<=e: reqs.append([cur,e])
    return ['bytes=%d-%d'%(a,b) for a,b in reqs]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('keyframe-not-after-seek fixture 0', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('keyframe-not-after-seek fixture 1', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2000,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('keyframe-not-after-seek fixture 2', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':3999,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('keyframe-not-after-seek fixture 3', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[1000,100],[3000,600]],'seek':500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=100-399'])))
check('keyframe-not-after-seek fixture 4', json.loads(json.dumps(solve({'cached':[[0,49]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('keyframe-not-after-seek fixture 5', json.loads(json.dumps(solve({'cached':[[50,200]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('keyframe-not-after-seek fixture 6', json.loads(json.dumps(solve({'cached':[[0,150]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-799'])))
check('keyframe-not-after-seek fixture 7', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':4500,'total':1200,'window':400}))), json.loads(json.dumps(['bytes=0-99','bytes=900-1199'])))
check('keyframe-not-after-seek fixture 8', json.loads(json.dumps(solve({'cached':[[0,99],[600,649]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-599','bytes=650-799'])))
check('keyframe-not-after-seek fixture 9', json.loads(json.dumps(solve({'cached':[[0,99],[900,950]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-799'])))
check('keyframe-not-after-seek fixture 10', json.loads(json.dumps(solve({'cached':[[0,99],[799,850]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-798'])))
check('keyframe-not-after-seek fixture 11', json.loads(json.dumps(solve({'cached':[[0,99],[600,610],[540,700]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-539','bytes=701-799'])))
check('keyframe-not-after-seek fixture 12', json.loads(json.dumps(solve({'cached':[[0,99],[500,798]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=799-799'])))
check('keyframe-not-after-seek fixture 13', json.loads(json.dumps(solve({'cached':[[0,99],[500,510]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=511-799'])))
check('keyframe-not-after-seek fixture 14', json.loads(json.dumps(solve({'cached':[[0,99],[501,510]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-500','bytes=511-799'])))
check('keyframe-not-after-seek fixture 15', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,1300]],'seek':3000,'total':1200,'window':300}))), json.loads(json.dumps(None)))
check('keyframe-not-after-seek fixture 16', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':10,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=100-399'])))
check('keyframe-not-after-seek fixture 17', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[1000,200],[2000,300],[3000,400],[4000,500],[5000,600]],'seek':1000*N,'total':2000,'window':50}))), json.loads(json.dumps(['bytes=0-99',"bytes=%d-%d"%(100*N+100,100*N+149)])))
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

meaning: Fixture-count band, not measured model difficulty

deps: stdlib

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    idx=x['index']
    T=x['total']
    if not idx or T<=0: return None
    reqs=[]
    H=x['header_end']
    if H>0 and not any(a<=0 and H-1<=b for a,b in x['cached']): reqs.append([0,H-1])
    k=-1
    for i,(tm,off) in enumerate(idx):
        if tm<=x['seek']+1: k=i
    o=idx[max(k,0)][1]
    if o>=T: return None
    e=min(T-1,o+x['window']-1)
    cur=o
    for a,b in sorted(x['cached']):
        if b<cur or a>e: continue
        if a>cur: reqs.append([cur,a-1])
        cur=max(cur,b+1)
    if cur<=e: reqs.append([cur,e])
    return ['bytes=%d-%d'%(a,b) for a,b in reqs]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('keyframe-not-after-seek fixture 0', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('keyframe-not-after-seek fixture 1', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2000,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('keyframe-not-after-seek fixture 2', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':3999,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('keyframe-not-after-seek fixture 3', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[1000,100],[3000,600]],'seek':500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=100-399'])))
check('keyframe-not-after-seek fixture 4', json.loads(json.dumps(solve({'cached':[[0,49]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('keyframe-not-after-seek fixture 5', json.loads(json.dumps(solve({'cached':[[50,200]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('keyframe-not-after-seek fixture 6', json.loads(json.dumps(solve({'cached':[[0,150]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-799'])))
check('keyframe-not-after-seek fixture 7', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':4500,'total':1200,'window':400}))), json.loads(json.dumps(['bytes=0-99','bytes=900-1199'])))
check('keyframe-not-after-seek fixture 8', json.loads(json.dumps(solve({'cached':[[0,99],[600,649]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-599','bytes=650-799'])))
check('keyframe-not-after-seek fixture 9', json.loads(json.dumps(solve({'cached':[[0,99],[900,950]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-799'])))
check('keyframe-not-after-seek fixture 10', json.loads(json.dumps(solve({'cached':[[0,99],[799,850]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-798'])))
check('keyframe-not-after-seek fixture 11', json.loads(json.dumps(solve({'cached':[[0,99],[600,610],[540,700]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-539','bytes=701-799'])))
check('keyframe-not-after-seek fixture 12', json.loads(json.dumps(solve({'cached':[[0,99],[500,798]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=799-799'])))
check('keyframe-not-after-seek fixture 13', json.loads(json.dumps(solve({'cached':[[0,99],[500,510]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=511-799'])))
check('keyframe-not-after-seek fixture 14', json.loads(json.dumps(solve({'cached':[[0,99],[501,510]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-500','bytes=511-799'])))
check('keyframe-not-after-seek fixture 15', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,1300]],'seek':3000,'total':1200,'window':300}))), json.loads(json.dumps(None)))
check('keyframe-not-after-seek fixture 16', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':10,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=100-399'])))
check('keyframe-not-after-seek fixture 17', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[1000,200],[2000,300],[3000,400],[4000,500],[5000,600]],'seek':1000*N,'total':2000,'window':50}))), json.loads(json.dumps(['bytes=0-99',"bytes=%d-%d"%(100*N+100,100*N+149)])))
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
A media player maps a seek time to keyframe-aligned byte range requests around cached spans: the decoder starts at the last keyframe at or before the seek time.

x has a time-sorted keyframe index [time,byte-offset], total length, init header length H (bytes 0..H-1), seek time, byte window and cached inclusive spans (unordered). Request the header unless one cached span covers all of it. Start at the last keyframe with time<=seek, or the first keyframe when seeking earlier. A start offset at or beyond total, an empty index or nonpositive total returns null. The media window is [start,min(total-1,start+window-1)]; request only its uncached gaps in ascending order, as inclusive bytes=a-b values after any header request.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    idx=x['index']
    T=x['total']
    if not idx or T<=0: return None
    reqs=[]
    H=x['header_end']
    if H>0 and not any(a<=0 and H-1<=b for a,b in x['cached']): reqs.append([0,H-1])
    k=-1
    for i,(tm,off) in enumerate(idx):
        if tm<=x['seek']: k=i
    o=idx[k][1]
    if o>=T: return None
    e=min(T-1,o+x['window']-1)
    cur=o
    for a,b in sorted(x['cached']):
        if b<cur or a>e: continue
        if a>cur: reqs.append([cur,a-1])
        cur=max(cur,b+1)
    if cur<=e: reqs.append([cur,e])
    return ['bytes=%d-%d'%(a,b) for a,b in reqs]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('pre-roll-sentinel fixture 0', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('pre-roll-sentinel fixture 1', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2000,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('pre-roll-sentinel fixture 2', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':3999,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('pre-roll-sentinel fixture 3', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[1000,100],[3000,600]],'seek':500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=100-399'])))
check('pre-roll-sentinel fixture 4', json.loads(json.dumps(solve({'cached':[[0,49]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('pre-roll-sentinel fixture 5', json.loads(json.dumps(solve({'cached':[[50,200]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('pre-roll-sentinel fixture 6', json.loads(json.dumps(solve({'cached':[[0,150]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-799'])))
check('pre-roll-sentinel fixture 7', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':4500,'total':1200,'window':400}))), json.loads(json.dumps(['bytes=0-99','bytes=900-1199'])))
check('pre-roll-sentinel fixture 8', json.loads(json.dumps(solve({'cached':[[0,99],[600,649]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-599','bytes=650-799'])))
check('pre-roll-sentinel fixture 9', json.loads(json.dumps(solve({'cached':[[0,99],[900,950]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-799'])))
check('pre-roll-sentinel fixture 10', json.loads(json.dumps(solve({'cached':[[0,99],[799,850]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-798'])))
check('pre-roll-sentinel fixture 11', json.loads(json.dumps(solve({'cached':[[0,99],[600,610],[540,700]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-539','bytes=701-799'])))
check('pre-roll-sentinel fixture 12', json.loads(json.dumps(solve({'cached':[[0,99],[500,798]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=799-799'])))
check('pre-roll-sentinel fixture 13', json.loads(json.dumps(solve({'cached':[[0,99],[500,510]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=511-799'])))
check('pre-roll-sentinel fixture 14', json.loads(json.dumps(solve({'cached':[[0,99],[501,510]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-500','bytes=511-799'])))
check('pre-roll-sentinel fixture 15', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,1300]],'seek':3000,'total':1200,'window':300}))), json.loads(json.dumps(None)))
check('pre-roll-sentinel fixture 16', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':10,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=100-399'])))
check('pre-roll-sentinel fixture 17', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[1000,200],[2000,300],[3000,400],[4000,500],[5000,600]],'seek':1000*N,'total':2000,'window':50}))), json.loads(json.dumps(['bytes=0-99',"bytes=%d-%d"%(100*N+100,100*N+149)])))
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    idx=x['index']
    T=x['total']
    if not idx or T<=0: return None
    reqs=[]
    H=x['header_end']
    if H>0 and not any(a<=0 and H-1<=b for a,b in x['cached']): reqs.append([0,H-1])
    k=-1
    for i,(tm,off) in enumerate(idx):
        if tm<=x['seek']: k=i
    o=idx[k][1] if k>=0 else 0
    if o>=T: return None
    e=min(T-1,o+x['window']-1)
    cur=o
    for a,b in sorted(x['cached']):
        if b<cur or a>e: continue
        if a>cur: reqs.append([cur,a-1])
        cur=max(cur,b+1)
    if cur<=e: reqs.append([cur,e])
    return ['bytes=%d-%d'%(a,b) for a,b in reqs]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('pre-roll-sentinel fixture 0', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('pre-roll-sentinel fixture 1', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2000,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('pre-roll-sentinel fixture 2', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':3999,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('pre-roll-sentinel fixture 3', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[1000,100],[3000,600]],'seek':500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=100-399'])))
check('pre-roll-sentinel fixture 4', json.loads(json.dumps(solve({'cached':[[0,49]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('pre-roll-sentinel fixture 5', json.loads(json.dumps(solve({'cached':[[50,200]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('pre-roll-sentinel fixture 6', json.loads(json.dumps(solve({'cached':[[0,150]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-799'])))
check('pre-roll-sentinel fixture 7', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':4500,'total':1200,'window':400}))), json.loads(json.dumps(['bytes=0-99','bytes=900-1199'])))
check('pre-roll-sentinel fixture 8', json.loads(json.dumps(solve({'cached':[[0,99],[600,649]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-599','bytes=650-799'])))
check('pre-roll-sentinel fixture 9', json.loads(json.dumps(solve({'cached':[[0,99],[900,950]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-799'])))
check('pre-roll-sentinel fixture 10', json.loads(json.dumps(solve({'cached':[[0,99],[799,850]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-798'])))
check('pre-roll-sentinel fixture 11', json.loads(json.dumps(solve({'cached':[[0,99],[600,610],[540,700]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-539','bytes=701-799'])))
check('pre-roll-sentinel fixture 12', json.loads(json.dumps(solve({'cached':[[0,99],[500,798]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=799-799'])))
check('pre-roll-sentinel fixture 13', json.loads(json.dumps(solve({'cached':[[0,99],[500,510]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=511-799'])))
check('pre-roll-sentinel fixture 14', json.loads(json.dumps(solve({'cached':[[0,99],[501,510]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-500','bytes=511-799'])))
check('pre-roll-sentinel fixture 15', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,1300]],'seek':3000,'total':1200,'window':300}))), json.loads(json.dumps(None)))
check('pre-roll-sentinel fixture 16', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':10,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=100-399'])))
check('pre-roll-sentinel fixture 17', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[1000,200],[2000,300],[3000,400],[4000,500],[5000,600]],'seek':1000*N,'total':2000,'window':50}))), json.loads(json.dumps(['bytes=0-99',"bytes=%d-%d"%(100*N+100,100*N+149)])))
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
A media player maps a seek time to keyframe-aligned byte range requests around cached spans: seeks before the first keyframe start there instead of wrapping to the last.

x has a time-sorted keyframe index [time,byte-offset], total length, init header length H (bytes 0..H-1), seek time, byte window and cached inclusive spans (unordered). Request the header unless one cached span covers all of it. Start at the last keyframe with time<=seek, or the first keyframe when seeking earlier. A start offset at or beyond total, an empty index or nonpositive total returns null. The media window is [start,min(total-1,start+window-1)]; request only its uncached gaps in ascending order, as inclusive bytes=a-b values after any header request.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    idx=x['index']
    T=x['total']
    if not idx or T<=0: return None
    reqs=[]
    H=x['header_end']
    if H>0 and not any(a<=0 for a,b in x['cached']): reqs.append([0,H-1])
    k=-1
    for i,(tm,off) in enumerate(idx):
        if tm<=x['seek']: k=i
    o=idx[max(k,0)][1]
    if o>=T: return None
    e=min(T-1,o+x['window']-1)
    cur=o
    for a,b in sorted(x['cached']):
        if b<cur or a>e: continue
        if a>cur: reqs.append([cur,a-1])
        cur=max(cur,b+1)
    if cur<=e: reqs.append([cur,e])
    return ['bytes=%d-%d'%(a,b) for a,b in reqs]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('init-cache-coverage fixture 0', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('init-cache-coverage fixture 1', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2000,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('init-cache-coverage fixture 2', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':3999,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('init-cache-coverage fixture 3', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[1000,100],[3000,600]],'seek':500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=100-399'])))
check('init-cache-coverage fixture 4', json.loads(json.dumps(solve({'cached':[[0,49]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('init-cache-coverage fixture 5', json.loads(json.dumps(solve({'cached':[[50,200]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('init-cache-coverage fixture 6', json.loads(json.dumps(solve({'cached':[[0,150]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-799'])))
check('init-cache-coverage fixture 7', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':4500,'total':1200,'window':400}))), json.loads(json.dumps(['bytes=0-99','bytes=900-1199'])))
check('init-cache-coverage fixture 8', json.loads(json.dumps(solve({'cached':[[0,99],[600,649]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-599','bytes=650-799'])))
check('init-cache-coverage fixture 9', json.loads(json.dumps(solve({'cached':[[0,99],[900,950]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-799'])))
check('init-cache-coverage fixture 10', json.loads(json.dumps(solve({'cached':[[0,99],[799,850]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-798'])))
check('init-cache-coverage fixture 11', json.loads(json.dumps(solve({'cached':[[0,99],[600,610],[540,700]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-539','bytes=701-799'])))
check('init-cache-coverage fixture 12', json.loads(json.dumps(solve({'cached':[[0,99],[500,798]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=799-799'])))
check('init-cache-coverage fixture 13', json.loads(json.dumps(solve({'cached':[[0,99],[500,510]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=511-799'])))
check('init-cache-coverage fixture 14', json.loads(json.dumps(solve({'cached':[[0,99],[501,510]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-500','bytes=511-799'])))
check('init-cache-coverage fixture 15', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,1300]],'seek':3000,'total':1200,'window':300}))), json.loads(json.dumps(None)))
check('init-cache-coverage fixture 16', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':10,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=100-399'])))
check('init-cache-coverage fixture 17', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[1000,200],[2000,300],[3000,400],[4000,500],[5000,600]],'seek':1000*N,'total':2000,'window':50}))), json.loads(json.dumps(['bytes=0-99',"bytes=%d-%d"%(100*N+100,100*N+149)])))
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    idx=x['index']
    T=x['total']
    if not idx or T<=0: return None
    reqs=[]
    H=x['header_end']
    if H>0 and not any(a<=0 or H-1<=b for a,b in x['cached']): reqs.append([0,H-1])
    k=-1
    for i,(tm,off) in enumerate(idx):
        if tm<=x['seek']: k=i
    o=idx[max(k,0)][1]
    if o>=T: return None
    e=min(T-1,o+x['window']-1)
    cur=o
    for a,b in sorted(x['cached']):
        if b<cur or a>e: continue
        if a>cur: reqs.append([cur,a-1])
        cur=max(cur,b+1)
    if cur<=e: reqs.append([cur,e])
    return ['bytes=%d-%d'%(a,b) for a,b in reqs]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('init-cache-coverage fixture 0', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('init-cache-coverage fixture 1', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2000,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('init-cache-coverage fixture 2', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':3999,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('init-cache-coverage fixture 3', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[1000,100],[3000,600]],'seek':500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=100-399'])))
check('init-cache-coverage fixture 4', json.loads(json.dumps(solve({'cached':[[0,49]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('init-cache-coverage fixture 5', json.loads(json.dumps(solve({'cached':[[50,200]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('init-cache-coverage fixture 6', json.loads(json.dumps(solve({'cached':[[0,150]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-799'])))
check('init-cache-coverage fixture 7', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':4500,'total':1200,'window':400}))), json.loads(json.dumps(['bytes=0-99','bytes=900-1199'])))
check('init-cache-coverage fixture 8', json.loads(json.dumps(solve({'cached':[[0,99],[600,649]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-599','bytes=650-799'])))
check('init-cache-coverage fixture 9', json.loads(json.dumps(solve({'cached':[[0,99],[900,950]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-799'])))
check('init-cache-coverage fixture 10', json.loads(json.dumps(solve({'cached':[[0,99],[799,850]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-798'])))
check('init-cache-coverage fixture 11', json.loads(json.dumps(solve({'cached':[[0,99],[600,610],[540,700]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-539','bytes=701-799'])))
check('init-cache-coverage fixture 12', json.loads(json.dumps(solve({'cached':[[0,99],[500,798]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=799-799'])))
check('init-cache-coverage fixture 13', json.loads(json.dumps(solve({'cached':[[0,99],[500,510]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=511-799'])))
check('init-cache-coverage fixture 14', json.loads(json.dumps(solve({'cached':[[0,99],[501,510]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-500','bytes=511-799'])))
check('init-cache-coverage fixture 15', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,1300]],'seek':3000,'total':1200,'window':300}))), json.loads(json.dumps(None)))
check('init-cache-coverage fixture 16', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':10,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=100-399'])))
check('init-cache-coverage fixture 17', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[1000,200],[2000,300],[3000,400],[4000,500],[5000,600]],'seek':1000*N,'total':2000,'window':50}))), json.loads(json.dumps(['bytes=0-99',"bytes=%d-%d"%(100*N+100,100*N+149)])))
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
A media player maps a seek time to keyframe-aligned byte range requests around cached spans: the header is skipped only when one cached span covers every header byte.

x has a time-sorted keyframe index [time,byte-offset], total length, init header length H (bytes 0..H-1), seek time, byte window and cached inclusive spans (unordered). Request the header unless one cached span covers all of it. Start at the last keyframe with time<=seek, or the first keyframe when seeking earlier. A start offset at or beyond total, an empty index or nonpositive total returns null. The media window is [start,min(total-1,start+window-1)]; request only its uncached gaps in ascending order, as inclusive bytes=a-b values after any header request.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    idx=x['index']
    T=x['total']
    if not idx or T<=0: return None
    reqs=[]
    H=x['header_end']
    if H>0 and not any(a<=0 and H-1<=b for a,b in x['cached']): reqs.append([0,H-1])
    k=-1
    for i,(tm,off) in enumerate(idx):
        if tm<=x['seek']: k=i
    o=idx[max(k,0)][1]
    if o>=T: return None
    e=o+x['window']-1
    cur=o
    for a,b in sorted(x['cached']):
        if b<cur or a>e: continue
        if a>cur: reqs.append([cur,a-1])
        cur=max(cur,b+1)
    if cur<=e: reqs.append([cur,e])
    return ['bytes=%d-%d'%(a,b) for a,b in reqs]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('window-end-clamp fixture 0', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('window-end-clamp fixture 1', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2000,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('window-end-clamp fixture 2', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':3999,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('window-end-clamp fixture 3', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[1000,100],[3000,600]],'seek':500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=100-399'])))
check('window-end-clamp fixture 4', json.loads(json.dumps(solve({'cached':[[0,49]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('window-end-clamp fixture 5', json.loads(json.dumps(solve({'cached':[[50,200]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('window-end-clamp fixture 6', json.loads(json.dumps(solve({'cached':[[0,150]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-799'])))
check('window-end-clamp fixture 7', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':4500,'total':1200,'window':400}))), json.loads(json.dumps(['bytes=0-99','bytes=900-1199'])))
check('window-end-clamp fixture 8', json.loads(json.dumps(solve({'cached':[[0,99],[600,649]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-599','bytes=650-799'])))
check('window-end-clamp fixture 9', json.loads(json.dumps(solve({'cached':[[0,99],[900,950]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-799'])))
check('window-end-clamp fixture 10', json.loads(json.dumps(solve({'cached':[[0,99],[799,850]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-798'])))
check('window-end-clamp fixture 11', json.loads(json.dumps(solve({'cached':[[0,99],[600,610],[540,700]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-539','bytes=701-799'])))
check('window-end-clamp fixture 12', json.loads(json.dumps(solve({'cached':[[0,99],[500,798]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=799-799'])))
check('window-end-clamp fixture 13', json.loads(json.dumps(solve({'cached':[[0,99],[500,510]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=511-799'])))
check('window-end-clamp fixture 14', json.loads(json.dumps(solve({'cached':[[0,99],[501,510]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-500','bytes=511-799'])))
check('window-end-clamp fixture 15', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,1300]],'seek':3000,'total':1200,'window':300}))), json.loads(json.dumps(None)))
check('window-end-clamp fixture 16', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':10,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=100-399'])))
check('window-end-clamp fixture 17', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[1000,200],[2000,300],[3000,400],[4000,500],[5000,600]],'seek':1000*N,'total':2000,'window':50}))), json.loads(json.dumps(['bytes=0-99',"bytes=%d-%d"%(100*N+100,100*N+149)])))
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    idx=x['index']
    T=x['total']
    if not idx or T<=0: return None
    reqs=[]
    H=x['header_end']
    if H>0 and not any(a<=0 and H-1<=b for a,b in x['cached']): reqs.append([0,H-1])
    k=-1
    for i,(tm,off) in enumerate(idx):
        if tm<=x['seek']: k=i
    o=idx[max(k,0)][1]
    if o>=T: return None
    e=min(T,o+x['window']-1)
    cur=o
    for a,b in sorted(x['cached']):
        if b<cur or a>e: continue
        if a>cur: reqs.append([cur,a-1])
        cur=max(cur,b+1)
    if cur<=e: reqs.append([cur,e])
    return ['bytes=%d-%d'%(a,b) for a,b in reqs]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('window-end-clamp fixture 0', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('window-end-clamp fixture 1', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2000,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('window-end-clamp fixture 2', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':3999,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('window-end-clamp fixture 3', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[1000,100],[3000,600]],'seek':500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=100-399'])))
check('window-end-clamp fixture 4', json.loads(json.dumps(solve({'cached':[[0,49]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('window-end-clamp fixture 5', json.loads(json.dumps(solve({'cached':[[50,200]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('window-end-clamp fixture 6', json.loads(json.dumps(solve({'cached':[[0,150]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-799'])))
check('window-end-clamp fixture 7', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':4500,'total':1200,'window':400}))), json.loads(json.dumps(['bytes=0-99','bytes=900-1199'])))
check('window-end-clamp fixture 8', json.loads(json.dumps(solve({'cached':[[0,99],[600,649]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-599','bytes=650-799'])))
check('window-end-clamp fixture 9', json.loads(json.dumps(solve({'cached':[[0,99],[900,950]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-799'])))
check('window-end-clamp fixture 10', json.loads(json.dumps(solve({'cached':[[0,99],[799,850]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-798'])))
check('window-end-clamp fixture 11', json.loads(json.dumps(solve({'cached':[[0,99],[600,610],[540,700]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-539','bytes=701-799'])))
check('window-end-clamp fixture 12', json.loads(json.dumps(solve({'cached':[[0,99],[500,798]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=799-799'])))
check('window-end-clamp fixture 13', json.loads(json.dumps(solve({'cached':[[0,99],[500,510]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=511-799'])))
check('window-end-clamp fixture 14', json.loads(json.dumps(solve({'cached':[[0,99],[501,510]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-500','bytes=511-799'])))
check('window-end-clamp fixture 15', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,1300]],'seek':3000,'total':1200,'window':300}))), json.loads(json.dumps(None)))
check('window-end-clamp fixture 16', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':10,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=100-399'])))
check('window-end-clamp fixture 17', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[1000,200],[2000,300],[3000,400],[4000,500],[5000,600]],'seek':1000*N,'total':2000,'window':50}))), json.loads(json.dumps(['bytes=0-99',"bytes=%d-%d"%(100*N+100,100*N+149)])))
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
A media player maps a seek time to keyframe-aligned byte range requests around cached spans: the media window stops at the last representation byte.

x has a time-sorted keyframe index [time,byte-offset], total length, init header length H (bytes 0..H-1), seek time, byte window and cached inclusive spans (unordered). Request the header unless one cached span covers all of it. Start at the last keyframe with time<=seek, or the first keyframe when seeking earlier. A start offset at or beyond total, an empty index or nonpositive total returns null. The media window is [start,min(total-1,start+window-1)]; request only its uncached gaps in ascending order, as inclusive bytes=a-b values after any header request.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    idx=x['index']
    T=x['total']
    if not idx or T<=0: return None
    reqs=[]
    H=x['header_end']
    if H>0 and not any(a<=0 and H-1<=b for a,b in x['cached']): reqs.append([0,H-1])
    k=-1
    for i,(tm,off) in enumerate(idx):
        if tm<=x['seek']: k=i
    o=idx[max(k,0)][1]
    if o>=T: return None
    e=min(T-1,o+x['window']-1)
    cur=o
    for a,b in sorted(x['cached']):
        if b<cur: continue
        if a>cur: reqs.append([cur,a-1])
        cur=max(cur,b+1)
    if cur<=e: reqs.append([cur,e])
    return ['bytes=%d-%d'%(a,b) for a,b in reqs]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('window-boundary fixture 0', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('window-boundary fixture 1', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2000,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('window-boundary fixture 2', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':3999,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('window-boundary fixture 3', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[1000,100],[3000,600]],'seek':500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=100-399'])))
check('window-boundary fixture 4', json.loads(json.dumps(solve({'cached':[[0,49]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('window-boundary fixture 5', json.loads(json.dumps(solve({'cached':[[50,200]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('window-boundary fixture 6', json.loads(json.dumps(solve({'cached':[[0,150]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-799'])))
check('window-boundary fixture 7', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':4500,'total':1200,'window':400}))), json.loads(json.dumps(['bytes=0-99','bytes=900-1199'])))
check('window-boundary fixture 8', json.loads(json.dumps(solve({'cached':[[0,99],[600,649]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-599','bytes=650-799'])))
check('window-boundary fixture 9', json.loads(json.dumps(solve({'cached':[[0,99],[900,950]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-799'])))
check('window-boundary fixture 10', json.loads(json.dumps(solve({'cached':[[0,99],[799,850]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-798'])))
check('window-boundary fixture 11', json.loads(json.dumps(solve({'cached':[[0,99],[600,610],[540,700]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-539','bytes=701-799'])))
check('window-boundary fixture 12', json.loads(json.dumps(solve({'cached':[[0,99],[500,798]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=799-799'])))
check('window-boundary fixture 13', json.loads(json.dumps(solve({'cached':[[0,99],[500,510]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=511-799'])))
check('window-boundary fixture 14', json.loads(json.dumps(solve({'cached':[[0,99],[501,510]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-500','bytes=511-799'])))
check('window-boundary fixture 15', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,1300]],'seek':3000,'total':1200,'window':300}))), json.loads(json.dumps(None)))
check('window-boundary fixture 16', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':10,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=100-399'])))
check('window-boundary fixture 17', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[1000,200],[2000,300],[3000,400],[4000,500],[5000,600]],'seek':1000*N,'total':2000,'window':50}))), json.loads(json.dumps(['bytes=0-99',"bytes=%d-%d"%(100*N+100,100*N+149)])))
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    idx=x['index']
    T=x['total']
    if not idx or T<=0: return None
    reqs=[]
    H=x['header_end']
    if H>0 and not any(a<=0 and H-1<=b for a,b in x['cached']): reqs.append([0,H-1])
    k=-1
    for i,(tm,off) in enumerate(idx):
        if tm<=x['seek']: k=i
    o=idx[max(k,0)][1]
    if o>=T: return None
    e=min(T-1,o+x['window']-1)
    cur=o
    for a,b in sorted(x['cached']):
        if b<cur or a>=e: continue
        if a>cur: reqs.append([cur,a-1])
        cur=max(cur,b+1)
    if cur<=e: reqs.append([cur,e])
    return ['bytes=%d-%d'%(a,b) for a,b in reqs]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('window-boundary fixture 0', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('window-boundary fixture 1', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2000,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('window-boundary fixture 2', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':3999,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('window-boundary fixture 3', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[1000,100],[3000,600]],'seek':500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=100-399'])))
check('window-boundary fixture 4', json.loads(json.dumps(solve({'cached':[[0,49]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('window-boundary fixture 5', json.loads(json.dumps(solve({'cached':[[50,200]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('window-boundary fixture 6', json.loads(json.dumps(solve({'cached':[[0,150]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-799'])))
check('window-boundary fixture 7', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':4500,'total':1200,'window':400}))), json.loads(json.dumps(['bytes=0-99','bytes=900-1199'])))
check('window-boundary fixture 8', json.loads(json.dumps(solve({'cached':[[0,99],[600,649]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-599','bytes=650-799'])))
check('window-boundary fixture 9', json.loads(json.dumps(solve({'cached':[[0,99],[900,950]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-799'])))
check('window-boundary fixture 10', json.loads(json.dumps(solve({'cached':[[0,99],[799,850]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-798'])))
check('window-boundary fixture 11', json.loads(json.dumps(solve({'cached':[[0,99],[600,610],[540,700]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-539','bytes=701-799'])))
check('window-boundary fixture 12', json.loads(json.dumps(solve({'cached':[[0,99],[500,798]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=799-799'])))
check('window-boundary fixture 13', json.loads(json.dumps(solve({'cached':[[0,99],[500,510]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=511-799'])))
check('window-boundary fixture 14', json.loads(json.dumps(solve({'cached':[[0,99],[501,510]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-500','bytes=511-799'])))
check('window-boundary fixture 15', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,1300]],'seek':3000,'total':1200,'window':300}))), json.loads(json.dumps(None)))
check('window-boundary fixture 16', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':10,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=100-399'])))
check('window-boundary fixture 17', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[1000,200],[2000,300],[3000,400],[4000,500],[5000,600]],'seek':1000*N,'total':2000,'window':50}))), json.loads(json.dumps(['bytes=0-99',"bytes=%d-%d"%(100*N+100,100*N+149)])))
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
A media player maps a seek time to keyframe-aligned byte range requests around cached spans: cached spans beyond the window cannot create requests past it.

x has a time-sorted keyframe index [time,byte-offset], total length, init header length H (bytes 0..H-1), seek time, byte window and cached inclusive spans (unordered). Request the header unless one cached span covers all of it. Start at the last keyframe with time<=seek, or the first keyframe when seeking earlier. A start offset at or beyond total, an empty index or nonpositive total returns null. The media window is [start,min(total-1,start+window-1)]; request only its uncached gaps in ascending order, as inclusive bytes=a-b values after any header request.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    idx=x['index']
    T=x['total']
    if not idx or T<=0: return None
    reqs=[]
    H=x['header_end']
    if H>0 and not any(a<=0 and H-1<=b for a,b in x['cached']): reqs.append([0,H-1])
    k=-1
    for i,(tm,off) in enumerate(idx):
        if tm<=x['seek']: k=i
    o=idx[max(k,0)][1]
    if o>=T: return None
    e=min(T-1,o+x['window']-1)
    cur=o
    for a,b in sorted(x['cached']):
        if b<cur or a>e: continue
        if a>cur: reqs.append([cur,a])
        cur=max(cur,b+1)
    if cur<=e: reqs.append([cur,e])
    return ['bytes=%d-%d'%(a,b) for a,b in reqs]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('gap-end fixture 0', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('gap-end fixture 1', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2000,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('gap-end fixture 2', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':3999,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('gap-end fixture 3', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[1000,100],[3000,600]],'seek':500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=100-399'])))
check('gap-end fixture 4', json.loads(json.dumps(solve({'cached':[[0,49]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('gap-end fixture 5', json.loads(json.dumps(solve({'cached':[[50,200]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('gap-end fixture 6', json.loads(json.dumps(solve({'cached':[[0,150]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-799'])))
check('gap-end fixture 7', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':4500,'total':1200,'window':400}))), json.loads(json.dumps(['bytes=0-99','bytes=900-1199'])))
check('gap-end fixture 8', json.loads(json.dumps(solve({'cached':[[0,99],[600,649]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-599','bytes=650-799'])))
check('gap-end fixture 9', json.loads(json.dumps(solve({'cached':[[0,99],[900,950]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-799'])))
check('gap-end fixture 10', json.loads(json.dumps(solve({'cached':[[0,99],[799,850]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-798'])))
check('gap-end fixture 11', json.loads(json.dumps(solve({'cached':[[0,99],[600,610],[540,700]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-539','bytes=701-799'])))
check('gap-end fixture 12', json.loads(json.dumps(solve({'cached':[[0,99],[500,798]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=799-799'])))
check('gap-end fixture 13', json.loads(json.dumps(solve({'cached':[[0,99],[500,510]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=511-799'])))
check('gap-end fixture 14', json.loads(json.dumps(solve({'cached':[[0,99],[501,510]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-500','bytes=511-799'])))
check('gap-end fixture 15', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,1300]],'seek':3000,'total':1200,'window':300}))), json.loads(json.dumps(None)))
check('gap-end fixture 16', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':10,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=100-399'])))
check('gap-end fixture 17', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[1000,200],[2000,300],[3000,400],[4000,500],[5000,600]],'seek':1000*N,'total':2000,'window':50}))), json.loads(json.dumps(['bytes=0-99',"bytes=%d-%d"%(100*N+100,100*N+149)])))
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    idx=x['index']
    T=x['total']
    if not idx or T<=0: return None
    reqs=[]
    H=x['header_end']
    if H>0 and not any(a<=0 and H-1<=b for a,b in x['cached']): reqs.append([0,H-1])
    k=-1
    for i,(tm,off) in enumerate(idx):
        if tm<=x['seek']: k=i
    o=idx[max(k,0)][1]
    if o>=T: return None
    e=min(T-1,o+x['window']-1)
    cur=o
    for a,b in sorted(x['cached']):
        if b<cur or a>e: continue
        if a>cur: reqs.append([cur,b])
        cur=max(cur,b+1)
    if cur<=e: reqs.append([cur,e])
    return ['bytes=%d-%d'%(a,b) for a,b in reqs]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('gap-end fixture 0', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('gap-end fixture 1', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2000,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('gap-end fixture 2', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':3999,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('gap-end fixture 3', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[1000,100],[3000,600]],'seek':500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=100-399'])))
check('gap-end fixture 4', json.loads(json.dumps(solve({'cached':[[0,49]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('gap-end fixture 5', json.loads(json.dumps(solve({'cached':[[50,200]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('gap-end fixture 6', json.loads(json.dumps(solve({'cached':[[0,150]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-799'])))
check('gap-end fixture 7', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':4500,'total':1200,'window':400}))), json.loads(json.dumps(['bytes=0-99','bytes=900-1199'])))
check('gap-end fixture 8', json.loads(json.dumps(solve({'cached':[[0,99],[600,649]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-599','bytes=650-799'])))
check('gap-end fixture 9', json.loads(json.dumps(solve({'cached':[[0,99],[900,950]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-799'])))
check('gap-end fixture 10', json.loads(json.dumps(solve({'cached':[[0,99],[799,850]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-798'])))
check('gap-end fixture 11', json.loads(json.dumps(solve({'cached':[[0,99],[600,610],[540,700]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-539','bytes=701-799'])))
check('gap-end fixture 12', json.loads(json.dumps(solve({'cached':[[0,99],[500,798]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=799-799'])))
check('gap-end fixture 13', json.loads(json.dumps(solve({'cached':[[0,99],[500,510]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=511-799'])))
check('gap-end fixture 14', json.loads(json.dumps(solve({'cached':[[0,99],[501,510]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-500','bytes=511-799'])))
check('gap-end fixture 15', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,1300]],'seek':3000,'total':1200,'window':300}))), json.loads(json.dumps(None)))
check('gap-end fixture 16', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':10,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=100-399'])))
check('gap-end fixture 17', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[1000,200],[2000,300],[3000,400],[4000,500],[5000,600]],'seek':1000*N,'total':2000,'window':50}))), json.loads(json.dumps(['bytes=0-99',"bytes=%d-%d"%(100*N+100,100*N+149)])))
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
A media player maps a seek time to keyframe-aligned byte range requests around cached spans: a gap request stops before the next cached byte.

x has a time-sorted keyframe index [time,byte-offset], total length, init header length H (bytes 0..H-1), seek time, byte window and cached inclusive spans (unordered). Request the header unless one cached span covers all of it. Start at the last keyframe with time<=seek, or the first keyframe when seeking earlier. A start offset at or beyond total, an empty index or nonpositive total returns null. The media window is [start,min(total-1,start+window-1)]; request only its uncached gaps in ascending order, as inclusive bytes=a-b values after any header request.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    idx=x['index']
    T=x['total']
    if not idx or T<=0: return None
    reqs=[]
    H=x['header_end']
    if H>0 and not any(a<=0 and H-1<=b for a,b in x['cached']): reqs.append([0,H-1])
    k=-1
    for i,(tm,off) in enumerate(idx):
        if tm<=x['seek']: k=i
    o=idx[max(k,0)][1]
    if o>=T: return None
    e=min(T-1,o+x['window']-1)
    cur=o
    for a,b in x['cached']:
        if b<cur or a>e: continue
        if a>cur: reqs.append([cur,a-1])
        cur=max(cur,b+1)
    if cur<=e: reqs.append([cur,e])
    return ['bytes=%d-%d'%(a,b) for a,b in reqs]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('cached-order fixture 0', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('cached-order fixture 1', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2000,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('cached-order fixture 2', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':3999,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('cached-order fixture 3', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[1000,100],[3000,600]],'seek':500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=100-399'])))
check('cached-order fixture 4', json.loads(json.dumps(solve({'cached':[[0,49]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('cached-order fixture 5', json.loads(json.dumps(solve({'cached':[[50,200]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('cached-order fixture 6', json.loads(json.dumps(solve({'cached':[[0,150]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-799'])))
check('cached-order fixture 7', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':4500,'total':1200,'window':400}))), json.loads(json.dumps(['bytes=0-99','bytes=900-1199'])))
check('cached-order fixture 8', json.loads(json.dumps(solve({'cached':[[0,99],[600,649]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-599','bytes=650-799'])))
check('cached-order fixture 9', json.loads(json.dumps(solve({'cached':[[0,99],[900,950]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-799'])))
check('cached-order fixture 10', json.loads(json.dumps(solve({'cached':[[0,99],[799,850]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-798'])))
check('cached-order fixture 11', json.loads(json.dumps(solve({'cached':[[0,99],[600,610],[540,700]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-539','bytes=701-799'])))
check('cached-order fixture 12', json.loads(json.dumps(solve({'cached':[[0,99],[500,798]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=799-799'])))
check('cached-order fixture 13', json.loads(json.dumps(solve({'cached':[[0,99],[500,510]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=511-799'])))
check('cached-order fixture 14', json.loads(json.dumps(solve({'cached':[[0,99],[501,510]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-500','bytes=511-799'])))
check('cached-order fixture 15', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,1300]],'seek':3000,'total':1200,'window':300}))), json.loads(json.dumps(None)))
check('cached-order fixture 16', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':10,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=100-399'])))
check('cached-order fixture 17', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[1000,200],[2000,300],[3000,400],[4000,500],[5000,600]],'seek':1000*N,'total':2000,'window':50}))), json.loads(json.dumps(['bytes=0-99',"bytes=%d-%d"%(100*N+100,100*N+149)])))
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    idx=x['index']
    T=x['total']
    if not idx or T<=0: return None
    reqs=[]
    H=x['header_end']
    if H>0 and not any(a<=0 and H-1<=b for a,b in x['cached']): reqs.append([0,H-1])
    k=-1
    for i,(tm,off) in enumerate(idx):
        if tm<=x['seek']: k=i
    o=idx[max(k,0)][1]
    if o>=T: return None
    e=min(T-1,o+x['window']-1)
    cur=o
    for a,b in sorted(x['cached'],key=lambda r:r[1]):
        if b<cur or a>e: continue
        if a>cur: reqs.append([cur,a-1])
        cur=max(cur,b+1)
    if cur<=e: reqs.append([cur,e])
    return ['bytes=%d-%d'%(a,b) for a,b in reqs]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('cached-order fixture 0', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('cached-order fixture 1', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2000,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('cached-order fixture 2', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':3999,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('cached-order fixture 3', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[1000,100],[3000,600]],'seek':500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=100-399'])))
check('cached-order fixture 4', json.loads(json.dumps(solve({'cached':[[0,49]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('cached-order fixture 5', json.loads(json.dumps(solve({'cached':[[50,200]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=500-799'])))
check('cached-order fixture 6', json.loads(json.dumps(solve({'cached':[[0,150]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-799'])))
check('cached-order fixture 7', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':4500,'total':1200,'window':400}))), json.loads(json.dumps(['bytes=0-99','bytes=900-1199'])))
check('cached-order fixture 8', json.loads(json.dumps(solve({'cached':[[0,99],[600,649]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-599','bytes=650-799'])))
check('cached-order fixture 9', json.loads(json.dumps(solve({'cached':[[0,99],[900,950]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-799'])))
check('cached-order fixture 10', json.loads(json.dumps(solve({'cached':[[0,99],[799,850]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-798'])))
check('cached-order fixture 11', json.loads(json.dumps(solve({'cached':[[0,99],[600,610],[540,700]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-539','bytes=701-799'])))
check('cached-order fixture 12', json.loads(json.dumps(solve({'cached':[[0,99],[500,798]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=799-799'])))
check('cached-order fixture 13', json.loads(json.dumps(solve({'cached':[[0,99],[500,510]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=511-799'])))
check('cached-order fixture 14', json.loads(json.dumps(solve({'cached':[[0,99],[501,510]],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':2500,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=500-500','bytes=511-799'])))
check('cached-order fixture 15', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,1300]],'seek':3000,'total':1200,'window':300}))), json.loads(json.dumps(None)))
check('cached-order fixture 16', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[2000,500],[4000,900]],'seek':10,'total':1200,'window':300}))), json.loads(json.dumps(['bytes=0-99','bytes=100-399'])))
check('cached-order fixture 17', json.loads(json.dumps(solve({'cached':[],'header_end':100,'index':[[0,100],[1000,200],[2000,300],[3000,400],[4000,500],[5000,600]],'seek':1000*N,'total':2000,'window':50}))), json.loads(json.dumps(['bytes=0-99',"bytes=%d-%d"%(100*N+100,100*N+149)])))
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
A media player maps a seek time to keyframe-aligned byte range requests around cached spans: cached spans are processed in start order.

x has a time-sorted keyframe index [time,byte-offset], total length, init header length H (bytes 0..H-1), seek time, byte window and cached inclusive spans (unordered). Request the header unless one cached span covers all of it. Start at the last keyframe with time<=seek, or the first keyframe when seeking earlier. A start offset at or beyond total, an empty index or nonpositive total returns null. The media window is [start,min(total-1,start+window-1)]; request only its uncached gaps in ascending order, as inclusive bytes=a-b values after any header request.

split: open-access