code: def _diff(
      old: "DataIndex",
      new: "DataIndex",
      *,
      granular: bool = False,
      not_in_cache: bool = False,
      not_in_remote: bool = False,
      remote_refresh: bool = False,
      callback: "Callback" = DEFAULT_CALLBACK,
  ) -> Dict[str, List[str]]:
      from dvc_data.index import StorageError
      from dvc_data.index.diff import UNCHANGED, UNKNOWN, diff
  
      ret: Dict[str, List[str]] = {}
  
      def _add_change(typ, change):
          typ = _adapt_typ(typ)
          if typ not in ret:
              ret[typ] = []
  
          ret[typ].append(_adapt_path(change))
  
      for change in diff(
          old,
          new,
          with_unchanged=True,
          shallow=not granular,
          hash_only=True,
          with_unknown=True,
          callback=callback,
      ):
          if (
              change.typ == UNCHANGED
              and (not change.old or not change.old.hash_info)
              and (not change.new or not change.new.hash_info)
          ):
              # NOTE: emulating previous behaviour
              continue
  
          if change.typ == UNKNOWN and not change.new:
              # NOTE: emulating previous behaviour
              continue
  
          if (
              not_in_cache
              and change.old
              and change.old.hash_info
              and not old.storage_map.cache_exists(change.old)
          ):
              # NOTE: emulating previous behaviour
              _add_change("not_in_cache", change)
  
          try:
              if (
                  not_in_remote
                  and change.old
                  and change.old.hash_info
                  and not old.storage_map.remote_exists(
                      change.old, refresh=remote_refresh
                  )
              ):
                  _add_change("not_in_remote", change)
          except StorageError:
              pass
  
          _add_change(change.typ, change)
  
      return ret
  
file_path: dvc/dvc/repo/data.py
imports: import os
  import posixpath
  from typing import TYPE_CHECKING, Any, Dict, Iterable, List, TypedDict, Union
  from dvc.fs.callbacks import DEFAULT_CALLBACK
  from dvc.ui import ui
label_desc: Use image node_id 4 for calling a global function with example usage: _diff(old, new) and returns: ret