class_docstr: A simple out-of-graph Replay Buffer.
  
  Stores transitions, state, action, reward, next_state, terminal (and any
  extra contents specified) in a circular buffer and provides a uniform
  transition sampling function.
  
  When the states consist of stacks of observations storing the states is
  inefficient. This class writes observations and constructs the stacked states
  at sample time.
  
  Attributes:
    add_count: int, counter of how many transitions have been added (including
      the blank ones at the beginning of an episode).
    invalid_range: np.array, an array with the indices of cursor-related invalid
      transitions
    episode_end_indices: set[int], a set of indices corresponding to the
      end of an episode.
docstr: Returns the range of array at the index handling wraparound if necessary.
  
  Args:
    array: np.array, the array to get the stack from.
    start_index: int, index to the start of the range to be returned. Range
      will wraparound if start_index is smaller than 0.
    end_index: int, exclusive end index. Range will wraparound if end_index
      exceeds replay_capacity.
  
  Returns:
    np.array, with shape [end_index - start_index, array.shape[1:]].
docstr_tok: ["Returns","the","range","of","array","at","the","index","handling","wraparound","if","necessary",".","Args",":","array",":","np.array",",","the","array","to","get","the","stack","from",".","start_index",":","int",",","index","to","the","start","of","the","range","to","be","returned",".","Range","will","wraparound","if","start_index","is","smaller","than","0.","end_index",":","int",",","exclusive","end","index",".","Range","will","wraparound","if","end_index","exceeds","replay_capacity",".","Returns",":","np.array",",","with","shape","[","end_index","-","start_index",",","array.shape","[","1",":","]","]","."]
code: def get_range(self, array, start_index, end_index):
      """Returns the range of array at the index handling wraparound if necessary.
  
      Args:
        array: np.array, the array to get the stack from.
        start_index: int, index to the start of the range to be returned. Range
          will wraparound if start_index is smaller than 0.
        end_index: int, exclusive end index. Range will wraparound if end_index
          exceeds replay_capacity.
  
      Returns:
        np.array, with shape [end_index - start_index, array.shape[1:]].
      """
      assert (
          end_index > start_index
      ), "end_index must be larger than start_index"
      assert end_index >= 0
      assert start_index < self._replay_capacity
      if not self.is_full():
          assert (
              end_index <= self.cursor()
          ), "Index {} has not been added.".format(start_index)
  
      # Fast slice read when there is no wraparound.
      if (
          start_index % self._replay_capacity
          < end_index % self._replay_capacity
      ):
          return_array = array[start_index:end_index, ...]
      # Slow list read.
      else:
          indices = [
              (start_index + i) % self._replay_capacity
              for i in range(end_index - start_index)
          ]
          return_array = array[indices, ...]
      return return_array
  
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  import collections
  import gzip
  import math
  import os
  import pickle
  from absl import logging
  import gin.tf
  import numpy
  import tensorflow
label_desc: Use image node_id 15 for calling the OutOfGraphReplayBuffer obj's underlying member method code with example usage: obj.get_range(array, start_index, end_index) and returns: return_array