|
| 1 | +from typing import List |
| 2 | + |
| 3 | + |
| 4 | +def allocation_num(number_of_bytes: int, partitions: int) -> List[str]: |
| 5 | + """ |
| 6 | + Divide a number of bytes into x partitions. |
| 7 | + |
| 8 | + In a multi-threaded download, this algorithm could be used to provide |
| 9 | + each worker thread with a block of non-overlapping bytes to download. |
| 10 | + For example: |
| 11 | + for i in allocation_list: |
| 12 | + requests.get(url,headers={'Range':f'bytes={i}'}) |
| 13 | +
|
| 14 | + parameter |
| 15 | + ------------ |
| 16 | + : param number_of_bytes |
| 17 | + : param partitions |
| 18 | +
|
| 19 | + return |
| 20 | + ------------ |
| 21 | + : return: list of bytes to be assigned to each worker thread |
| 22 | +
|
| 23 | + Examples: |
| 24 | + ------------ |
| 25 | + >>> allocation_num(16647, 4) |
| 26 | + ['0-4161', '4162-8322', '8323-12483', '12484-16647'] |
| 27 | + >>> allocation_num(888, 888) |
| 28 | + Traceback (most recent call last): |
| 29 | + ... |
| 30 | + ValueError: partitions can not >= number_of_bytes! |
| 31 | + >>> allocation_num(888, 999) |
| 32 | + Traceback (most recent call last): |
| 33 | + ... |
| 34 | + ValueError: partitions can not >= number_of_bytes! |
| 35 | + >>> allocation_num(888, -4) |
| 36 | + Traceback (most recent call last): |
| 37 | + ... |
| 38 | + ValueError: partitions must be a positive number! |
| 39 | + """ |
| 40 | + if partitions <= 0: |
| 41 | + raise ValueError('partitions must be a positive number!') |
| 42 | + if partitions >= number_of_bytes: |
| 43 | + raise ValueError('partitions can not >= number_of_bytes!') |
| 44 | + bytes_per_partition = number_of_bytes // partitions |
| 45 | + allocation_list = [f'0-{bytes_per_partition}'] |
| 46 | + for i in range(1, partitions - 1): |
| 47 | + length = f'{bytes_per_partition * i + 1}-{bytes_per_partition * (i + 1)}' |
| 48 | + allocation_list.append(length) |
| 49 | + allocation_list.append(f'{(bytes_per_partition * (partitions - 1)) + 1}-' |
| 50 | + f'{number_of_bytes}') |
| 51 | + return allocation_list |
| 52 | + |
| 53 | + |
| 54 | +if __name__ == '__main__': |
| 55 | + import doctest |
| 56 | + doctest.testmod() |
0 commit comments