'Deletes the data and the container itself for the given container. This
will call :func:`reap_object` up to sqrt(self.concurrency) times
concurrently for the objects in the container.
If there is any exception while deleting a single object, the process
will continue for any other objects in the container and the failed
objects will be tried again the next time this function is called with
the same parameters.
If there is any exception while listing the objects for deletion, the
process will stop (but will obviously be tried again the next time this
function is called with the same parameters). This is a possibility
since the listing comes from querying just the primary remote container
server.
Once all objects have been attempted to be deleted, the container
itself will be attempted to be deleted by sending a delete request to
all container nodes. The format of the delete request is such that each
container server will update a corresponding account server, removing
the container from the account\'s listing.
This function returns nothing and should raise no exception but only
update various self.stats_* values for what occurs.
:param account: The name of the account for the container.
:param account_partition: The partition for the account on the account
ring.
:param account_nodes: The primary node dicts for the account.
:param container: The name of the container to delete.
* See also: :func:`swift.common.ring.Ring.get_nodes` for a description
of the account node dicts.'

def reap_container(self, account, account_partition, account_nodes, container):

    account_nodes = list(account_nodes)
    (part, nodes) = self.get_container_ring().get_nodes(account, container)
    node = nodes[(-1)]
    pool = GreenPool(size=self.object_concurrency)
    marker = ''
    while True:
        objects = None
        try:
            (headers, objects) = direct_get_container(node, part, account, container, marker=marker, conn_timeout=self.conn_timeout, response_timeout=self.node_timeout)
            self.stats_return_codes[2] = (self.stats_return_codes.get(2, 0) + 1)
            self.logger.increment('return_codes.2')
        except ClientException as err:
            if (self.logger.getEffectiveLevel() <= DEBUG):
                self.logger.exception(_('Exception    with    %(ip)s:%(port)s/%(device)s'), node)
            self.stats_return_codes[(err.http_status // 100)] = (self.stats_return_codes.get((err.http_status // 100), 0) + 1)
            self.logger.increment(('return_codes.%d' % ((err.http_status // 100),)))
        except (Timeout, socket.error) as err:
            self.logger.error(_('Timeout    Exception    with    %(ip)s:%(port)s/%(device)s'), node)
        if (not objects):
            break
        try:
            policy_index = headers.get('X-Backend-Storage-Policy-Index', 0)
            policy = POLICIES.get_by_index(policy_index)
            if (not policy):
                self.logger.error(('ERROR:    invalid    storage    policy    index:    %r' % policy_index))
            for obj in objects:
                if isinstance(obj['name'], six.text_type):
                    obj['name'] = obj['name'].encode('utf8')
                pool.spawn(self.reap_object, account, container, part, nodes, obj['name'], policy_index)
            pool.waitall()
        except (Exception, Timeout):
            self.logger.exception(_('Exception    with    objects    for    container    %(container)s    for    account    %(account)s'), {'container': container, 'account': account})
        marker = objects[(-1)]['name']
        if (marker == ''):
            break
    successes = 0
    failures = 0
    timestamp = Timestamp.now()
    for node in nodes:
        anode = account_nodes.pop()
        try:
            direct_delete_container(node, part, account, container, conn_timeout=self.conn_timeout, response_timeout=self.node_timeout, headers={'X-Account-Host': ('%(ip)s:%(port)s' % anode), 'X-Account-Partition': str(account_partition), 'X-Account-Device': anode['device'], 'X-Account-Override-Deleted': 'yes', 'X-Timestamp': timestamp.internal})
            successes += 1
            self.stats_return_codes[2] = (self.stats_return_codes.get(2, 0) + 1)
            self.logger.increment('return_codes.2')
        except ClientException as err:
            if (self.logger.getEffectiveLevel() <= DEBUG):
                self.logger.exception(_('Exception    with    %(ip)s:%(port)s/%(device)s'), node)
            failures += 1
            self.logger.increment('containers_failures')
            self.stats_return_codes[(err.http_status // 100)] = (self.stats_return_codes.get((err.http_status // 100), 0) + 1)
            self.logger.increment(('return_codes.%d' % ((err.http_status // 100),)))
        except (Timeout, socket.error) as err:
            self.logger.error(_('Timeout    Exception    with    %(ip)s:%(port)s/%(device)s'), node)
            failures += 1
            self.logger.increment('containers_failures')
    if (successes > failures):
        self.stats_containers_deleted += 1
        self.logger.increment('containers_deleted')
    elif (not successes):
        self.stats_containers_remaining += 1
        self.logger.increment('containers_remaining')
    else:
        self.stats_containers_possibly_remaining += 1
        self.logger.increment('containers_possibly_remaining')
