class_docstr: A minimal replay buffer used by Decision Transformer (DT)
  to process episodes into max_seq_len length segments and do shuffling.
class_docstr_tok: ["A","minimal","replay","buffer","used","by","Decision","Transformer","(","DT",")","to","process","episodes","into","max_seq_len","length","segments","and","do","shuffling","."]
code: def _add_single_episode(self, episode: SampleBatch):
      ep_len = episode.env_steps()
  
      if ep_len > self.max_ep_len:
          raise ValueError(
              f"The maximum rollout length is {self.max_ep_len} but we tried to add a"
              f"rollout of {episode.env_steps()} steps to the SegmentationBuffer."
          )
  
      # compute returns to go
      rewards = episode[SampleBatch.REWARDS].reshape(-1)
      rtg = discount_cumsum(rewards, 1.0)
      # rtg needs to be one longer than the rest for return targets during training.
      rtg = np.concatenate(
          [rtg, np.zeros((1,), dtype=np.float32)], axis=0
      )
      episode[SampleBatch.RETURNS_TO_GO] = rtg[:, None]
  
      # Add timesteps and masks
      episode[SampleBatch.T] = np.arange(ep_len, dtype=np.int32)
      episode[SampleBatch.ATTENTION_MASKS] = np.ones(
          ep_len, dtype=np.float32
      )
  
      # Add to the buffer.
      if len(self._buffer) < self.capacity:
          self._buffer.append(episode)
      else:
          # TODO: add config for sampling and eviction policies.
          replace_ind = random.randint(0, self.capacity - 1)
          self._buffer[replace_ind] = episode
  
file_path: ray/rllib_contrib/dt/src/rllib_dt/dt/segmentation_buffer.py
imports: import logging
  import random
  from collections import defaultdict
  from typing import List
  import numpy
  from ray.rllib.evaluation.postprocessing import discount_cumsum
  from ray.rllib.policy.sample_batch import MultiAgentBatch, SampleBatch, concat_samples
  from ray.rllib.utils.typing import SampleBatchType
label_desc: Use image node_id 3 for calling the SegmentationBuffer obj's underlying member method code with example usage: obj._add_single_episode(episode) without return types