PyORAm
[iotcloud.git] / PyORAM / src / pyoram / util / misc.py
1 import base64
2
3 import six
4
5 def log2floor(n):
6     """
7     Returns the exact value of floor(log2(n)).
8     No floating point calculations are used.
9     Requires positive integer type.
10     """
11     assert n > 0
12     return n.bit_length() - 1
13
14 def log2ceil(n):
15     """
16     Returns the exact value of ceil(log2(n)).
17     No floating point calculations are used.
18     Requires positive integer type.
19     """
20     if n == 1:
21         return 0
22     return log2floor(n-1) + 1
23
24 def intdivceil(x, y):
25     """
26     Returns the exact value of ceil(x // y).
27     No floating point calculations are used.
28     Requires positive integer types. The result
29     is undefined if at least one of the inputs
30     is floating point.
31     """
32     result = x // y
33     if (x % y):
34         result += 1
35     return result
36
37 def save_private_key(filename, key):
38     with open(filename, "wb") as f:
39         f.write(base64.b64encode(key))
40
41 def load_private_key(filename):
42     with open(filename, "rb") as f:
43         return base64.b64decode(f.read())
44
45 from fractions import Fraction
46
47 class MemorySize(object):
48
49     to_bytes = {}
50     to_bytes['b'] = lambda x: Fraction(x,8)
51     to_bytes['B'] = lambda x: Fraction(x,1)
52     to_bytes['KB'] = lambda x: Fraction(1000*x,1)
53     to_bytes['MB'] = lambda x: Fraction((1000**2)*x,1)
54     to_bytes['GB'] = lambda x: Fraction((1000**3)*x,1)
55     to_bytes['TB'] = lambda x: Fraction((1000**4)*x,1)
56     to_bytes['KiB'] = lambda x: Fraction(1024*x,1)
57     to_bytes['MiB'] = lambda x: Fraction((1024**2)*x,1)
58     to_bytes['GiB'] = lambda x: Fraction((1024**3)*x,1)
59     to_bytes['TiB'] = lambda x: Fraction((1024**4)*x,1)
60
61     def __init__(self, size, unit='B'):
62         assert size >= 0
63         self.numbytes = MemorySize.to_bytes[unit](Fraction.from_float(size))
64
65     def __str__(self):
66         if self.B < 1:
67             return "%.3f b" % (self.b)
68         if self.KB < 1:
69             return "%.3f B" % (self.B)
70         if self.MB < 1:
71             return "%.3f KB" % (self.KB)
72         if self.GB < 1:
73             return "%.3f MB" % (self.MB)
74         if self.TB < 1:
75             return "%.3f GB" % (self.GB)
76         return "%.3f TB" % (self.TB)
77
78     @property
79     def b(self): return self.numbytes*8
80     @property
81     def B(self): return self.numbytes
82
83     @property
84     def KB(self): return self.B/1000
85     @property
86     def MB(self): return self.KB/1000
87     @property
88     def GB(self): return self.MB/1000
89     @property
90     def TB(self): return self.GB/1000
91
92     @property
93     def KiB(self): return self.B/1024
94     @property
95     def MiB(self): return self.KiB/1024
96     @property
97     def GiB(self): return self.MiB/1024
98     @property
99     def TiB(self): return self.GiB/1024
100
101 def chunkiter(objs, n=100):
102     """
103     Chunk an iterator of unknown size. The optional
104     keyword 'n' sets the chunk size (default 100).
105     """
106
107     objs = iter(objs)
108     try:
109         while (1):
110             chunk = []
111             while len(chunk) < n:
112                 chunk.append(six.next(objs))
113             yield chunk
114     except StopIteration:
115         pass
116     if len(chunk):
117         yield chunk