1 | #!/usr/bin/env python |
---|
2 | |
---|
3 | |
---|
4 | import sys, math |
---|
5 | from allmydata import uri, storage |
---|
6 | from allmydata.immutable import upload |
---|
7 | from allmydata.interfaces import DEFAULT_IMMUTABLE_MAX_SEGMENT_SIZE |
---|
8 | from allmydata.util import mathutil |
---|
9 | |
---|
10 | def roundup(size, blocksize=4096): |
---|
11 | return blocksize * mathutil.div_ceil(size, blocksize) |
---|
12 | |
---|
13 | |
---|
14 | class BigFakeString(object): |
---|
15 | def __init__(self, length): |
---|
16 | self.length = length |
---|
17 | self.fp = 0 |
---|
18 | def seek(self, offset, whence=0): |
---|
19 | if whence == 0: |
---|
20 | self.fp = offset |
---|
21 | elif whence == 1: |
---|
22 | self.fp += offset |
---|
23 | elif whence == 2: |
---|
24 | self.fp = self.length - offset |
---|
25 | def tell(self): |
---|
26 | return self.fp |
---|
27 | |
---|
28 | def calc(filesize, params=(3,7,10), segsize=DEFAULT_IMMUTABLE_MAX_SEGMENT_SIZE): |
---|
29 | num_shares = params[2] |
---|
30 | if filesize <= upload.Uploader.URI_LIT_SIZE_THRESHOLD: |
---|
31 | urisize = len(uri.LiteralFileURI("A"*filesize).to_string()) |
---|
32 | sharesize = 0 |
---|
33 | sharespace = 0 |
---|
34 | else: |
---|
35 | u = upload.FileUploader(None) # XXX changed |
---|
36 | u.set_params(params) |
---|
37 | # unfortunately, Encoder doesn't currently lend itself to answering |
---|
38 | # this question without measuring a filesize, so we have to give it a |
---|
39 | # fake one |
---|
40 | data = BigFakeString(filesize) |
---|
41 | u.set_filehandle(data) |
---|
42 | u.set_encryption_key("a"*16) |
---|
43 | sharesize, blocksize = u.setup_encoder() |
---|
44 | # how much overhead? |
---|
45 | # 0x20 bytes of offsets |
---|
46 | # 0x04 bytes of extension length |
---|
47 | # 0x1ad bytes of extension (=429) |
---|
48 | # total is 465 bytes |
---|
49 | num_segments = mathutil.div_ceil(filesize, segsize) |
---|
50 | num_share_hashes = int(math.log(mathutil.next_power_of_k(num_shares, 2), |
---|
51 | 2)) + 1 |
---|
52 | sharesize = storage.allocated_size(sharesize, num_segments, |
---|
53 | num_share_hashes, |
---|
54 | 429) |
---|
55 | sharespace = num_shares * roundup(sharesize) |
---|
56 | urisize = len(uri.pack_uri(storage_index="a"*32, |
---|
57 | key="a"*16, |
---|
58 | uri_extension_hash="a"*32, |
---|
59 | needed_shares=params[0], |
---|
60 | total_shares=params[2], |
---|
61 | size=filesize)) |
---|
62 | |
---|
63 | return urisize, sharesize, sharespace |
---|
64 | |
---|
65 | def main(): |
---|
66 | filesize = int(sys.argv[1]) |
---|
67 | urisize, sharesize, sharespace = calc(filesize) |
---|
68 | print("urisize:", urisize) |
---|
69 | print("sharesize: %10d" % sharesize) |
---|
70 | print("sharespace: %10d" % sharespace) |
---|
71 | print("desired expansion: %1.1f" % (1.0 * 10 / 3)) |
---|
72 | print("effective expansion: %1.1f" % (1.0 * sharespace / filesize)) |
---|
73 | |
---|
74 | def chart(): |
---|
75 | filesize = 2 |
---|
76 | while filesize < 2**20: |
---|
77 | urisize, sharesize, sharespace = calc(int(filesize)) |
---|
78 | expansion = 1.0 * sharespace / int(filesize) |
---|
79 | print("%d,%d,%d,%1.2f" % (int(filesize), urisize, sharespace, expansion)) |
---|
80 | filesize = filesize * 2**0.5 |
---|
81 | |
---|
82 | if __name__ == '__main__': |
---|
83 | if sys.argv[1] == "chart": |
---|
84 | chart() |
---|
85 | else: |
---|
86 | main() |
---|
87 | |
---|