Revision 3e7c63f8 snf-cyclades-app/synnefo/db/pools/__init__.py

b/snf-cyclades-app/synnefo/db/pools/__init__.py
27 27
    """
28 28
    def __init__(self, pool_table):
29 29
        self.pool_table = pool_table
30

  
30
        self.pool_size = pool_table.size
31 31
        if pool_table.available_map:
32 32
            self.available = _bitarray_from_string(pool_table.available_map)
33 33
            self.reserved = _bitarray_from_string(pool_table.reserved_map)
34 34
        else:
35
            size = self.pool_table.size
36
            padding = find_padding(size)
37
            size = size + padding
38
            self.pool_size = size
39
            self.available = self._create_empty_pool()
40
            self.reserved = self._create_empty_pool()
41
            for i in xrange(0, padding):
42
                self._reserve(size - i - 1, external=True)
43

  
44
    def _create_empty_pool(self):
45
        assert(self.pool_size % 8 == 0)
46
        ba = bitarray(self.pool_size)
35
            self.available = self._create_empty_pool(self.pool_size)
36
            self.reserved = self._create_empty_pool(self.pool_size)
37
            self.add_padding(self.pool_size)
38

  
39
    def _create_empty_pool(self, size):
40
        ba = bitarray(size)
47 41
        ba.setall(AVAILABLE)
48 42
        return ba
49 43

  
44
    def add_padding(self, pool_size):
45
        bits = find_padding(pool_size)
46
        self.available.extend([AVAILABLE] * bits)
47
        self.reserved.extend([UNAVAILABLE] * bits)
48

  
49
    def cut_padding(self, pool_size):
50
        bits = find_padding(pool_size)
51
        self.available = self.available[:-bits]
52
        self.reserved = self.reserved[:-bits]
53

  
50 54
    @property
51 55
    def pool(self):
52 56
        return (self.available & self.reserved)
......
57 61
            raise EmptyPool
58 62
        # Get the first available index
59 63
        index = int(self.pool.index(AVAILABLE))
64
        assert(index < self.pool_size)
60 65
        self._reserve(index)
61 66
        return self.index_to_value(index)
62 67

  
......
85 90
        return not self.pool.any()
86 91

  
87 92
    def size(self):
93
        """Return the size of the bitarray(original size + padding)."""
88 94
        return self.pool.length()
89 95

  
90 96
    def _reserve(self, index, external=False):
......
106 112
        return self.pool.count(UNAVAILABLE)
107 113

  
108 114
    def count_reserved(self):
109
        return self.reserved.count(UNAVAILABLE)
115
        return self.reserved[:self.pool_size].count(UNAVAILABLE)
110 116

  
111 117
    def count_unreserved(self):
112
        return self.size() - self.count_reserved()
118
        return self.pool_size - self.count_reserved()
113 119

  
114 120
    def is_available(self, value, index=False):
115 121
        if not index:
......
126 132
        return self.reserved[idx] == UNAVAILABLE
127 133

  
128 134
    def to_01(self):
129
        return self.pool.to01()
135
        return self.pool[:self.pool_size].to01()
130 136

  
131 137
    def to_map(self):
132 138
        return self.to_01().replace("0", "X").replace("1", ".")
133 139

  
140
    def extend(self, bits_num):
141
        assert(bits_num >= 0)
142
        self.resize(bits_num)
143

  
144
    def shrink(self, bits_num):
145
        assert(bits_num >= 0)
146
        size = self.pool_size
147
        tmp = self.available[(size - bits_num): size]
148
        if tmp.count(UNAVAILABLE):
149
            raise Exception("Can not shrink. In use")
150
        self.resize(-bits_num)
151

  
152
    def resize(self, bits_num):
153
        if bits_num == 0:
154
            return
155
        # Cut old padding
156
        self.cut_padding(self.pool_size)
157
        # Do the resize
158
        if bits_num > 0:
159
            self.available.extend([AVAILABLE] * bits_num)
160
            self.reserved.extend([AVAILABLE] * bits_num)
161
        else:
162
            self.available = self.available[:bits_num]
163
            self.reserved = self.reserved[:bits_num]
164
        # Add new padding
165
        self.pool_size = self.pool_size + bits_num
166
        self.add_padding(self.pool_size)
167
        self.pool_table.size = self.pool_size
168

  
134 169
    def index_to_value(self, index):
135 170
        raise NotImplementedError
136 171

  
......
183 218
        do_init = False if pool_table.available_map else True
184 219
        super(MacPrefixPool, self).__init__(pool_table)
185 220
        if do_init:
186
            for i in xrange(1, self.size()):
221
            for i in xrange(1, self.pool_size):
187 222
                if not self.validate_mac(self.index_to_value(i)):
188 223
                    self._reserve(i, external=True)
189 224
            # Reserve the first mac-prefix for public-networks
......
221 256
            self._reserve(0, external=True)
222 257
            if gateway:
223 258
                self.reserve(gateway, external=True)
224
            self._reserve(self.size() - 1, external=True)
259
            self._reserve(self.pool_size - 1, external=True)
225 260

  
226 261
    def value_to_index(self, value):
227 262
        addr = ipaddr.IPAddress(value)

Also available in: Unified diff