class_docstr: Used to zip multiple files in zip chunks of a particular size, all in parallel
class_docstr_tok: ["Used","to","zip","multiple","files","in","zip","chunks","of","a","particular","size",",","all","in","parallel"]
docstr: Generator function that returns zip files as soon as they are available.
  The zipping is done in parallel
  
  :param file_paths: List of paths to the files to zip
  :param arcnames: Dictionary that maps the file path to what should be its name in the archive.
  
  :return: Generator of ParallelZipper.ZipperObjects
docstr_tok: ["Generator","function","that","returns","zip","files","as","soon","as","they","are","available",".","The","zipping","is","done","in","parallel",":","param","file_paths",":","List","of","paths","to","the","files","to","zip",":","param","arcnames",":","Dictionary","that","maps","the","file","path","to","what","should","be","its","name","in","the","archive",".",":","return",":","Generator","of","ParallelZipper.ZipperObjects"]
code: def zip_iter(
      self,
      file_paths,  # type: List[Union[str, Path]]
      arcnames=None,  # type: Optional[dict[Union[str, Path], str]]
  ):
      # type: (...) -> Generator[ParallelZipper.ZipperObject]
      """
      Generator function that returns zip files as soon as they are available.
      The zipping is done in parallel
  
      :param file_paths: List of paths to the files to zip
      :param arcnames: Dictionary that maps the file path to what should be its name in the archive.
  
      :return: Generator of ParallelZipper.ZipperObjects
      """
      if arcnames is None:
          arcnames = dict()
  
      while not self._zipper_queue.empty():
          self._zipper_queue.get_nowait()
      for _ in range(self._max_workers):
          self._zipper_queue.put(
              ParallelZipper.ZipperObject(
                  self._chunk_size,
                  self._zipper_queue,
                  self._zipper_results,
                  self._allow_zip_64,
                  self._compression,
                  self._zip_prefix,
                  self._zip_suffix,
                  self._verbose,
                  self._task,
              )
          )
      filtered_file_paths = []
      for file_path in file_paths:
          if not Path(file_path).is_file():
              LoggerRoot.get_base_logger().warning(
                  "Could not store dataset file {}. File skipped".format(
                      file_path
                  )
              )
          else:
              filtered_file_paths.append(file_path)
      file_paths = filtered_file_paths
  
      file_paths = sorted(
          file_paths, key=lambda k: Path(k).stat().st_size, reverse=True
      )
      # zip in parallel
      pooled = []
      if not self._pool:
          pool = ThreadPoolExecutor(max_workers=self._max_workers)
      else:
          pool = self._pool
      for f in file_paths:
          zipper = self._zipper_queue.get()
          pooled.append(
              pool.submit(
                  zipper.zip,
                  Path(f).as_posix(),
                  arcname=arcnames.get(f),
              )
          )
          for result in self._yield_zipper_results():
              yield result
      for task in pooled:
          task.result()
      if not self._pool:
          pool.shutdown()
  
      for result in self._yield_zipper_results():
          yield result
  
      zipper_results_leftover = []
  
      # extract remaining results
      while not self._zipper_queue.empty():
          result = self._zipper_queue.get()
          if result.count != 0:
              zipper_results_leftover.append(result)
          else:
              result.delete()
      zipper_results_leftover = deque(
          sorted(zipper_results_leftover, reverse=True)
      )
  
      # merge zip files greedily if possible and get the paths as results
      while len(zipper_results_leftover) > 0:
          zip_ = zipper_results_leftover.pop()
          zip_.close()
          if zip_.size >= self._chunk_size > 0:
              yield zip_
              continue
          while len(zipper_results_leftover) > 0 and (
              self._chunk_size <= 0
              or zipper_results_leftover[0].size + zip_.size
              < self._chunk_size
          ):
              child_zip = zipper_results_leftover.popleft()
              child_zip.close()
              zip_.merge(child_zip)
              child_zip.delete()
          yield zip_
  
imports: import os
  from copy import deepcopy
  from time import sleep
  from concurrent.futures import ThreadPoolExecutor
  from typing import Any, Callable, Optional, Union, Generator, List, Type
  from zipfile import ZipFile, ZIP_DEFLATED
  from six.moves.queue import PriorityQueue, Queue, Empty
  from pathlib2 import Path
  from tempfile import mkstemp
  from collections import deque
  from threading import Thread
  from ..debugging.log import LoggerRoot
  from ..storage.util import format_size
label_desc: Use image node_id 2 for calling the ParallelZipper obj's underlying member method code with example usage: obj.zip_iter(file_paths, arcnames) without return types