code: def basic_cleanup(self):
      
      next_expire = None
      keys_to_delete = []
      if self.expire is not None and self.expire > 0:
          # cleanup invalid cache item until the meet valid cache item and record next expire time
          for k, item in self.cache_items.items():
              if item.is_dead():
                  keys_to_delete.append(k)
              else:
                  next_expire = item.remaining_survival_time()
                  break
  
      # if direct delete will to cause an error: OrderedDict mutated during iteration
      # so use delay delete
      for k in keys_to_delete:
          self.cache_items.pop(k)
  
      # if reach the upper limit of capacity then will execute evict by eviction strategy
      while (len(self.cache_items) > self.capacity):
          evicted_keys = self.evict_func(cache_dict=self.cache_items, evict_number=self.evict_number)
          self.logger.debug('Evict operation is completed, count: %s, keys: %s' % (len(evicted_keys), evicted_keys))
  
      return next_expire
docs: Test:
  
      >>> from common_cache import Cache
      >>> import time
      >>> cache = Cache(expire=1, cleanup_func=basic_cleanup, regularly_cleanup=False)
      >>> cache.put('a', value=0)
      >>> cache.put('b', value=1)
      >>> cache.put('c', value=2)
      >>> cache.put('d', value=3, expire=3)
      >>> cache.size()
      4
      >>> time.sleep(1)
      >>> cache.put('e', 4)
      >>> cache.get('a') == None
      True
      >>> cache.get('d') == None
      False