class_docstr: This is a key-value store, mapping strings to tensors. The data is kept on disk,
  making this class useful as a cache for storing tensors.
  
  `TensorCache` is also safe to access from multiple processes at the same time, so
  you can use it in distributed training situations, or from multiple training
  runs at the same time.
class_docstr_tok: ["This","is","a","key-value","store",",","mapping","strings","to","tensors",".","The","data","is","kept","on","disk",",","making","this","class","useful","as","a","cache","for","storing","tensors",".","`","TensorCache","`","is","also","safe","to","access","from","multiple","processes","at","the","same","time",",","so","you","can","use","it","in","distributed","training","situations",",","or","from","multiple","training","runs","at","the","same","time","."]
docstr: Creates a `TensorCache` by either opening an existing one on disk, or creating
  a new one. Its interface is almost exactly like a Python dictionary, where the
  keys are strings and the values are `torch.Tensor`.
  
  Parameters
  ----------
  filename: `str`
      Path to the location of the cache
  map_size: `int`, optional, defaults to 1TB
      This is the maximum size the cache will ever grow to. On reasonable operating
      systems, there is no penalty to making this a large value.
      `TensorCache` uses a memory-mapped file to store the data. When the file is
      first opened, we have to give the maximum size it can ever grow to. This is
      that number. Reasonable operating systems don't actually allocate that space
      until it is really needed.
docstr_tok: ["Creates","a","`","TensorCache","`","by","either","opening","an","existing","one","on","disk",",","or","creating","a","new","one",".","Its","interface","is","almost","exactly","like","a","Python","dictionary",",","where","the","keys","are","strings","and","the","values","are","`","torch.Tensor","`",".","Parameters","--","--","--","--","--","filename",":","`","str","`","Path","to","the","location","of","the","cache","map_size",":","`","int","`",",","optional",",","defaults","to","1TB","This","is","the","maximum","size","the","cache","will","ever","grow","to",".","On","reasonable","operating","systems",",","there","is","no","penalty","to","making","this","a","large","value",".","`","TensorCache","`","uses","a","memory-mapped","file","to","store","the","data",".","When","the","file","is","first","opened",",","we","have","to","give","the","maximum","size","it","can","ever","grow","to",".","This","is","that","number",".","Reasonable","operating","systems","do","n't","actually","allocate","that","space","until","it","is","really","needed","."]
code: def __init__(
      self,
      filename: Union[str, PathLike],
      *,
      map_size: int = 1024 * 1024 * 1024 * 1024,
      read_only: bool = False,
  ) -> None:
      """
      Creates a `TensorCache` by either opening an existing one on disk, or creating
      a new one. Its interface is almost exactly like a Python dictionary, where the
      keys are strings and the values are `torch.Tensor`.
  
      Parameters
      ----------
      filename: `str`
          Path to the location of the cache
      map_size: `int`, optional, defaults to 1TB
          This is the maximum size the cache will ever grow to. On reasonable operating
          systems, there is no penalty to making this a large value.
          `TensorCache` uses a memory-mapped file to store the data. When the file is
          first opened, we have to give the maximum size it can ever grow to. This is
          that number. Reasonable operating systems don't actually allocate that space
          until it is really needed.
      """
      self.lmdb_env: lmdb.Environment
      if hasattr(self, "lmdb_env"):
          # We're being initialized again after a cache hit in _active_tensor_caches, thanks
          # to __new__. In this case, we may have to upgrade to read/write, but other than
          # that we are good to go.
          if read_only:
              return
          if not self.read_only:
              return
  
          # Upgrade a read-only lmdb env to a read/write lmdb env.
          filename = self.lmdb_env.path()
          old_info = self.lmdb_env.info()
  
          self.lmdb_env.close()
          self.lmdb_env = lmdb.open(
              filename,
              map_size=old_info["map_size"],
              subdir=False,
              metasync=False,
              sync=True,
              readahead=False,
              meminit=False,
              readonly=False,
              lock=True,
          )
      else:
          filename = str(filename)
  
          cpu_count = os.cpu_count() or 1
          if os.path.exists(filename):
              if os.path.isfile(filename):
                  # If the file is not writable, set read_only to True, but issue a warning.
                  if not os.access(filename, os.W_OK):
                      if not read_only:
                          warnings.warn(
                              f"File '{filename}' is read-only, so cache will be read-only",
                              UserWarning,
                          )
                      read_only = True
              else:
                  # If it's not a file, raise an error.
                  raise ValueError(
                      "Expect a file, found a directory instead"
                  )
  
          use_lock = True
          if read_only:
              # Check if the lock file is writable. If it's not, then we won't be able to use the lock.
  
              # This is always how lmdb names the lock file.
              lock_filename = filename + "-lock"
              if os.path.isfile(lock_filename):
                  use_lock = os.access(lock_filename, os.W_OK)
              else:
                  # If the lock file doesn't exist yet, then the directory needs to be writable in
                  # order to create and use the lock file.
                  use_lock = os.access(
                      os.path.dirname(lock_filename), os.W_OK
                  )
  
          if not use_lock:
              warnings.warn(
                  f"Lacking permissions to use lock file on cache '{filename}'.\nUse at your own risk!",
                  UserWarning,
              )
  
          self.lmdb_env = lmdb.open(
              filename,
              subdir=False,
              map_size=map_size,
              max_readers=cpu_count * 4,
              max_spare_txns=cpu_count * 4,
              metasync=False,
              sync=True,
              readahead=False,
              meminit=False,
              readonly=read_only,
              lock=use_lock,
          )
          _active_tensor_caches[_unique_file_id(filename)] = self
  
          # We have another cache here that makes sure we return the same object for the same key. Without it,
          # you would get a different tensor, using different memory, every time you call __getitem__(), even
          # if you call it with the same key.
          # The downside is that we can't keep self.cache_cache up to date when multiple processes modify the
          # cache at the same time. We can guarantee though that it is up to date as long as processes either
          # write new values, or read existing ones.
          self.cache_cache: MutableMapping[
              str, Tensor
          ] = WeakValueDictionary()
  
imports: import bz2
  import gzip
  import lzma
  import weakref
  from contextlib import contextmanager
  import glob
  import io
  import os
  import logging
  import json
  from abc import ABC
  from collections import defaultdict
  from datetime import timedelta
  from fnmatch import fnmatch
  from os import PathLike
  from pathlib import Path
  from typing import Optional, Tuple, Union, Callable, Set, List, Iterator, Iterable, Dict, NamedTuple, MutableMapping
  from weakref import WeakValueDictionary
  import shutil
  import pickle
  import time
  import warnings
  import cached_path
  from cached_path import resource_to_filename, check_tarfile, is_url_or_existing_file, find_latest_cached
  from cached_path.cache_file import CacheFile
  from cached_path.common import PathOrStr
  from cached_path.file_lock import FileLock
  from cached_path.meta import Meta
  import torch
  import numpy
  import lmdb
  from torch import Tensor
label_desc: Use image node_id 2 to create a new TensorCache object from inherited base classes: MutableMapping, ABC with example: obj = TensorCache(filename)