public void testRandomReads() throws IOException {
   int length = randomIntBetween(10, scaledRandomIntBetween(PAGE_SIZE * 2, PAGE_SIZE * 20));
   BytesReference pbr = newBytesReference(length);
   StreamInput streamInput = pbr.streamInput();
   BytesRefBuilder target = new BytesRefBuilder();
   while (target.length() < pbr.length()) {
     switch (randomIntBetween(0, 10)) {
       case 6:
       case 5:
         target.append(new BytesRef(new byte[] {streamInput.readByte()}));
         break;
       case 4:
       case 3:
         BytesRef bytesRef =
             streamInput.readBytesRef(scaledRandomIntBetween(1, pbr.length() - target.length()));
         target.append(bytesRef);
         break;
       default:
         byte[] buffer = new byte[scaledRandomIntBetween(1, pbr.length() - target.length())];
         int offset = scaledRandomIntBetween(0, buffer.length - 1);
         int read = streamInput.read(buffer, offset, buffer.length - offset);
         target.append(new BytesRef(buffer, offset, read));
         break;
     }
   }
   assertEquals(pbr.length(), target.length());
   BytesRef targetBytes = target.get();
   assertArrayEquals(
       pbr.toBytes(),
       Arrays.copyOfRange(targetBytes.bytes, targetBytes.offset, targetBytes.length));
 }
 /** Read from a stream. */
 public StoreFileMetaData(StreamInput in) throws IOException {
   name = in.readString();
   length = in.readVLong();
   checksum = in.readString();
   // TODO Why not Version.parse?
   writtenBy = Lucene.parseVersionLenient(in.readString(), FIRST_LUCENE_CHECKSUM_VERSION);
   hash = in.readBytesRef();
 }
  /**
   * Deserialize
   *
   * @param in the input
   * @throws IOException
   */
  @Override
  public void readFrom(StreamInput in) throws IOException {
    super.readFrom(in);

    isPruned = in.readBoolean();
    size = in.readVInt();
    termsEncoding = TermsByQueryRequest.TermsEncoding.values()[in.readVInt()];
    encodedTerms = in.readBytesRef();
  }
 @Override
 public void readFrom(StreamInput in) throws IOException {
   termBytes = in.readBytesRef();
   docCount = in.readVLong();
   docCountError = -1;
   if (showDocCountError) {
     docCountError = in.readLong();
   }
   aggregations = InternalAggregations.readAggregations(in);
 }
 /** Read from a stream. */
 public IncludeExclude(StreamInput in) throws IOException {
   if (in.readBoolean()) {
     includeValues = null;
     excludeValues = null;
     incZeroBasedPartition = 0;
     incNumPartitions = 0;
     String includeString = in.readOptionalString();
     include = includeString == null ? null : new RegExp(includeString);
     String excludeString = in.readOptionalString();
     exclude = excludeString == null ? null : new RegExp(excludeString);
     return;
   }
   include = null;
   exclude = null;
   if (in.readBoolean()) {
     int size = in.readVInt();
     includeValues = new TreeSet<>();
     for (int i = 0; i < size; i++) {
       includeValues.add(in.readBytesRef());
     }
   } else {
     includeValues = null;
   }
   if (in.readBoolean()) {
     int size = in.readVInt();
     excludeValues = new TreeSet<>();
     for (int i = 0; i < size; i++) {
       excludeValues.add(in.readBytesRef());
     }
   } else {
     excludeValues = null;
   }
   if (in.getVersion().onOrAfter(Version.V_5_2_0_UNRELEASED)) {
     incNumPartitions = in.readVInt();
     incZeroBasedPartition = in.readVInt();
   } else {
     incNumPartitions = 0;
     incZeroBasedPartition = 0;
   }
 }
  @Override
  public void readFrom(StreamInput in) throws IOException {
    this.setIsPruned(in.readBoolean());
    int size = in.readInt();

    bytesUsed = Counter.newCounter();
    pool = new ByteBlockPool(new ByteBlockPool.DirectTrackingAllocator(bytesUsed));
    set = new BytesRefHash(pool);

    for (long i = 0; i < size; i++) {
      set.add(in.readBytesRef());
    }
  }
 @Override
 public void readFrom(StreamInput in) throws IOException {
   super.readFrom(in);
   percolatorTypeId = in.readByte();
   requestedSize = in.readVInt();
   count = in.readVLong();
   matches = new BytesRef[in.readVInt()];
   for (int i = 0; i < matches.length; i++) {
     matches[i] = in.readBytesRef();
   }
   scores = new float[in.readVInt()];
   for (int i = 0; i < scores.length; i++) {
     scores[i] = in.readFloat();
   }
   int size = in.readVInt();
   for (int i = 0; i < size; i++) {
     int mSize = in.readVInt();
     Map<String, HighlightField> fields = new HashMap<>();
     for (int j = 0; j < mSize; j++) {
       fields.put(in.readString(), HighlightField.readHighlightField(in));
     }
     hls.add(fields);
   }
   aggregations = InternalAggregations.readOptionalAggregations(in);
   if (in.readBoolean()) {
     int pipelineAggregatorsSize = in.readVInt();
     List<SiblingPipelineAggregator> pipelineAggregators =
         new ArrayList<>(pipelineAggregatorsSize);
     for (int i = 0; i < pipelineAggregatorsSize; i++) {
       BytesReference type = in.readBytesReference();
       PipelineAggregator pipelineAggregator =
           PipelineAggregatorStreams.stream(type).readResult(in);
       pipelineAggregators.add((SiblingPipelineAggregator) pipelineAggregator);
     }
     this.pipelineAggregators = pipelineAggregators;
   }
 }
  public static TopDocs readTopDocs(StreamInput in) throws IOException {
    if (!in.readBoolean()) {
      // no docs
      return null;
    }
    if (in.readBoolean()) {
      int totalHits = in.readVInt();
      float maxScore = in.readFloat();

      SortField[] fields = new SortField[in.readVInt()];
      for (int i = 0; i < fields.length; i++) {
        String field = null;
        if (in.readBoolean()) {
          field = in.readString();
        }
        fields[i] = new SortField(field, readSortType(in), in.readBoolean());
      }

      FieldDoc[] fieldDocs = new FieldDoc[in.readVInt()];
      for (int i = 0; i < fieldDocs.length; i++) {
        Comparable[] cFields = new Comparable[in.readVInt()];
        for (int j = 0; j < cFields.length; j++) {
          byte type = in.readByte();
          if (type == 0) {
            cFields[j] = null;
          } else if (type == 1) {
            cFields[j] = in.readString();
          } else if (type == 2) {
            cFields[j] = in.readInt();
          } else if (type == 3) {
            cFields[j] = in.readLong();
          } else if (type == 4) {
            cFields[j] = in.readFloat();
          } else if (type == 5) {
            cFields[j] = in.readDouble();
          } else if (type == 6) {
            cFields[j] = in.readByte();
          } else if (type == 7) {
            cFields[j] = in.readShort();
          } else if (type == 8) {
            cFields[j] = in.readBoolean();
          } else if (type == 9) {
            cFields[j] = in.readBytesRef();
          } else {
            throw new IOException("Can't match type [" + type + "]");
          }
        }
        fieldDocs[i] = new FieldDoc(in.readVInt(), in.readFloat(), cFields);
      }
      return new TopFieldDocs(totalHits, fieldDocs, fields, maxScore);
    } else {
      int totalHits = in.readVInt();
      float maxScore = in.readFloat();

      ScoreDoc[] scoreDocs = new ScoreDoc[in.readVInt()];
      for (int i = 0; i < scoreDocs.length; i++) {
        scoreDocs[i] = new ScoreDoc(in.readVInt(), in.readFloat());
      }
      return new TopDocs(totalHits, scoreDocs, maxScore);
    }
  }