class_docstr: A replay buffer that stores and can sample whole episodes.
  
  This buffer only stores valid steps, and doesn't require paths to
  have a maximum length.
  
  Args:
      capacity_in_transitions (int): Total memory allocated for the buffer.
      env_spec (EnvSpec): Environment specification.
class_docstr_tok: ["A","replay","buffer","that","stores","and","can","sample","whole","episodes",".","This","buffer","only","stores","valid","steps",",","and","does","n't","require","paths","to","have","a","maximum","length",".","Args",":","capacity_in_transitions","(","int",")",":","Total","memory","allocated","for","the","buffer",".","env_spec","(","EnvSpec",")",":","Environment","specification","."]
docstr: Add a path to the buffer.
  
  Args:
      path (dict): A dict of array of shape (path_len, flat_dim).
  
  Raises:
      ValueError: If a key is missing from path or path has wrong shape.
docstr_tok: ["Add","a","path","to","the","buffer",".","Args",":","path","(","dict",")",":","A","dict","of","array","of","shape","(","path_len",",","flat_dim",")",".","Raises",":","ValueError",":","If","a","key","is","missing","from","path","or","path","has","wrong","shape","."]
code: def add_path(self, path):
      """Add a path to the buffer.
  
      Args:
          path (dict): A dict of array of shape (path_len, flat_dim).
  
      Raises:
          ValueError: If a key is missing from path or path has wrong shape.
  
      """
      for key, buf_arr in self._buffer.items():
          path_array = path.get(key, None)
          if path_array is None:
              raise ValueError("Key {} missing from path.".format(key))
          if (
              len(path_array.shape) != 2
              or path_array.shape[1] != buf_arr.shape[1]
          ):
              raise ValueError("Array {} has wrong shape.".format(key))
      path_len = self._get_path_length(path)
      first_seg, second_seg = self._next_path_segments(path_len)
      # Remove paths which will overlap with this one.
      while self._path_segments and self._segments_overlap(
          first_seg, self._path_segments[0][0]
      ):
          self._path_segments.popleft()
      while self._path_segments and self._segments_overlap(
          second_seg, self._path_segments[0][0]
      ):
          self._path_segments.popleft()
      self._path_segments.append((first_seg, second_seg))
      for key, array in path.items():
          buf_arr = self._get_or_allocate_key(key, array)
          # numpy doesn't special case range indexing, so it's very slow.
          # Slice manually instead, which is faster than any other method.
          buf_arr[first_seg.start : first_seg.stop] = array[
              : len(first_seg)
          ]
          buf_arr[second_seg.start : second_seg.stop] = array[
              len(first_seg) :
          ]
      if second_seg.stop != 0:
          self._first_idx_of_next_path = second_seg.stop
      else:
          self._first_idx_of_next_path = first_seg.stop
      self._transitions_stored = min(
          self._capacity, self._transitions_stored + path_len
      )
  
file_path: garage/src/garage/replay_buffer/path_buffer.py
imports: import collections
  import numpy
  from garage import StepType, TimeStepBatch
label_desc: Use image node_id 3 for calling the PathBuffer obj's underlying member method code with example usage: obj.add_path(path) without return types