'Recursively calculates the allocated value of a project
:param ctxt: context used to retrieve DB values
:param resource: the resource to calculate allocated value for
:param project_tree: the project tree used to calculate allocated
e.g. {\'A\': {\'B\': {\'D\': None}, \'C\': None}}
A project\'s "allocated" value depends on:
1) the quota limits which have been "given" to it\'s children, in
the case those limits are not unlimited (-1)
2) the current quota being used by a child plus whatever the child
has given to it\'s children, in the case of unlimited (-1) limits
Scenario #2 requires recursively calculating allocated, and in order
to efficiently calculate things we will save off any previously
calculated allocated values.
NOTE: this currently leaves a race condition when a project\'s allocated
value has been calculated (with a -1 limit), but then a child project
gets a volume created, thus changing the in-use value and messing up
the child\'s allocated value. We should look into updating the allocated
values as we\'re going along and switching to NestedQuotaDriver with
flip of a switch.'

def _get_cur_project_allocated(self, ctxt, resource, project_tree):

    cur_project_id = list(project_tree)[0]
    project_subtree = project_tree[cur_project_id]
    res_name = resource.name
    if (cur_project_id not in self._allocated):
        self._allocated[cur_project_id] = {}
    if (res_name not in self._allocated[cur_project_id]):
        cur_project_allocated = 0
        child_proj_ids = (project_subtree.keys() if project_subtree else {})
        res_dict = {res_name: resource}
        child_project_quotas = {child_id: self.get_project_quotas(ctxt, res_dict, child_id) for child_id in child_proj_ids}
        for (child_id, child_quota) in child_project_quotas.items():
            child_limit = child_quota[res_name]['limit']
            if (child_limit != (-1)):
                if (child_quota[res_name].get('in_use', 0) > child_limit):
                    msg = (_("Quota    limit    invalid    for    project    '%(proj)s'    for    resource    '%(res)s':    limit    of    %(limit)d    is    less    than    in-use    value    of    %(used)d") % {'proj': child_id, 'res': res_name, 'limit': child_limit, 'used': child_quota[res_name]['in_use']})
                    raise exception.InvalidNestedQuotaSetup(reason=msg)
                cur_project_allocated += child_limit
            else:
                child_in_use = child_quota[res_name].get('in_use', 0)
                child_alloc = self._get_cur_project_allocated(ctxt, resource, {child_id: project_subtree[child_id]})
                cur_project_allocated += (child_in_use + child_alloc)
        self._allocated[cur_project_id][res_name] = cur_project_allocated
    return self._allocated[cur_project_id][res_name]
