'Implement EC policy specific handling of .data and legacy .durable
files.
If a frag_prefs keyword arg is provided then its value may determine
which fragment index at which timestamp is used to construct the
diskfile. The value of frag_prefs should be a list. Each item in the
frag_prefs list should be a dict that describes per-timestamp
preferences using the following items:
* timestamp: An instance of :class:`~swift.common.utils.Timestamp`.
* exclude: A list of valid fragment indexes (i.e. whole numbers)
that should be EXCLUDED when choosing a fragment at the
timestamp. This list may be empty.
For example::
{\'timestamp\': <Timestamp instance>, \'exclude\': [1,3]},
{\'timestamp\': <Timestamp instance>, \'exclude\': []}
The order of per-timestamp dicts in the frag_prefs list is significant
and indicates descending preference for fragments from each timestamp
i.e. a fragment that satisfies the first per-timestamp preference in
the frag_prefs will be preferred over a fragment that satisfies a
subsequent per-timestamp preferred, and so on.
If a timestamp is not cited in any per-timestamp preference dict then
it is assumed that any fragment index at that timestamp may be used to
construct the diskfile.
When a frag_prefs arg is provided, including an empty list, there is no
requirement for there to be a durable file at the same timestamp as a
data file that is chosen to construct the disk file
:param exts: dict of lists of file info, keyed by extension
:param results: a dict that may be updated with results
:param frag_index: if set, search for a specific fragment index .data
file, otherwise accept the first valid .data file.
:param frag_prefs: if set, search for any fragment index .data file
that satisfies the frag_prefs.'

def _process_ondisk_files(self, exts, results, frag_index=None, frag_prefs=None, **kwargs):

    durable_info = None
    if exts.get('.durable'):
        durable_info = exts['.durable'][0]
    all_frags = exts.get('.data')
    frag_sets = {}
    durable_frag_set = None
    while all_frags:
        (frag_set, all_frags) = self._split_gte_timestamp(all_frags, all_frags[0]['timestamp'])
        frag_set.sort(key=(lambda info: info['frag_index']))
        timestamp = frag_set[0]['timestamp']
        frag_sets[timestamp] = frag_set
        for frag in frag_set:
            if frag['durable']:
                if ((not durable_info) or (durable_info['timestamp'] < timestamp)):
                    durable_info = frag
                break
        if (durable_info and (durable_info['timestamp'] == timestamp)):
            durable_frag_set = frag_set
            break
    chosen_frag_set = None
    if (frag_prefs is not None):
        candidate_frag_sets = dict(frag_sets)
        for (ts, exclude_indexes) in [(ts_pref['timestamp'], ts_pref['exclude']) for ts_pref in frag_prefs if (ts_pref['timestamp'] in candidate_frag_sets)]:
            available_indexes = [info['frag_index'] for info in candidate_frag_sets[ts]]
            acceptable_indexes = list((set(available_indexes) - set(exclude_indexes)))
            if acceptable_indexes:
                chosen_frag_set = candidate_frag_sets[ts]
                frag_index = acceptable_indexes[(-1)]
                break
            else:
                candidate_frag_sets.pop(ts)
        else:
            if candidate_frag_sets:
                ts_newest = sorted(candidate_frag_sets.keys())[(-1)]
                chosen_frag_set = candidate_frag_sets[ts_newest]
    else:
        chosen_frag_set = durable_frag_set
    chosen_frag = None
    if chosen_frag_set:
        if (frag_index is not None):
            for info in chosen_frag_set:
                if (info['frag_index'] == frag_index):
                    chosen_frag = info
                    break
        else:
            chosen_frag = chosen_frag_set[(-1)]
    if chosen_frag:
        results['data_info'] = chosen_frag
        results['durable_frag_set'] = durable_frag_set
        results['chosen_frag_set'] = chosen_frag_set
        if (chosen_frag_set != durable_frag_set):
            (exts['.meta'], _older) = self._split_gt_timestamp(exts['.meta'], chosen_frag['timestamp'])
    results['frag_sets'] = frag_sets
    if durable_info:
        for ext in exts.keys():
            (exts[ext], older) = self._split_gte_timestamp(exts[ext], durable_info['timestamp'])
            results.setdefault('obsolete', []).extend(older)
    if (exts.get('.durable') and (not durable_frag_set)):
        results.setdefault('obsolete', []).extend(exts['.durable'])
        exts.pop('.durable')
    for frag_set in frag_sets.values():
        if (frag_set in (durable_frag_set, chosen_frag_set)):
            continue
        results.setdefault('possible_reclaim', []).extend(frag_set)
    if (exts.get('.meta') and (not durable_frag_set)):
        results.setdefault('possible_reclaim', []).extend(exts.get('.meta'))
