def reordered_keylist(self, allocations, new_quota): """ Creates the map for the keylist reorganzation. Each key of the returned dictionary is a resource uuid pointing to the resource uuid it should be moved to. If the allocation should not be moved they key-value is None. """ masters = [a for a in allocations if a.is_master] assert(len(masters) == 1) master = masters[0] allocations = dict(((a.resource, a) for a in allocations)) # generate the keylist (the allocation resources may be unordered) keylist = [master.resource] keylist.extend(utils.generate_uuids(master.resource, master.quota)) # prefill the map reordered = dict(((k, None) for k in keylist)) # each free allocation increases the offset by which the next key # for a non-free allocation is acquired offset = 0 for ix, key in enumerate(keylist): if allocations[key].is_available(): offset += 1 else: reordered[key] = keylist[ix - offset] return reordered
def siblings(self, imaginary=True): """Returns the master/mirrors group this allocation is part of. If 'imaginary' is true, inexistant mirrors are created on the fly. those mirrors are transient (see self.is_transient) """ # this function should always have itself in the result if not imaginary and self.is_transient: assert False, \ 'the resulting list would not contain this allocation' if self.quota == 1: assert(self.is_master) return [self] query = Session.query(Allocation) query = query.filter(Allocation.mirror_of == self.mirror_of) query = query.filter(Allocation._start == self._start) existing = dict(((e.resource, e) for e in query)) master = self.is_master and self or existing[self.mirror_of] existing[master.resource] = master uuids = utils.generate_uuids(master.resource, master.quota) imaginary = imaginary and (master.quota - len(existing)) or 0 siblings = [master] for uuid in uuids: if uuid in existing: siblings.append(existing[uuid]) elif imaginary > 0: allocation = master.copy() allocation.resource = uuid siblings.append(allocation) imaginary -= 1 return siblings