def _recursiveReduce(mapFunc, reductionFunc, scan, *iterables):
    """Generates the recursive reduction tree. Used by mapReduce."""
    if iterables:
        half = min(len(x) // 2 for x in iterables)
        data_left = [list(x)[:half] for x in iterables]
        data_right = [list(x)[half:] for x in iterables]
    else:
        data_left = data_right = [[]]

    # Submit the left and right parts of the reduction
    out_futures = [None, None]
    out_results = [None, None]
    for index, data in enumerate([data_left, data_right]):
        if any(len(x) <= 1 for x in data):
            out_results[index] = mapFunc(*list(zip(*data))[0])
        else:
            out_futures[index] = submit(
                _recursiveReduce,
                mapFunc,
                reductionFunc,
                scan,
                *data
            )

    # Wait for the results
    for index, future in enumerate(out_futures):
        if future:
            out_results[index] = future.result()

    # Apply a scan if needed
    if scan:
        last_results = copy.copy(out_results)
        if type(out_results[0]) is not list:
            out_results[0] = [out_results[0]]
        else:
            last_results[0] = out_results[0][-1]
        if type(out_results[1]) is list:
            out_results[0].extend(out_results[1][:-1])
            last_results[1] = out_results[1][-1]
        out_results[0].append(reductionFunc(*last_results))
        return out_results[0]

    return reductionFunc(*out_results)
Generates the recursive reduction tree. Used by mapReduce.