code: async def xread(self, count=None, block=None, **streams) -> dict:
          
          pieces = []
          if block is not None:
              if not isinstance(block, int) or block < 1:
                  raise RedisError("XREAD block must be a positive integer")
              pieces.append("BLOCK")
              pieces.append(str(block))
          if count is not None:
              if not isinstance(count, int) or count < 1:
                  raise RedisError("XREAD count must be a positive integer")
              pieces.append("COUNT")
              pieces.append(str(count))
          pieces.append("STREAMS")
          ids = []
          for partial_stream in streams.items():
              pieces.append(partial_stream[0])
              ids.append(partial_stream[1])
          pieces.extend(ids)
          return await self.execute_command('XREAD', *pieces)
docs: Available since 5.0.0.
  
          Time complexity:
          For each stream mentioned: O(log(N)+M) with N being the number
          of elements in the stream and M the number of elements being returned.
          If M is constant (e.g. always asking for the first 10 elements with COUNT),
          you can consider it O(log(N)). On the other side, XADD will pay the O(N)
          time in order to serve the N clients blocked on the stream getting new data.
  
          Read data from one or multiple streams,
          only returning entries with an ID greater
          than the last received ID reported by the caller.
  
          :param count: int, if set, only return this many items, beginning with the
                 earliest available.
          :param block: int, milliseconds we want to block before timing out,
                  if the BLOCK option is not used, the command is synchronous
          :param streams: stream_name - stream_id mapping
          :return dict like {stream_name: [(stream_id: entry), ...]}