Exemplo n.º 1
0
    def alloc(self, value=None):
        # Allocates a index from the allocation list
        if self._in_use.all():
            idx = self._in_use.length()
            if idx > self._max_alloc:
                raise ResourceExhaustionError()
            self._in_use.append(1)
        else:
            idx = self._in_use.index(0)
            self._in_use[idx] = 1

        try:
            idx = self._get_zk_index_from_bit(idx)
        except ResourceExhaustionError as e:
            if self._in_use.all():
                self._in_use.pop(1)
            else:
                self._in_use[idx] = 0
            raise ResourceExhaustionError(str(e))

        try:
            # Create a node at path and return its integer value
            id_str = "%(#)010d" % {'#': idx}
            self._zookeeper_client.create_node(self._path + id_str, value)
            return idx
        except ResourceExistsError:
            return self.alloc(value)
Exemplo n.º 2
0
    def _alloc_from_pools(self, pools=None):
        if not pools:
            raise ResourceExhaustionError()

        if self._reverse:
            pools = list(reversed(pools))
        for pool in pools:
            last_idx = self._in_use.length() - 1
            pool_start = pool['start']
            pool_end = pool['end']
            pool_size = pool_end - pool_start + 1
            if self._reverse:
                start_zk_idx = pool_end
                end_zk_idx = pool_start
            else:
                start_zk_idx = pool_start
                end_zk_idx = pool_end
            start_bit_idx = self._get_bit_from_zk_index(start_zk_idx)
            end_bit_idx = self._get_bit_from_zk_index(end_zk_idx)

            # if bitarray is less then start_bit_index,
            # extend bit array to start_bit_idx and use that idx
            if last_idx < start_bit_idx:
                temp = bitarray(start_bit_idx - last_idx)
                temp.setall(0)
                self._in_use.extend(temp)
                self._in_use[start_bit_idx] = 1
                return start_bit_idx

            # if bitarray is in between start_bit_idx and end_bit_idx
            if last_idx >= start_bit_idx and last_idx <= end_bit_idx:
                # we need to slice part of bitarray from
                # start of the pool and end of array
                pool_bitarray = self._in_use[start_bit_idx:]
            else:
                pool_bitarray = self._in_use[
                    start_bit_idx:end_bit_idx+1]
            if pool_bitarray.all():
                if last_idx >= end_bit_idx:
                    continue
                idx = self._in_use.length()
                self._in_use.append(1)
            else:
                idx = pool_bitarray.index(0)
                idx += start_bit_idx

            self._in_use[idx] = 1
            return idx

        raise ResourceExhaustionError()
Exemplo n.º 3
0
    def _get_zk_index_from_bit(self, idx):
        size = idx
        if self._reverse:
            for alloc in reversed(self._alloc_list):
                size -= alloc['end'] - alloc['start'] + 1
                if size < 0:
                    return alloc['start'] - size - 1
        else:
            for alloc in self._alloc_list:
                size -= alloc['end'] - alloc['start'] + 1
                if size < 0:
                    return alloc['end'] + size + 1

        raise ResourceExhaustionError('Cannot get zk index from bit %s' %
                                      (idx))
Exemplo n.º 4
0
    def alloc(self, value):
        if self._in_use.all():
            idx = self._in_use.length()
            if idx > self._size:
                raise ResourceExhaustionError()
            self._in_use.append(1)
        else:
            idx = self._in_use.index(0)
            self._in_use[idx] = 1

        idx = self._get_zk_index_from_bit(idx)
        try:
            # Create a node at path and return its integer value
            id_str = "%(#)010d" % {'#': idx}
            self._disc_service.create_node(self._path + id_str, value)
            return idx
        except kazoo.exceptions.NodeExistsError:
            return self.alloc(value)