code: def __init__(self, cache_dir=None, max_size=None):
      self._cache_dir = cache_dir
      self._max_size = max_size
      if self._cache_dir is None:
          self._cache_dir = CLIENT_CACHE_PATH
      if self._max_size is None:
          self._max_size = int(CLIENT_CACHE_MAX_SIZE)
      self._total = 0
  
      self._objects = None
      # We have a separate blob_cache per flow and datastore type.
      self._blob_caches = {}
  
      # We also keep a cache for FlowDataStore objects because some of them
      # may have long-lived persistent connections; this is purely a
      # performance optimization. Uses OrderedDict to implement a kind of LRU
      # cache and keep only a certain number of these caches around.
      self._store_caches = OrderedDict()
  
      # We also keep a cache of data_metadata for TaskDatastore. This is used
      # when querying for sizes of artifacts. Once we have queried for the size
      # of one artifact in a TaskDatastore, caching this means that any
      # queries on that same TaskDatastore will be quick (since we already
      # have all the metadata)
      self._task_metadata_caches = OrderedDict()
  
imports: from __future__ import print_function
  from collections import OrderedDict
  import os
  import sys
  import time
  from tempfile import NamedTemporaryFile
  from hashlib import sha1
  from metaflow.datastore import FlowDataStore
  from metaflow.datastore.content_addressed_store import BlobCache
  from metaflow.exception import MetaflowException
  from metaflow.metaflow_config import CLIENT_CACHE_PATH, CLIENT_CACHE_MAX_SIZE, CLIENT_CACHE_MAX_FLOWDATASTORE_COUNT, CLIENT_CACHE_MAX_TASKDATASTORE_COUNT
  from metaflow.plugins import DATASTORES
label_desc: Use image node_id 1 to create a new FileCache object from inherited base classes: object with example: obj = FileCache(cache_dir, max_size)