code: def get_filtered_paths_(
      paths: Iterable[str | Path],
      filter_paths: Iterable[str | Path],
      *,
      include_within_path: bool = False,
  ) -> Iterator[str]:
      """Among paths (or Path objects) select the ones within filter_paths.
  
      All `paths` and `filter_paths` must be relative and POSIX.
  
      In case of `include_with_path=True`, if a `filter_path` points to some path
      under a `path` within `paths`, that path would be returned as well, e.g.
      `path` 'submod' would be returned if there is a `filter_path` 'submod/subsub/file'.
  
      Complexity is O(N*log(N)), where N is the largest of the lengths of `paths`
      or `filter_paths`.
  
      Yields
      ------
      paths, sorted (so order is not preserved), which reside under 'filter_paths' or
      path within 'filter_paths' is under that path.
      """
  
      # do conversion and sanity checks, O(N)
      def _harmonize_paths(
          l: Iterable[str | Path],
      ) -> list[tuple[str, ...]]:
          ps = []
          for p in l:
              pp = PurePosixPath(p)
              if pp.is_absolute():
                  raise ValueError(
                      f"Got absolute path {p}, expected relative"
                  )
              if pp.parts and pp.parts[0] == "..":
                  raise ValueError(f"Path {p} leads outside")
              ps.append(pp.parts)  # store parts
          return sorted(ps)  # O(N * log(N))
  
      paths_parts = _harmonize_paths(paths)
      filter_paths_parts = _harmonize_paths(filter_paths)
  
      # we will pretty much "scroll" through sorted paths and filter_paths at the same time
      for path_parts in paths_parts:
          while filter_paths_parts:
              filter_path_parts = filter_paths_parts[0]
              l = min(len(path_parts), len(filter_path_parts))
              # if common part is "greater" in the path -- we can go to the next "filter"
              if filter_path_parts[:l] < path_parts[:l]:
                  # get to the next one
                  filter_paths_parts = filter_paths_parts[1:]
              else:
                  break  # otherwise -- consider this one!
          else:
              # no filter path left - the other paths cannot be the selected ones
              break
          if include_within_path:
              # if one identical or subpath of another one -- their parts match in the beginning
              # and we will just reuse that 'l'
              pass
          else:
              # if all components of the filter match, for that we also add len(path_parts) check below
              l = len(filter_path_parts)
          if len(path_parts) >= l and (
              path_parts[:l] == filter_path_parts[:l]
          ):
              yield "/".join(path_parts)
  
file_path: datalad/datalad/support/path.py
imports: from __future__ import annotations
  import os
  import os.path
  from collections import defaultdict
  from collections.abc import Iterable, Iterator
  from functools import wraps
  from itertools import dropwhile
  from pathlib import Path, PurePosixPath
  from ..utils import ensure_bytes, getpwd
label_desc: Use image node_id 5 for calling a global function with example usage: get_filtered_paths_(paths, filter_paths) and returns: sorted