<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:

def cleanup(self, ctime=None):
        '''
        This method is called iteratively by the connection owning it.
        Its job is to control the size of cache and remove old entries.
        '''
        ctime = ctime or time.time()
        if self.last_cleanup:
            self.average_cleanup_time.add_point(ctime - self.last_cleanup)
        self.last_cleanup = ctime

        log.debug('couchdb', "Running cache cleanup().")
        # first remove already invalidated entries, used this iteration to
        # build up the map of usage
        expire = list()

        # [(num_accessed / time_in_cache, size, ident)]
        usage = list()

        actual_size = 0

        for ident, entry in self.iteritems():
            if entry.state is EntryState.invalid:
                expire.append(ident)
                continue
            elif entry.state is EntryState.waiting:
                continue
            else: # EntryState.ready
                actual_size += entry.size
                time_in_cache = max([ctime - entry.cached_at, 1])
                usage.append((
                    float(entry.num_accessed) / time_in_cache,
                    -entry.size,
                    ident))

        self.average_size.add_point(actual_size)

        if self.average_size.get_value() > 3 * self.desired_size:
            log.warning("couchdb", "The average size of Cache is %.2f times "
                        "bigger than the desired size of: %s. It might be "
                        "a good idea to rethink the caching strategy.",
                        self.average_size.get_value() / self.desired_size,
                        self.desired_size)

        if actual_size > self.desired_size:
            log.debug('couchdb', "I will have to cleanup some data, "
                      "the actual size is: %s, the desired limit is %s.",
                      actual_size, self.desired_size)
            # The usage list is sorted in order of things I will
            # be removing first. The important factor is "density" of usages
            # in time.
            usage.sort()
            size_to_delete = 0
            num_to_delete = 0
            while (len(usage) > 1 and
                   actual_size - size_to_delete > self.desired_size):
                _, negative_size, ident = usage.pop(0)
                size_to_delete += -negative_size
                num_to_delete += 1
                expire.append(ident)
            log.debug('couchdb', "I will remove %d entries from cache of the "
                      "size of %s to compensate the size.",
                      num_to_delete, size_to_delete)

        for ident in expire:
            del self[ident]