class_docstr: Class providing all logic for managing the store in a generic way.
  
  The StoreBackend subclass has to implement 3 methods: create_location,
  clear_location and configure. The StoreBackend also has to provide
  a private _open_item, _item_exists and _move_item methods. The _open_item
  method has to have the same signature as the builtin open and return a
  file-like object.
class_docstr_tok: ["Class","providing","all","logic","for","managing","the","store","in","a","generic","way",".","The","StoreBackend","subclass","has","to","implement","3","methods",":","create_location",",","clear_location","and","configure",".","The","StoreBackend","also","has","to","provide","a","private","_open_item",",","_item_exists","and","_move_item","methods",".","The","_open_item","method","has","to","have","the","same","signature","as","the","builtin","open","and","return","a","file-like","object","."]
docstr: Get items to delete to keep the store under size, file, & age limits.
docstr_tok: ["Get","items","to","delete","to","keep","the","store","under","size",",","file",",","&","age","limits","."]
code: def _get_items_to_delete(
      self, bytes_limit, items_limit=None, age_limit=None
  ):
      """
      Get items to delete to keep the store under size, file, & age limits.
      """
      if isinstance(bytes_limit, str):
          bytes_limit = memstr_to_bytes(bytes_limit)
  
      items = self.get_items()
      size = sum(item.size for item in items)
  
      if bytes_limit is not None:
          to_delete_size = size - bytes_limit
      else:
          to_delete_size = 0
  
      if items_limit is not None:
          to_delete_items = len(items) - items_limit
      else:
          to_delete_items = 0
  
      if age_limit is not None:
          older_item = min(item.last_access for item in items)
          deadline = datetime.datetime.now() - age_limit
      else:
          deadline = None
  
      if (
          to_delete_size <= 0
          and to_delete_items <= 0
          and (deadline is None or older_item > deadline)
      ):
          return []
  
      # We want to delete first the cache items that were accessed a
      # long time ago
      items.sort(key=operator.attrgetter("last_access"))
  
      items_to_delete = []
      size_so_far = 0
      items_so_far = 0
  
      for item in items:
          if (
              (size_so_far >= to_delete_size)
              and items_so_far >= to_delete_items
              and (deadline is None or deadline < item.last_access)
          ):
              break
  
          items_to_delete.append(item)
          size_so_far += item.size
          items_so_far += 1
  
      return items_to_delete
  
imports: from pickle import PicklingError
  import re
  import os
  import os.path
  import datetime
  import json
  import shutil
  import warnings
  import collections
  import operator
  import threading
  from abc import ABCMeta, abstractmethod
  from .backports import concurrency_safe_rename
  from .disk import mkdirp, memstr_to_bytes, rm_subdirs
  from .None import numpy_pickle
label_desc: Use image node_id 15 for calling the StoreBackendMixin obj's underlying member method code with example usage: obj._get_items_to_delete(bytes_limit, items_limit, age_limit) and returns: items_to_delete, list