Remove unused Http2PriorityWriteScheduler.

PiperOrigin-RevId: 406349602
diff --git a/http2/core/http2_priority_write_scheduler.h b/http2/core/http2_priority_write_scheduler.h
deleted file mode 100644
index 4d64d75..0000000
--- a/http2/core/http2_priority_write_scheduler.h
+++ /dev/null
@@ -1,791 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef QUICHE_HTTP2_CORE_HTTP2_PRIORITY_WRITE_SCHEDULER_H_
-#define QUICHE_HTTP2_CORE_HTTP2_PRIORITY_WRITE_SCHEDULER_H_
-
-#include <cstdint>
-#include <deque>
-#include <map>
-#include <memory>
-#include <queue>
-#include <set>
-#include <string>
-#include <tuple>
-#include <unordered_map>
-#include <utility>
-#include <vector>
-
-#include "absl/container/flat_hash_map.h"
-#include "absl/strings/str_cat.h"
-#include "http2/core/write_scheduler.h"
-#include "common/platform/api/quiche_bug_tracker.h"
-#include "common/platform/api/quiche_logging.h"
-#include "spdy/core/spdy_intrusive_list.h"
-#include "spdy/core/spdy_protocol.h"
-
-namespace http2 {
-
-namespace test {
-template <typename StreamIdType>
-class Http2PriorityWriteSchedulerPeer;
-}
-
-// This data structure implements the HTTP/2 stream priority tree defined in
-// section 5.3 of RFC 7540:
-// http://tools.ietf.org/html/rfc7540#section-5.3
-//
-// Streams can be added and removed, and dependencies between them defined.
-// Streams constitute a tree rooted at stream ID 0: each stream has a single
-// parent stream, and 0 or more child streams.  Individual streams can be
-// marked as ready to read/write, and then the whole structure can be queried
-// to pick the next stream to read/write out of those that are ready.
-template <typename StreamIdType>
-class Http2PriorityWriteScheduler : public WriteScheduler<StreamIdType> {
- public:
-  using typename WriteScheduler<StreamIdType>::StreamPrecedenceType;
-
-  Http2PriorityWriteScheduler();
-  Http2PriorityWriteScheduler(const Http2PriorityWriteScheduler&) = delete;
-  Http2PriorityWriteScheduler& operator=(const Http2PriorityWriteScheduler&) =
-      delete;
-
-  // WriteScheduler methods
-  void RegisterStream(StreamIdType stream_id,
-                      const StreamPrecedenceType& precedence) override;
-  void UnregisterStream(StreamIdType stream_id) override;
-  bool StreamRegistered(StreamIdType stream_id) const override;
-  StreamPrecedenceType GetStreamPrecedence(
-      StreamIdType stream_id) const override;
-  void UpdateStreamPrecedence(StreamIdType stream_id,
-                              const StreamPrecedenceType& precedence) override;
-  std::vector<StreamIdType> GetStreamChildren(
-      StreamIdType stream_id) const override;
-  void RecordStreamEventTime(StreamIdType stream_id,
-                             int64_t now_in_usec) override;
-  int64_t GetLatestEventWithPrecedence(StreamIdType stream_id) const override;
-  bool ShouldYield(StreamIdType stream_id) const override;
-  void MarkStreamReady(StreamIdType stream_id, bool add_to_front) override;
-  void MarkStreamNotReady(StreamIdType stream_id) override;
-  bool HasReadyStreams() const override;
-  StreamIdType PopNextReadyStream() override;
-  std::tuple<StreamIdType, StreamPrecedenceType>
-  PopNextReadyStreamAndPrecedence() override;
-  size_t NumReadyStreams() const override;
-  bool IsStreamReady(StreamIdType stream_id) const override;
-  size_t NumRegisteredStreams() const override;
-  std::string DebugString() const override;
-
- private:
-  friend class test::Http2PriorityWriteSchedulerPeer<StreamIdType>;
-
-  struct StreamInfo;
-  using StreamInfoVector = absl::InlinedVector<StreamInfo*, 4>;
-
-  struct StreamInfo : public spdy::SpdyIntrusiveLink<StreamInfo> {
-    // ID for this stream.
-    StreamIdType id;
-    // StreamInfo for parent stream.
-    StreamInfo* parent = nullptr;
-    // Weights can range between 1 and 256 (inclusive).
-    int weight = spdy::kHttp2DefaultStreamWeight;
-    // The total weight of this stream's direct descendants.
-    int total_child_weights = 0;
-    // Pointers to StreamInfos for children, if any.
-    StreamInfoVector children;
-    // Whether the stream is ready for writing. The stream is present in
-    // scheduling_queue_ iff true.
-    bool ready = false;
-    // The scheduling priority of this stream. Streams with higher priority
-    // values are scheduled first.
-    // TODO(mpw): rename to avoid confusion with SPDY priorities,
-    //   which this is not.
-    float priority = 0;
-    // Ordinal value for this stream, used to ensure round-robin scheduling:
-    // among streams with the same scheduling priority, streams with lower
-    // ordinal are scheduled first.
-    int64_t ordinal = 0;
-    // Time of latest write event for stream of this priority, in microseconds.
-    int64_t last_event_time_usec = 0;
-
-    // Returns true if this stream is ancestor of |other|.
-    bool IsAncestorOf(const StreamInfo& other) const {
-      for (const StreamInfo* p = other.parent; p != nullptr; p = p->parent) {
-        if (p == this) {
-          return true;
-        }
-      }
-      return false;
-    }
-
-    // Whether this stream should be scheduled ahead of another stream.
-    bool SchedulesBefore(const StreamInfo& other) const {
-      return (priority != other.priority) ? priority > other.priority
-                                          : ordinal < other.ordinal;
-    }
-
-    // Returns the StreamPrecedenceType for this StreamInfo.
-    StreamPrecedenceType ToStreamPrecedence() const {
-      StreamIdType parent_id =
-          parent == nullptr ? spdy::kHttp2RootStreamId : parent->id;
-      bool exclusive = parent != nullptr && parent->children.size() == 1;
-      return StreamPrecedenceType(parent_id, weight, exclusive);
-    }
-  };
-
-  static bool Remove(StreamInfoVector* stream_infos,
-                     const StreamInfo* stream_info);
-
-  // Returns true iff any direct or transitive parent of the given stream is
-  // currently ready.
-  static bool HasReadyAncestor(const StreamInfo& stream_info);
-
-  // Returns StreamInfo for the given stream, or nullptr if it isn't
-  // registered.
-  const StreamInfo* FindStream(StreamIdType stream_id) const;
-  StreamInfo* FindStream(StreamIdType stream_id);
-
-  // Helpers for UpdateStreamPrecedence().
-  void UpdateStreamParent(StreamInfo* stream_info,
-                          StreamIdType parent_id,
-                          bool exclusive);
-  void UpdateStreamWeight(StreamInfo* stream_info, int weight);
-
-  // Update all priority values in the subtree rooted at the given stream, not
-  // including the stream itself. If this results in priority value changes for
-  // scheduled streams, those streams are rescheduled to ensure proper ordering
-  // of scheduling_queue_.
-  // TODO(mpw): rename to avoid confusion with SPDY priorities.
-  void UpdatePrioritiesUnder(StreamInfo* stream_info);
-
-  // Inserts stream into scheduling_queue_ at the appropriate location given
-  // its priority and ordinal. Time complexity is O(scheduling_queue.size()).
-  void Schedule(StreamInfo* stream_info);
-
-  // Removes stream from scheduling_queue_.
-  void Unschedule(StreamInfo* stream_info);
-
-  // Return true if all internal invariants hold (useful for unit tests).
-  // Unless there are bugs, this should always return true.
-  bool ValidateInvariantsForTests() const;
-
-  // Returns true if the parent stream has the given stream in its children.
-  bool StreamHasChild(const StreamInfo& parent_info,
-                      const StreamInfo* child_info) const;
-
-  // Pointee owned by all_stream_infos_.
-  StreamInfo* root_stream_info_;
-  // Maps from stream IDs to StreamInfo objects.
-  absl::flat_hash_map<StreamIdType, std::unique_ptr<StreamInfo>>
-      all_stream_infos_;
-  // Queue containing all ready streams, ordered with streams of higher
-  // priority before streams of lower priority, and, among streams of equal
-  // priority, streams with lower ordinal before those with higher
-  // ordinal. Note that not all streams in scheduling_queue_ are eligible to be
-  // picked as the next stream: some may have ancestor stream(s) that are ready
-  // and unblocked. In these situations the occluded child streams are left in
-  // the queue, to reduce churn.
-  spdy::SpdyIntrusiveList<StreamInfo> scheduling_queue_;
-  // Ordinal value to assign to next node inserted into scheduling_queue_ when
-  // |add_to_front == true|. Decremented after each assignment.
-  int64_t head_ordinal_ = -1;
-  // Ordinal value to assign to next node inserted into scheduling_queue_ when
-  // |add_to_front == false|. Incremented after each assignment.
-  int64_t tail_ordinal_ = 0;
-};
-
-template <typename StreamIdType>
-Http2PriorityWriteScheduler<StreamIdType>::Http2PriorityWriteScheduler() {
-  auto root_stream_info = std::make_unique<StreamInfo>();
-  root_stream_info_ = root_stream_info.get();
-  root_stream_info->id = spdy::kHttp2RootStreamId;
-  root_stream_info->weight = spdy::kHttp2DefaultStreamWeight;
-  root_stream_info->parent = nullptr;
-  root_stream_info->priority = 1.0;
-  root_stream_info->ready = false;
-  all_stream_infos_[spdy::kHttp2RootStreamId] = std::move(root_stream_info);
-}
-
-template <typename StreamIdType>
-bool Http2PriorityWriteScheduler<StreamIdType>::StreamRegistered(
-    StreamIdType stream_id) const {
-  return all_stream_infos_.find(stream_id) != all_stream_infos_.end();
-}
-
-template <typename StreamIdType>
-void Http2PriorityWriteScheduler<StreamIdType>::RegisterStream(
-    StreamIdType stream_id,
-    const StreamPrecedenceType& precedence) {
-  // TODO(mpw): uncomment the QUICHE_BUG_IF below once all tests
-  //   (e.g. SpdyClientDispatcher) modified to pass StreamPrecedence instances
-  //   appropriate for protocol version under test.
-  //
-  // QUICHE_BUG_IF(spdy_bug_8_1, precedence.is_spdy3_priority())
-  //     << "Expected HTTP/2 stream dependency";
-
-  if (StreamRegistered(stream_id)) {
-    QUICHE_BUG(spdy_bug_8_2) << "Stream " << stream_id << " already registered";
-    return;
-  }
-
-  StreamInfo* parent = FindStream(precedence.parent_id());
-  if (parent == nullptr) {
-    // parent_id may legitimately not be registered yet--see b/15676312.
-    QUICHE_VLOG(1) << "Parent stream " << precedence.parent_id()
-                   << " not registered";
-    parent = root_stream_info_;
-  }
-
-  auto new_stream_info = std::make_unique<StreamInfo>();
-  StreamInfo* new_stream_info_ptr = new_stream_info.get();
-  new_stream_info_ptr->id = stream_id;
-  new_stream_info_ptr->weight = precedence.weight();
-  new_stream_info_ptr->parent = parent;
-  all_stream_infos_[stream_id] = std::move(new_stream_info);
-  if (precedence.is_exclusive()) {
-    // Move the parent's current children below the new stream.
-    using std::swap;
-    swap(new_stream_info_ptr->children, parent->children);
-    new_stream_info_ptr->total_child_weights = parent->total_child_weights;
-    // Update each child's parent.
-    for (StreamInfo* child : new_stream_info_ptr->children) {
-      child->parent = new_stream_info_ptr;
-    }
-    // Clear parent's old child data.
-    QUICHE_DCHECK(parent->children.empty());
-    parent->total_child_weights = 0;
-  }
-  // Add new stream to parent.
-  parent->children.push_back(new_stream_info_ptr);
-  parent->total_child_weights += precedence.weight();
-
-  // Update all priorities under parent, since addition of a stream affects
-  // sibling priorities as well.
-  UpdatePrioritiesUnder(parent);
-
-  // Stream starts with ready == false, so no need to schedule it yet.
-  QUICHE_DCHECK(!new_stream_info_ptr->ready);
-}
-
-template <typename StreamIdType>
-void Http2PriorityWriteScheduler<StreamIdType>::UnregisterStream(
-    StreamIdType stream_id) {
-  if (stream_id == spdy::kHttp2RootStreamId) {
-    QUICHE_BUG(spdy_bug_8_3) << "Cannot unregister root stream";
-    return;
-  }
-  // Remove the stream from table.
-  auto it = all_stream_infos_.find(stream_id);
-  if (it == all_stream_infos_.end()) {
-    QUICHE_BUG(spdy_bug_8_4) << "Stream " << stream_id << " not registered";
-    return;
-  }
-  std::unique_ptr<StreamInfo> stream_info(std::move(it->second));
-  all_stream_infos_.erase(it);
-  // If ready (and hence scheduled), unschedule.
-  if (stream_info->ready) {
-    Unschedule(stream_info.get());
-  }
-
-  StreamInfo* parent = stream_info->parent;
-  // Remove the stream from parent's child list.
-  Remove(&parent->children, stream_info.get());
-  parent->total_child_weights -= stream_info->weight;
-
-  // Move the stream's children to the parent's child list.
-  // Update each child's parent and weight.
-  for (StreamInfo* child : stream_info->children) {
-    child->parent = parent;
-    parent->children.push_back(child);
-    // Divide the removed stream's weight among its children, rounding to the
-    // nearest valid weight.
-    float float_weight = stream_info->weight *
-                         static_cast<float>(child->weight) /
-                         static_cast<float>(stream_info->total_child_weights);
-    int new_weight = floor(float_weight + 0.5);
-    if (new_weight == 0) {
-      new_weight = 1;
-    }
-    child->weight = new_weight;
-    parent->total_child_weights += child->weight;
-  }
-  UpdatePrioritiesUnder(parent);
-}
-
-template <typename StreamIdType>
-typename Http2PriorityWriteScheduler<StreamIdType>::StreamPrecedenceType
-Http2PriorityWriteScheduler<StreamIdType>::GetStreamPrecedence(
-    StreamIdType stream_id) const {
-  const StreamInfo* stream_info = FindStream(stream_id);
-  if (stream_info == nullptr) {
-    // Unknown streams tolerated due to b/15676312. However, return lowest
-    // weight.
-    QUICHE_VLOG(1) << "Stream " << stream_id << " not registered";
-    return StreamPrecedenceType(spdy::kHttp2RootStreamId,
-                                spdy::kHttp2MinStreamWeight, false);
-  }
-  return stream_info->ToStreamPrecedence();
-}
-
-template <typename StreamIdType>
-std::vector<StreamIdType>
-Http2PriorityWriteScheduler<StreamIdType>::GetStreamChildren(
-    StreamIdType stream_id) const {
-  std::vector<StreamIdType> child_vec;
-  const StreamInfo* stream_info = FindStream(stream_id);
-  if (stream_info == nullptr) {
-    QUICHE_BUG(spdy_bug_8_5) << "Stream " << stream_id << " not registered";
-  } else {
-    child_vec.reserve(stream_info->children.size());
-    for (StreamInfo* child : stream_info->children) {
-      child_vec.push_back(child->id);
-    }
-  }
-  return child_vec;
-}
-
-template <typename StreamIdType>
-void Http2PriorityWriteScheduler<StreamIdType>::UpdateStreamPrecedence(
-    StreamIdType stream_id,
-    const StreamPrecedenceType& precedence) {
-  // TODO(mpw): uncomment the QUICHE_BUG_IF below once all tests
-  //   (e.g. SpdyClientDispatcher) modified to pass StreamPrecedence instances
-  //   appropriate for protocol version under test.
-  //
-  // QUICHE_BUG_IF(spdy_bug_8_6, precedence.is_spdy3_priority())
-  //     << "Expected HTTP/2 stream dependency";
-  if (stream_id == spdy::kHttp2RootStreamId) {
-    QUICHE_BUG(spdy_bug_8_7) << "Cannot set precedence of root stream";
-    return;
-  }
-
-  StreamInfo* stream_info = FindStream(stream_id);
-  if (stream_info == nullptr) {
-    // TODO(mpw): add to all_stream_infos_ on demand--see b/15676312.
-    QUICHE_VLOG(1) << "Stream " << stream_id << " not registered";
-    return;
-  }
-  UpdateStreamParent(stream_info, precedence.parent_id(),
-                     precedence.is_exclusive());
-  UpdateStreamWeight(stream_info, precedence.weight());
-}
-
-template <typename StreamIdType>
-void Http2PriorityWriteScheduler<StreamIdType>::UpdateStreamWeight(
-    StreamInfo* stream_info,
-    int weight) {
-  if (weight == stream_info->weight) {
-    return;
-  }
-  if (stream_info->parent != nullptr) {
-    stream_info->parent->total_child_weights += (weight - stream_info->weight);
-  }
-  stream_info->weight = weight;
-
-  // Change in weight also affects sibling priorities.
-  UpdatePrioritiesUnder(stream_info->parent);
-}
-
-template <typename StreamIdType>
-void Http2PriorityWriteScheduler<StreamIdType>::UpdateStreamParent(
-    StreamInfo* stream_info,
-    StreamIdType parent_id,
-    bool exclusive) {
-  if (stream_info->id == parent_id) {
-    QUICHE_BUG(spdy_bug_8_8) << "Cannot set stream to be its own parent";
-    return;
-  }
-  StreamInfo* new_parent = FindStream(parent_id);
-  if (new_parent == nullptr) {
-    // parent_id may legitimately not be registered yet--see b/15676312.
-    QUICHE_VLOG(1) << "Parent stream " << parent_id << " not registered";
-    return;
-  }
-
-  if (stream_info->parent == new_parent &&
-      (!exclusive || new_parent->children.size() == 1u)) {
-    // If the new parent is already the stream's parent, and exclusivity (if
-    // specified) is already satisfied, we are done.
-    return;
-  }
-
-  // Next, check to see if the new parent is currently a descendant
-  // of the stream.
-  StreamInfo* last = new_parent->parent;
-  bool cycle_exists = false;
-  while (last != nullptr) {
-    if (last == stream_info) {
-      cycle_exists = true;
-      break;
-    }
-    last = last->parent;
-  }
-
-  if (cycle_exists) {
-    // The new parent moves to the level of the current stream.
-    UpdateStreamParent(new_parent, stream_info->parent->id, false);
-  }
-
-  // Remove stream from old parent's child list.
-  StreamInfo* old_parent = stream_info->parent;
-  Remove(&old_parent->children, stream_info);
-  old_parent->total_child_weights -= stream_info->weight;
-  UpdatePrioritiesUnder(old_parent);
-
-  if (exclusive) {
-    // Move the new parent's current children below the current stream.
-    for (StreamInfo* child : new_parent->children) {
-      child->parent = stream_info;
-      stream_info->children.push_back(child);
-    }
-    stream_info->total_child_weights += new_parent->total_child_weights;
-    // Clear new parent's old child data.
-    new_parent->children.clear();
-    new_parent->total_child_weights = 0;
-  }
-
-  // Make the change.
-  stream_info->parent = new_parent;
-  new_parent->children.push_back(stream_info);
-  new_parent->total_child_weights += stream_info->weight;
-  UpdatePrioritiesUnder(new_parent);
-}
-
-template <typename StreamIdType>
-void Http2PriorityWriteScheduler<StreamIdType>::RecordStreamEventTime(
-    StreamIdType stream_id,
-    int64_t now_in_usec) {
-  if (stream_id == spdy::kHttp2RootStreamId) {
-    QUICHE_BUG(spdy_bug_8_9) << "Cannot record event time for root stream";
-    return;
-  }
-  StreamInfo* stream_info = FindStream(stream_id);
-  if (stream_info == nullptr) {
-    QUICHE_BUG(spdy_bug_8_10) << "Stream " << stream_id << " not registered";
-    return;
-  }
-  stream_info->last_event_time_usec = now_in_usec;
-}
-
-// O(n) in the number of streams, which isn't great. However, this method will
-// soon be superseded by
-// Http2WeightedWriteScheduler::GetLatestEventWithPrecedence(), for which an
-// efficient implementation is straightforward. Also, this method is only
-// called when calculating idle timeouts, so performance isn't key.
-template <typename StreamIdType>
-int64_t Http2PriorityWriteScheduler<StreamIdType>::GetLatestEventWithPrecedence(
-    StreamIdType stream_id) const {
-  if (stream_id == spdy::kHttp2RootStreamId) {
-    QUICHE_BUG(spdy_bug_8_11) << "Invalid argument: root stream";
-    return 0;
-  }
-  const StreamInfo* stream_info = FindStream(stream_id);
-  if (stream_info == nullptr) {
-    QUICHE_BUG(spdy_bug_8_12) << "Stream " << stream_id << " not registered";
-    return 0;
-  }
-  int64_t last_event_time_usec = 0;
-  for (const auto& kv : all_stream_infos_) {
-    const StreamInfo& other = *kv.second;
-    if (other.priority > stream_info->priority) {
-      last_event_time_usec =
-          std::max(last_event_time_usec, other.last_event_time_usec);
-    }
-  }
-  return last_event_time_usec;
-}
-
-// Worst-case time complexity of O(n*d), where n is scheduling queue length and
-// d is tree depth. In practice, should be much shorter, since loop terminates
-// at first writable stream or |stream_id| (whichever is first).
-template <typename StreamIdType>
-bool Http2PriorityWriteScheduler<StreamIdType>::ShouldYield(
-    StreamIdType stream_id) const {
-  if (stream_id == spdy::kHttp2RootStreamId) {
-    QUICHE_BUG(spdy_bug_8_13) << "Invalid argument: root stream";
-    return false;
-  }
-  const StreamInfo* stream_info = FindStream(stream_id);
-  if (stream_info == nullptr) {
-    QUICHE_BUG(spdy_bug_8_14) << "Stream " << stream_id << " not registered";
-    return false;
-  }
-  if (HasReadyAncestor(*stream_info)) {
-    return true;
-  }
-  for (const StreamInfo& scheduled : scheduling_queue_) {
-    if (HasReadyAncestor(scheduled)) {
-      // Skip streams which cannot be scheduled.
-      continue;
-    }
-    if (stream_info->IsAncestorOf(scheduled)) {
-      // Do not yield to descendants.
-      return false;
-    }
-    // Yield to streams with higher priorities.
-    return scheduled.SchedulesBefore(*stream_info);
-  }
-  return false;
-}
-
-template <typename StreamIdType>
-void Http2PriorityWriteScheduler<StreamIdType>::MarkStreamReady(
-    StreamIdType stream_id,
-    bool add_to_front) {
-  if (stream_id == spdy::kHttp2RootStreamId) {
-    QUICHE_BUG(spdy_bug_8_15) << "Cannot mark root stream ready";
-    return;
-  }
-  StreamInfo* stream_info = FindStream(stream_id);
-  if (stream_info == nullptr) {
-    QUICHE_BUG(spdy_bug_8_16) << "Stream " << stream_id << " not registered";
-    return;
-  }
-  if (stream_info->ready) {
-    return;
-  }
-  stream_info->ordinal = add_to_front ? head_ordinal_-- : tail_ordinal_++;
-  Schedule(stream_info);
-}
-
-template <typename StreamIdType>
-void Http2PriorityWriteScheduler<StreamIdType>::MarkStreamNotReady(
-    StreamIdType stream_id) {
-  if (stream_id == spdy::kHttp2RootStreamId) {
-    QUICHE_BUG(spdy_bug_8_17) << "Cannot mark root stream unready";
-    return;
-  }
-  StreamInfo* stream_info = FindStream(stream_id);
-  if (stream_info == nullptr) {
-    QUICHE_BUG(spdy_bug_8_18) << "Stream " << stream_id << " not registered";
-    return;
-  }
-  if (!stream_info->ready) {
-    return;
-  }
-  Unschedule(stream_info);
-}
-
-template <typename StreamIdType>
-bool Http2PriorityWriteScheduler<StreamIdType>::Remove(
-    StreamInfoVector* stream_infos,
-    const StreamInfo* stream_info) {
-  for (typename StreamInfoVector::iterator it = stream_infos->begin();
-       it != stream_infos->end(); ++it) {
-    if (*it == stream_info) {
-      stream_infos->erase(it);
-      return true;
-    }
-  }
-  return false;
-}
-
-template <typename StreamIdType>
-bool Http2PriorityWriteScheduler<StreamIdType>::HasReadyAncestor(
-    const StreamInfo& stream_info) {
-  for (const StreamInfo* parent = stream_info.parent; parent != nullptr;
-       parent = parent->parent) {
-    if (parent->ready) {
-      return true;
-    }
-  }
-  return false;
-}
-
-template <typename StreamIdType>
-const typename Http2PriorityWriteScheduler<StreamIdType>::StreamInfo*
-Http2PriorityWriteScheduler<StreamIdType>::FindStream(
-    StreamIdType stream_id) const {
-  auto it = all_stream_infos_.find(stream_id);
-  return it == all_stream_infos_.end() ? nullptr : it->second.get();
-}
-
-template <typename StreamIdType>
-typename Http2PriorityWriteScheduler<StreamIdType>::StreamInfo*
-Http2PriorityWriteScheduler<StreamIdType>::FindStream(StreamIdType stream_id) {
-  auto it = all_stream_infos_.find(stream_id);
-  return it == all_stream_infos_.end() ? nullptr : it->second.get();
-}
-
-template <typename StreamIdType>
-void Http2PriorityWriteScheduler<StreamIdType>::UpdatePrioritiesUnder(
-    StreamInfo* stream_info) {
-  for (StreamInfo* child : stream_info->children) {
-    child->priority = stream_info->priority *
-                      (static_cast<float>(child->weight) /
-                       static_cast<float>(stream_info->total_child_weights));
-    if (child->ready) {
-      // Reposition in scheduling_queue_. Use post-order for scheduling, to
-      // benefit from the fact that children have priority <= parent priority.
-      Unschedule(child);
-      UpdatePrioritiesUnder(child);
-      Schedule(child);
-    } else {
-      UpdatePrioritiesUnder(child);
-    }
-  }
-}
-
-template <typename StreamIdType>
-void Http2PriorityWriteScheduler<StreamIdType>::Schedule(
-    StreamInfo* stream_info) {
-  QUICHE_DCHECK(!stream_info->ready);
-  for (StreamInfo& s : scheduling_queue_) {
-    if (stream_info->SchedulesBefore(s)) {
-      scheduling_queue_.insert(&s, stream_info);
-      stream_info->ready = true;
-      return;
-    }
-  }
-  scheduling_queue_.push_back(stream_info);
-  stream_info->ready = true;
-}
-
-template <typename StreamIdType>
-void Http2PriorityWriteScheduler<StreamIdType>::Unschedule(
-    StreamInfo* stream_info) {
-  QUICHE_DCHECK(stream_info->ready);
-  scheduling_queue_.erase(stream_info);
-  stream_info->ready = false;
-}
-
-template <typename StreamIdType>
-bool Http2PriorityWriteScheduler<StreamIdType>::StreamHasChild(
-    const StreamInfo& parent_info,
-    const StreamInfo* child_info) const {
-  auto found = std::find(parent_info.children.begin(),
-                         parent_info.children.end(), child_info);
-  return found != parent_info.children.end();
-}
-
-template <typename StreamIdType>
-bool Http2PriorityWriteScheduler<StreamIdType>::HasReadyStreams() const {
-  return !scheduling_queue_.empty();
-}
-
-template <typename StreamIdType>
-StreamIdType Http2PriorityWriteScheduler<StreamIdType>::PopNextReadyStream() {
-  return std::get<0>(PopNextReadyStreamAndPrecedence());
-}
-
-template <typename StreamIdType>
-std::tuple<
-    StreamIdType,
-    typename Http2PriorityWriteScheduler<StreamIdType>::StreamPrecedenceType>
-Http2PriorityWriteScheduler<StreamIdType>::PopNextReadyStreamAndPrecedence() {
-  for (StreamInfo& stream_info : scheduling_queue_) {
-    if (!HasReadyAncestor(stream_info)) {
-      Unschedule(&stream_info);
-      return std::make_tuple(stream_info.id, stream_info.ToStreamPrecedence());
-    }
-  }
-  QUICHE_BUG(spdy_bug_8_19) << "No ready streams";
-  return std::make_tuple(
-      spdy::kHttp2RootStreamId,
-      StreamPrecedenceType(spdy::kHttp2RootStreamId,
-                           spdy::kHttp2MinStreamWeight, false));
-}
-
-template <typename StreamIdType>
-size_t Http2PriorityWriteScheduler<StreamIdType>::NumReadyStreams() const {
-  return scheduling_queue_.size();
-}
-
-template <typename StreamIdType>
-bool Http2PriorityWriteScheduler<StreamIdType>::IsStreamReady(
-    StreamIdType stream_id) const {
-  if (stream_id == spdy::kHttp2RootStreamId) {
-    QUICHE_BUG(spdy_bug_8_20) << "Try to check whether root stream is ready";
-    return false;
-  }
-  const StreamInfo* stream_info = FindStream(stream_id);
-  if (stream_info == nullptr) {
-    QUICHE_BUG(spdy_bug_8_21) << "Stream " << stream_id << " not registered";
-    return false;
-  }
-  return stream_info->ready;
-}
-
-template <typename StreamIdType>
-size_t Http2PriorityWriteScheduler<StreamIdType>::NumRegisteredStreams() const {
-  return all_stream_infos_.size();
-}
-
-template <typename StreamIdType>
-std::string Http2PriorityWriteScheduler<StreamIdType>::DebugString() const {
-  return absl::StrCat("Http2PriorityWriteScheduler {num_registered_streams=",
-                      NumRegisteredStreams(),
-                      " num_ready_streams=", NumReadyStreams(), "}");
-}
-
-template <typename StreamIdType>
-bool Http2PriorityWriteScheduler<StreamIdType>::ValidateInvariantsForTests()
-    const {
-  size_t total_streams = 0;
-  size_t streams_visited = 0;
-  // Iterate through all streams in the map.
-  for (const auto& kv : all_stream_infos_) {
-    ++total_streams;
-    ++streams_visited;
-    StreamIdType stream_id = kv.first;
-    const StreamInfo& stream_info = *kv.second;
-
-    // Verify each StreamInfo mapped under the proper stream ID.
-    if (stream_id != stream_info.id) {
-      QUICHE_DLOG(INFO) << "Stream ID " << stream_id
-                        << " maps to StreamInfo with ID " << stream_info.id;
-      return false;
-    }
-
-    // All streams except the root should have a parent, and should appear in
-    // the children of that parent.
-    if (stream_info.id != spdy::kHttp2RootStreamId &&
-        !StreamHasChild(*stream_info.parent, &stream_info)) {
-      QUICHE_DLOG(INFO) << "Parent stream " << stream_info.parent->id
-                        << " is not registered, or does not list stream "
-                        << stream_info.id << " as its child.";
-      return false;
-    }
-
-    if (!stream_info.children.empty()) {
-      int total_child_weights = 0;
-      // Iterate through the stream's children.
-      for (StreamInfo* child : stream_info.children) {
-        ++streams_visited;
-        // Each stream in the list should exist and should have this stream
-        // set as its parent.
-        if (!StreamRegistered(child->id) || child->parent != &stream_info) {
-          QUICHE_DLOG(INFO)
-              << "Child stream " << child->id << " is not registered, "
-              << "or does not list " << stream_info.id << " as its parent.";
-          return false;
-        }
-        total_child_weights += child->weight;
-      }
-      // Verify that total_child_weights is correct.
-      if (total_child_weights != stream_info.total_child_weights) {
-        QUICHE_DLOG(INFO) << "Child weight totals do not agree. For stream "
-                          << stream_info.id << " total_child_weights has value "
-                          << stream_info.total_child_weights << ", expected "
-                          << total_child_weights;
-        return false;
-      }
-    }
-  }
-
-  // Make sure NumRegisteredStreams() reflects the total number of streams the
-  // map contains.
-  if (total_streams != NumRegisteredStreams()) {
-    QUICHE_DLOG(INFO) << "Map contains incorrect number of streams.";
-    return false;
-  }
-  // Validate the validation function; we should have visited each stream twice
-  // (except for the root)
-  QUICHE_DCHECK(streams_visited == 2 * NumRegisteredStreams() - 1);
-  return true;
-}
-
-}  // namespace http2
-
-#endif  // QUICHE_HTTP2_CORE_HTTP2_PRIORITY_WRITE_SCHEDULER_H_
diff --git a/http2/core/http2_priority_write_scheduler_test.cc b/http2/core/http2_priority_write_scheduler_test.cc
deleted file mode 100644
index 7f08619..0000000
--- a/http2/core/http2_priority_write_scheduler_test.cc
+++ /dev/null
@@ -1,970 +0,0 @@
-// Copyright (c) 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "http2/core/http2_priority_write_scheduler.h"
-
-#include <initializer_list>
-
-#include "common/platform/api/quiche_test.h"
-#include "common/platform/api/quiche_test_helpers.h"
-
-using ::testing::AssertionFailure;
-using ::testing::AssertionResult;
-using ::testing::AssertionSuccess;
-using ::testing::ElementsAre;
-using ::testing::IsEmpty;
-using ::testing::UnorderedElementsAre;
-
-namespace http2 {
-namespace test {
-
-using ::spdy::kHttp2MaxStreamWeight;
-using ::spdy::kHttp2MinStreamWeight;
-using ::spdy::kHttp2RootStreamId;
-using ::spdy::kV3LowestPriority;
-using ::spdy::SpdyStreamPrecedence;
-
-template <typename StreamIdType>
-class Http2PriorityWriteSchedulerPeer {
- public:
-  explicit Http2PriorityWriteSchedulerPeer(
-      Http2PriorityWriteScheduler<StreamIdType>* scheduler)
-      : scheduler_(scheduler) {}
-
-  int TotalChildWeights(StreamIdType stream_id) const {
-    return scheduler_->FindStream(stream_id)->total_child_weights;
-  }
-
-  bool ValidateInvariants() const {
-    return scheduler_->ValidateInvariantsForTests();
-  }
-
- private:
-  Http2PriorityWriteScheduler<StreamIdType>* scheduler_;
-};
-
-class Http2PriorityWriteSchedulerTest : public QuicheTest {
- protected:
-  typedef uint32_t SpdyStreamId;
-
-  Http2PriorityWriteSchedulerTest() : peer_(&scheduler_) {}
-
-  Http2PriorityWriteScheduler<SpdyStreamId> scheduler_;
-  Http2PriorityWriteSchedulerPeer<SpdyStreamId> peer_;
-};
-
-TEST_F(Http2PriorityWriteSchedulerTest, RegisterAndUnregisterStreams) {
-  EXPECT_EQ(1u, scheduler_.NumRegisteredStreams());
-  EXPECT_TRUE(scheduler_.StreamRegistered(0));
-  EXPECT_FALSE(scheduler_.StreamRegistered(1));
-
-  scheduler_.RegisterStream(1, SpdyStreamPrecedence(0, 100, false));
-  EXPECT_EQ(2u, scheduler_.NumRegisteredStreams());
-  ASSERT_TRUE(scheduler_.StreamRegistered(1));
-  EXPECT_EQ(100, scheduler_.GetStreamPrecedence(1).weight());
-  EXPECT_FALSE(scheduler_.StreamRegistered(5));
-  EXPECT_THAT(scheduler_.GetStreamChildren(0), ElementsAre(1));
-
-  scheduler_.RegisterStream(5, SpdyStreamPrecedence(0, 50, false));
-  // Should not be able to add a stream with an id that already exists.
-  EXPECT_QUICHE_BUG(
-      scheduler_.RegisterStream(5, SpdyStreamPrecedence(1, 50, false)),
-      "Stream 5 already registered");
-  EXPECT_EQ(3u, scheduler_.NumRegisteredStreams());
-  EXPECT_TRUE(scheduler_.StreamRegistered(1));
-  ASSERT_TRUE(scheduler_.StreamRegistered(5));
-  EXPECT_EQ(50, scheduler_.GetStreamPrecedence(5).weight());
-  EXPECT_FALSE(scheduler_.StreamRegistered(13));
-
-  scheduler_.RegisterStream(13, SpdyStreamPrecedence(5, 130, true));
-  EXPECT_EQ(4u, scheduler_.NumRegisteredStreams());
-  EXPECT_TRUE(scheduler_.StreamRegistered(1));
-  EXPECT_TRUE(scheduler_.StreamRegistered(5));
-  ASSERT_TRUE(scheduler_.StreamRegistered(13));
-  EXPECT_EQ(130, scheduler_.GetStreamPrecedence(13).weight());
-  EXPECT_EQ(5u, scheduler_.GetStreamPrecedence(13).parent_id());
-
-  scheduler_.UnregisterStream(5);
-  // Cannot remove a stream that has already been removed.
-  EXPECT_QUICHE_BUG(scheduler_.UnregisterStream(5), "Stream 5 not registered");
-  EXPECT_EQ(3u, scheduler_.NumRegisteredStreams());
-  EXPECT_TRUE(scheduler_.StreamRegistered(1));
-  EXPECT_FALSE(scheduler_.StreamRegistered(5));
-  EXPECT_TRUE(scheduler_.StreamRegistered(13));
-  EXPECT_EQ(kHttp2RootStreamId, scheduler_.GetStreamPrecedence(13).parent_id());
-
-  // The parent stream 19 doesn't exist, so this should use 0 as parent stream:
-  scheduler_.RegisterStream(7, SpdyStreamPrecedence(19, 70, false));
-  EXPECT_TRUE(scheduler_.StreamRegistered(7));
-  EXPECT_EQ(0u, scheduler_.GetStreamPrecedence(7).parent_id());
-  // Now stream 7 already exists, so this should fail:
-  EXPECT_QUICHE_BUG(
-      scheduler_.RegisterStream(7, SpdyStreamPrecedence(1, 70, false)),
-      "Stream 7 already registered");
-  // Try adding a second child to stream 13:
-  scheduler_.RegisterStream(17, SpdyStreamPrecedence(13, 170, false));
-
-  scheduler_.UpdateStreamPrecedence(17, SpdyStreamPrecedence(13, 150, false));
-  EXPECT_EQ(150, scheduler_.GetStreamPrecedence(17).weight());
-
-  ASSERT_TRUE(peer_.ValidateInvariants());
-}
-
-TEST_F(Http2PriorityWriteSchedulerTest, RegisterStreamWithSpdy3Priority) {
-  EXPECT_FALSE(scheduler_.StreamRegistered(1));
-  scheduler_.RegisterStream(1, SpdyStreamPrecedence(3));
-  EXPECT_EQ(0u, scheduler_.NumReadyStreams());
-  EXPECT_TRUE(scheduler_.StreamRegistered(1));
-  EXPECT_EQ(3, scheduler_.GetStreamPrecedence(1).spdy3_priority());
-  EXPECT_EQ(147, scheduler_.GetStreamPrecedence(1).weight());
-  EXPECT_EQ(kHttp2RootStreamId, scheduler_.GetStreamPrecedence(1).parent_id());
-  EXPECT_THAT(scheduler_.GetStreamChildren(1), IsEmpty());
-
-  EXPECT_QUICHE_BUG(scheduler_.RegisterStream(1, SpdyStreamPrecedence(4)),
-                    "Stream 1 already registered");
-  EXPECT_EQ(3, scheduler_.GetStreamPrecedence(1).spdy3_priority());
-}
-
-TEST_F(Http2PriorityWriteSchedulerTest, GetStreamWeight) {
-  // Unknown streams tolerated due to b/15676312.
-  EXPECT_EQ(kHttp2MinStreamWeight, scheduler_.GetStreamPrecedence(3).weight());
-  scheduler_.RegisterStream(3, SpdyStreamPrecedence(0, 130, true));
-  EXPECT_EQ(130, scheduler_.GetStreamPrecedence(3).weight());
-  scheduler_.UpdateStreamPrecedence(3, SpdyStreamPrecedence(0, 50, true));
-  EXPECT_EQ(50, scheduler_.GetStreamPrecedence(3).weight());
-  scheduler_.UnregisterStream(3);
-  EXPECT_EQ(kHttp2MinStreamWeight, scheduler_.GetStreamPrecedence(3).weight());
-}
-
-TEST_F(Http2PriorityWriteSchedulerTest, GetStreamPriority) {
-  // Unknown streams tolerated due to b/15676312.
-  EXPECT_EQ(kV3LowestPriority,
-            scheduler_.GetStreamPrecedence(3).spdy3_priority());
-  scheduler_.RegisterStream(3, SpdyStreamPrecedence(0, 130, true));
-  EXPECT_EQ(3, scheduler_.GetStreamPrecedence(3).spdy3_priority());
-  scheduler_.UpdateStreamPrecedence(3, SpdyStreamPrecedence(0, 50, true));
-  EXPECT_EQ(5, scheduler_.GetStreamPrecedence(3).spdy3_priority());
-  scheduler_.UnregisterStream(3);
-  EXPECT_EQ(kV3LowestPriority,
-            scheduler_.GetStreamPrecedence(3).spdy3_priority());
-}
-
-TEST_F(Http2PriorityWriteSchedulerTest, GetStreamParent) {
-  // Unknown streams tolerated due to b/15676312.
-  EXPECT_EQ(kHttp2RootStreamId, scheduler_.GetStreamPrecedence(3).parent_id());
-  scheduler_.RegisterStream(2, SpdyStreamPrecedence(0, 20, false));
-  scheduler_.RegisterStream(3, SpdyStreamPrecedence(2, 30, false));
-  EXPECT_EQ(2u, scheduler_.GetStreamPrecedence(3).parent_id());
-  scheduler_.UnregisterStream(3);
-  EXPECT_EQ(kHttp2RootStreamId, scheduler_.GetStreamPrecedence(3).parent_id());
-}
-
-TEST_F(Http2PriorityWriteSchedulerTest, GetStreamChildren) {
-  EXPECT_QUICHE_BUG(EXPECT_THAT(scheduler_.GetStreamChildren(7), IsEmpty()),
-                    "Stream 7 not registered");
-  scheduler_.RegisterStream(7, SpdyStreamPrecedence(0, 70, false));
-  EXPECT_THAT(scheduler_.GetStreamChildren(7), IsEmpty());
-  scheduler_.RegisterStream(9, SpdyStreamPrecedence(7, 90, false));
-  scheduler_.RegisterStream(15, SpdyStreamPrecedence(7, 150, false));
-  EXPECT_THAT(scheduler_.GetStreamChildren(7), UnorderedElementsAre(9, 15));
-  scheduler_.UnregisterStream(7);
-  EXPECT_QUICHE_BUG(EXPECT_THAT(scheduler_.GetStreamChildren(7), IsEmpty()),
-                    "Stream 7 not registered");
-}
-
-TEST_F(Http2PriorityWriteSchedulerTest, UpdateStreamWeight) {
-  EXPECT_QUICHE_BUG(
-      scheduler_.UpdateStreamPrecedence(0, SpdyStreamPrecedence(0, 10, false)),
-      "Cannot set precedence of root stream");
-
-  // For the moment, updating stream precedence on a non-registered stream
-  // should have no effect. In the future, it will lazily cause the stream to
-  // be registered (b/15676312).
-  scheduler_.UpdateStreamPrecedence(3, SpdyStreamPrecedence(0, 10, false));
-  EXPECT_FALSE(scheduler_.StreamRegistered(3));
-
-  scheduler_.RegisterStream(3, SpdyStreamPrecedence(0, 10, false));
-  scheduler_.UpdateStreamPrecedence(3, SpdyStreamPrecedence(0, 20, false));
-  EXPECT_EQ(20, scheduler_.GetStreamPrecedence(3).weight());
-  ASSERT_TRUE(peer_.ValidateInvariants());
-
-  EXPECT_QUICHE_BUG(
-      scheduler_.UpdateStreamPrecedence(3, SpdyStreamPrecedence(0, 500, false)),
-      "Invalid weight: 500");
-  EXPECT_EQ(kHttp2MaxStreamWeight, scheduler_.GetStreamPrecedence(3).weight());
-  EXPECT_QUICHE_BUG(
-      scheduler_.UpdateStreamPrecedence(3, SpdyStreamPrecedence(0, 0, false)),
-      "Invalid weight: 0");
-  EXPECT_EQ(kHttp2MinStreamWeight, scheduler_.GetStreamPrecedence(3).weight());
-  ASSERT_TRUE(peer_.ValidateInvariants());
-
-  scheduler_.UnregisterStream(3);
-}
-
-// Basic case of reparenting a subtree.
-TEST_F(Http2PriorityWriteSchedulerTest, UpdateStreamParentBasicNonExclusive) {
-  /* Tree:
-        0
-       / \
-      1   2
-     / \
-    3   4
-   */
-  scheduler_.RegisterStream(1, SpdyStreamPrecedence(0, 100, false));
-  scheduler_.RegisterStream(2, SpdyStreamPrecedence(0, 100, false));
-  scheduler_.RegisterStream(3, SpdyStreamPrecedence(1, 100, false));
-  scheduler_.RegisterStream(4, SpdyStreamPrecedence(1, 100, false));
-  scheduler_.UpdateStreamPrecedence(1, SpdyStreamPrecedence(2, 100, false));
-  EXPECT_THAT(scheduler_.GetStreamChildren(0), ElementsAre(2));
-  EXPECT_THAT(scheduler_.GetStreamChildren(1), UnorderedElementsAre(3, 4));
-  EXPECT_THAT(scheduler_.GetStreamChildren(2), ElementsAre(1));
-  EXPECT_THAT(scheduler_.GetStreamChildren(3), IsEmpty());
-  EXPECT_THAT(scheduler_.GetStreamChildren(4), IsEmpty());
-  ASSERT_TRUE(peer_.ValidateInvariants());
-}
-
-// Basic case of reparenting a subtree.  Result here is the same as the
-// non-exclusive case.
-TEST_F(Http2PriorityWriteSchedulerTest, UpdateStreamParentBasicExclusive) {
-  /* Tree:
-        0
-       / \
-      1   2
-     / \
-    3   4
-   */
-  scheduler_.RegisterStream(1, SpdyStreamPrecedence(0, 100, false));
-  scheduler_.RegisterStream(2, SpdyStreamPrecedence(0, 100, false));
-  scheduler_.RegisterStream(3, SpdyStreamPrecedence(1, 100, false));
-  scheduler_.RegisterStream(4, SpdyStreamPrecedence(1, 100, false));
-  scheduler_.UpdateStreamPrecedence(1, SpdyStreamPrecedence(2, 100, true));
-  EXPECT_THAT(scheduler_.GetStreamChildren(0), ElementsAre(2));
-  EXPECT_THAT(scheduler_.GetStreamChildren(1), UnorderedElementsAre(3, 4));
-  EXPECT_THAT(scheduler_.GetStreamChildren(2), ElementsAre(1));
-  EXPECT_THAT(scheduler_.GetStreamChildren(3), IsEmpty());
-  EXPECT_THAT(scheduler_.GetStreamChildren(4), IsEmpty());
-  ASSERT_TRUE(peer_.ValidateInvariants());
-}
-
-// We can't set the parent of a nonexistent stream, or set the parent to a
-// nonexistent stream.
-TEST_F(Http2PriorityWriteSchedulerTest, UpdateStreamParentNonexistent) {
-  scheduler_.RegisterStream(1, SpdyStreamPrecedence(0, 100, false));
-  scheduler_.RegisterStream(2, SpdyStreamPrecedence(0, 100, false));
-  for (bool exclusive : {true, false}) {
-    // For the moment, updating stream precedence on a non-registered stream or
-    // attempting to set parent to a nonexistent stream should have no
-    // effect. In the future, it will lazily cause the stream(s) to be
-    // registered (b/15676312).
-
-    // No-op: parent stream 3 not registered
-    scheduler_.UpdateStreamPrecedence(1,
-                                      SpdyStreamPrecedence(3, 100, exclusive));
-
-    // No-op: stream 4 not registered
-    scheduler_.UpdateStreamPrecedence(4,
-                                      SpdyStreamPrecedence(2, 100, exclusive));
-
-    // No-op: stream 3 not registered
-    scheduler_.UpdateStreamPrecedence(3,
-                                      SpdyStreamPrecedence(4, 100, exclusive));
-
-    EXPECT_THAT(scheduler_.GetStreamChildren(0), UnorderedElementsAre(1, 2));
-    EXPECT_THAT(scheduler_.GetStreamChildren(1), IsEmpty());
-    EXPECT_THAT(scheduler_.GetStreamChildren(2), IsEmpty());
-    EXPECT_FALSE(scheduler_.StreamRegistered(3));
-    EXPECT_FALSE(scheduler_.StreamRegistered(4));
-  }
-  ASSERT_TRUE(peer_.ValidateInvariants());
-}
-
-// We should be able to add multiple children to streams.
-TEST_F(Http2PriorityWriteSchedulerTest,
-       UpdateStreamParentMultipleChildrenNonExclusive) {
-  /* Tree:
-        0
-       / \
-      1   2
-     / \   \
-    3   4   5
-   */
-  scheduler_.RegisterStream(1, SpdyStreamPrecedence(0, 100, false));
-  scheduler_.RegisterStream(2, SpdyStreamPrecedence(0, 100, false));
-  scheduler_.RegisterStream(3, SpdyStreamPrecedence(1, 100, false));
-  scheduler_.RegisterStream(4, SpdyStreamPrecedence(1, 100, false));
-  scheduler_.RegisterStream(5, SpdyStreamPrecedence(2, 100, false));
-  scheduler_.UpdateStreamPrecedence(2, SpdyStreamPrecedence(1, 100, false));
-  EXPECT_THAT(scheduler_.GetStreamChildren(0), ElementsAre(1));
-  EXPECT_THAT(scheduler_.GetStreamChildren(1), UnorderedElementsAre(2, 3, 4));
-  EXPECT_THAT(scheduler_.GetStreamChildren(2), ElementsAre(5));
-  EXPECT_THAT(scheduler_.GetStreamChildren(3), IsEmpty());
-  EXPECT_THAT(scheduler_.GetStreamChildren(4), IsEmpty());
-  EXPECT_THAT(scheduler_.GetStreamChildren(5), IsEmpty());
-  ASSERT_TRUE(peer_.ValidateInvariants());
-}
-
-TEST_F(Http2PriorityWriteSchedulerTest,
-       UpdateStreamParentMultipleChildrenExclusive) {
-  /* Tree:
-        0
-       / \
-      1   2
-     / \   \
-    3   4   5
-   */
-  scheduler_.RegisterStream(1, SpdyStreamPrecedence(0, 100, false));
-  scheduler_.RegisterStream(2, SpdyStreamPrecedence(0, 100, false));
-  scheduler_.RegisterStream(3, SpdyStreamPrecedence(1, 100, false));
-  scheduler_.RegisterStream(4, SpdyStreamPrecedence(1, 100, false));
-  scheduler_.RegisterStream(5, SpdyStreamPrecedence(2, 100, false));
-  scheduler_.UpdateStreamPrecedence(2, SpdyStreamPrecedence(1, 100, true));
-  EXPECT_THAT(scheduler_.GetStreamChildren(0), ElementsAre(1));
-  EXPECT_THAT(scheduler_.GetStreamChildren(1), ElementsAre(2));
-  EXPECT_THAT(scheduler_.GetStreamChildren(2), UnorderedElementsAre(3, 4, 5));
-  EXPECT_THAT(scheduler_.GetStreamChildren(3), IsEmpty());
-  EXPECT_THAT(scheduler_.GetStreamChildren(4), IsEmpty());
-  EXPECT_THAT(scheduler_.GetStreamChildren(5), IsEmpty());
-  ASSERT_TRUE(peer_.ValidateInvariants());
-}
-
-TEST_F(Http2PriorityWriteSchedulerTest, UpdateStreamParentToChildNonExclusive) {
-  /* Tree:
-        0
-        |
-        1
-       / \
-      2   3
-      |
-      4
-   */
-  scheduler_.RegisterStream(1, SpdyStreamPrecedence(0, 100, false));
-  scheduler_.RegisterStream(2, SpdyStreamPrecedence(1, 100, false));
-  scheduler_.RegisterStream(3, SpdyStreamPrecedence(1, 100, false));
-  scheduler_.RegisterStream(4, SpdyStreamPrecedence(2, 100, false));
-  scheduler_.UpdateStreamPrecedence(1, SpdyStreamPrecedence(2, 100, false));
-  EXPECT_THAT(scheduler_.GetStreamChildren(0), ElementsAre(2));
-  EXPECT_THAT(scheduler_.GetStreamChildren(1), ElementsAre(3));
-  EXPECT_THAT(scheduler_.GetStreamChildren(2), UnorderedElementsAre(1, 4));
-  EXPECT_THAT(scheduler_.GetStreamChildren(3), IsEmpty());
-  EXPECT_THAT(scheduler_.GetStreamChildren(4), IsEmpty());
-  ASSERT_TRUE(peer_.ValidateInvariants());
-}
-
-TEST_F(Http2PriorityWriteSchedulerTest, UpdateStreamParentToChildExclusive) {
-  /* Tree:
-        0
-        |
-        1
-       / \
-      2   3
-      |
-      4
-   */
-  scheduler_.RegisterStream(1, SpdyStreamPrecedence(0, 100, false));
-  scheduler_.RegisterStream(2, SpdyStreamPrecedence(1, 100, false));
-  scheduler_.RegisterStream(3, SpdyStreamPrecedence(1, 100, false));
-  scheduler_.RegisterStream(4, SpdyStreamPrecedence(2, 100, false));
-  scheduler_.UpdateStreamPrecedence(1, SpdyStreamPrecedence(2, 100, true));
-  EXPECT_THAT(scheduler_.GetStreamChildren(0), ElementsAre(2));
-  EXPECT_THAT(scheduler_.GetStreamChildren(1), UnorderedElementsAre(3, 4));
-  EXPECT_THAT(scheduler_.GetStreamChildren(2), ElementsAre(1));
-  EXPECT_THAT(scheduler_.GetStreamChildren(3), IsEmpty());
-  EXPECT_THAT(scheduler_.GetStreamChildren(4), IsEmpty());
-  ASSERT_TRUE(peer_.ValidateInvariants());
-}
-
-TEST_F(Http2PriorityWriteSchedulerTest,
-       UpdateStreamParentToGrandchildNonExclusive) {
-  /* Tree:
-        0
-        |
-        1
-       / \
-      2   3
-     / \
-    4   5
-    |
-    6
-   */
-  scheduler_.RegisterStream(1, SpdyStreamPrecedence(0, 100, false));
-  scheduler_.RegisterStream(2, SpdyStreamPrecedence(1, 100, false));
-  scheduler_.RegisterStream(3, SpdyStreamPrecedence(1, 100, false));
-  scheduler_.RegisterStream(4, SpdyStreamPrecedence(2, 100, false));
-  scheduler_.RegisterStream(5, SpdyStreamPrecedence(2, 100, false));
-  scheduler_.RegisterStream(6, SpdyStreamPrecedence(4, 100, false));
-  scheduler_.UpdateStreamPrecedence(1, SpdyStreamPrecedence(4, 100, false));
-  EXPECT_THAT(scheduler_.GetStreamChildren(0), ElementsAre(4));
-  EXPECT_THAT(scheduler_.GetStreamChildren(1), UnorderedElementsAre(2, 3));
-  EXPECT_THAT(scheduler_.GetStreamChildren(2), ElementsAre(5));
-  EXPECT_THAT(scheduler_.GetStreamChildren(3), IsEmpty());
-  EXPECT_THAT(scheduler_.GetStreamChildren(4), UnorderedElementsAre(1, 6));
-  EXPECT_THAT(scheduler_.GetStreamChildren(5), IsEmpty());
-  EXPECT_THAT(scheduler_.GetStreamChildren(6), IsEmpty());
-  ASSERT_TRUE(peer_.ValidateInvariants());
-}
-
-TEST_F(Http2PriorityWriteSchedulerTest,
-       UpdateStreamParentToGrandchildExclusive) {
-  /* Tree:
-        0
-        |
-        1
-       / \
-      2   3
-     / \
-    4   5
-    |
-    6
-   */
-  scheduler_.RegisterStream(1, SpdyStreamPrecedence(0, 100, false));
-  scheduler_.RegisterStream(2, SpdyStreamPrecedence(1, 100, false));
-  scheduler_.RegisterStream(3, SpdyStreamPrecedence(1, 100, false));
-  scheduler_.RegisterStream(4, SpdyStreamPrecedence(2, 100, false));
-  scheduler_.RegisterStream(5, SpdyStreamPrecedence(2, 100, false));
-  scheduler_.RegisterStream(6, SpdyStreamPrecedence(4, 100, false));
-  scheduler_.UpdateStreamPrecedence(1, SpdyStreamPrecedence(4, 100, true));
-  EXPECT_THAT(scheduler_.GetStreamChildren(0), ElementsAre(4));
-  EXPECT_THAT(scheduler_.GetStreamChildren(1), UnorderedElementsAre(2, 3, 6));
-  EXPECT_THAT(scheduler_.GetStreamChildren(2), ElementsAre(5));
-  EXPECT_THAT(scheduler_.GetStreamChildren(3), IsEmpty());
-  EXPECT_THAT(scheduler_.GetStreamChildren(4), ElementsAre(1));
-  EXPECT_THAT(scheduler_.GetStreamChildren(5), IsEmpty());
-  EXPECT_THAT(scheduler_.GetStreamChildren(6), IsEmpty());
-  ASSERT_TRUE(peer_.ValidateInvariants());
-}
-
-TEST_F(Http2PriorityWriteSchedulerTest, RegisterStreamParentExclusive) {
-  /*  0
-     / \
-    1   2
- */
-  scheduler_.RegisterStream(1, SpdyStreamPrecedence(0, 100, false));
-  scheduler_.RegisterStream(2, SpdyStreamPrecedence(0, 100, false));
-  /*  0
-      |
-      3
-     / \
-    1   2
-  */
-  scheduler_.RegisterStream(3, SpdyStreamPrecedence(0, 100, true));
-  EXPECT_THAT(scheduler_.GetStreamChildren(0), ElementsAre(3));
-  EXPECT_THAT(scheduler_.GetStreamChildren(3), UnorderedElementsAre(1, 2));
-  EXPECT_THAT(scheduler_.GetStreamChildren(1), IsEmpty());
-  EXPECT_THAT(scheduler_.GetStreamChildren(2), IsEmpty());
-  ASSERT_TRUE(peer_.ValidateInvariants());
-}
-
-TEST_F(Http2PriorityWriteSchedulerTest, UpdateStreamParentExclusive) {
-  /*  0
-     /|\
-    1 2 3
- */
-  scheduler_.RegisterStream(1, SpdyStreamPrecedence(0, 100, false));
-  scheduler_.RegisterStream(2, SpdyStreamPrecedence(0, 100, false));
-  scheduler_.RegisterStream(3, SpdyStreamPrecedence(0, 100, false));
-  /*  0
-      |
-      1
-     / \
-    2   3
-  */
-  scheduler_.UpdateStreamPrecedence(1, SpdyStreamPrecedence(0, 100, true));
-  EXPECT_THAT(scheduler_.GetStreamChildren(0), ElementsAre(1));
-  EXPECT_THAT(scheduler_.GetStreamChildren(1), UnorderedElementsAre(2, 3));
-  EXPECT_THAT(scheduler_.GetStreamChildren(2), IsEmpty());
-  EXPECT_THAT(scheduler_.GetStreamChildren(3), IsEmpty());
-  ASSERT_TRUE(peer_.ValidateInvariants());
-}
-
-TEST_F(Http2PriorityWriteSchedulerTest, UpdateStreamParentExclusive2) {
-  /*   0
-       |
-       1
-      / \
-     2   3
-        / \
-       4   5
-       |
-       6
- */
-  scheduler_.RegisterStream(1, SpdyStreamPrecedence(0, 100, false));
-  scheduler_.RegisterStream(2, SpdyStreamPrecedence(1, 100, false));
-  scheduler_.RegisterStream(3, SpdyStreamPrecedence(1, 100, false));
-  scheduler_.RegisterStream(4, SpdyStreamPrecedence(3, 100, false));
-  scheduler_.RegisterStream(5, SpdyStreamPrecedence(3, 100, false));
-  scheduler_.RegisterStream(6, SpdyStreamPrecedence(4, 100, false));
-  // Update stream 1's parent to 4 exclusive.
-  /*  0
-      |
-      4
-      |
-      1
-     /|\
-    2 3 6
-      |
-      5
-  */
-  scheduler_.UpdateStreamPrecedence(1, SpdyStreamPrecedence(4, 100, true));
-  EXPECT_THAT(scheduler_.GetStreamChildren(0), ElementsAre(4));
-  EXPECT_THAT(scheduler_.GetStreamChildren(4), ElementsAre(1));
-  EXPECT_THAT(scheduler_.GetStreamChildren(1), UnorderedElementsAre(2, 3, 6));
-  EXPECT_THAT(scheduler_.GetStreamChildren(2), IsEmpty());
-  EXPECT_THAT(scheduler_.GetStreamChildren(3), ElementsAre(5));
-  EXPECT_THAT(scheduler_.GetStreamChildren(6), IsEmpty());
-  ASSERT_TRUE(peer_.ValidateInvariants());
-}
-
-TEST_F(Http2PriorityWriteSchedulerTest, UpdateStreamParentNonExclusive) {
-  /*   0
-       |
-       1
-      / \
-     2   3
-        / \
-       4   5
-       |
-       6
- */
-  scheduler_.RegisterStream(1, SpdyStreamPrecedence(0, 100, false));
-  scheduler_.RegisterStream(2, SpdyStreamPrecedence(1, 100, false));
-  scheduler_.RegisterStream(3, SpdyStreamPrecedence(1, 100, false));
-  scheduler_.RegisterStream(4, SpdyStreamPrecedence(3, 100, false));
-  scheduler_.RegisterStream(5, SpdyStreamPrecedence(3, 100, false));
-  scheduler_.RegisterStream(6, SpdyStreamPrecedence(4, 100, false));
-  // Update stream 1's parent to 4.
-  /*  0
-      |
-      4
-     / \
-    6   1
-       / \
-      2   3
-          |
-          5
-  */
-  scheduler_.UpdateStreamPrecedence(1, SpdyStreamPrecedence(4, 100, false));
-  EXPECT_THAT(scheduler_.GetStreamChildren(0), ElementsAre(4));
-  EXPECT_THAT(scheduler_.GetStreamChildren(4), UnorderedElementsAre(6, 1));
-  EXPECT_THAT(scheduler_.GetStreamChildren(6), IsEmpty());
-  EXPECT_THAT(scheduler_.GetStreamChildren(1), UnorderedElementsAre(2, 3));
-  EXPECT_THAT(scheduler_.GetStreamChildren(2), IsEmpty());
-  EXPECT_THAT(scheduler_.GetStreamChildren(3), ElementsAre(5));
-  EXPECT_THAT(scheduler_.GetStreamChildren(5), IsEmpty());
-  ASSERT_TRUE(peer_.ValidateInvariants());
-}
-
-TEST_F(Http2PriorityWriteSchedulerTest, UpdateStreamParentToParent) {
-  scheduler_.RegisterStream(1, SpdyStreamPrecedence(0, 100, false));
-  scheduler_.RegisterStream(2, SpdyStreamPrecedence(1, 100, false));
-  scheduler_.RegisterStream(3, SpdyStreamPrecedence(1, 100, false));
-  EXPECT_THAT(scheduler_.GetStreamChildren(1), UnorderedElementsAre(2, 3));
-  EXPECT_THAT(scheduler_.GetStreamChildren(2), IsEmpty());
-  EXPECT_THAT(scheduler_.GetStreamChildren(3), IsEmpty());
-  for (bool exclusive : {true, false}) {
-    scheduler_.UpdateStreamPrecedence(2,
-                                      SpdyStreamPrecedence(1, 100, exclusive));
-    EXPECT_THAT(scheduler_.GetStreamChildren(0), ElementsAre(1));
-    EXPECT_THAT(scheduler_.GetStreamChildren(1), UnorderedElementsAre(2));
-    EXPECT_THAT(scheduler_.GetStreamChildren(2), UnorderedElementsAre(3));
-    EXPECT_THAT(scheduler_.GetStreamChildren(3), IsEmpty());
-  }
-  ASSERT_TRUE(peer_.ValidateInvariants());
-}
-
-TEST_F(Http2PriorityWriteSchedulerTest, UpdateStreamParentToSelf) {
-  scheduler_.RegisterStream(1, SpdyStreamPrecedence(0, 100, false));
-  EXPECT_QUICHE_BUG(
-      scheduler_.UpdateStreamPrecedence(1, SpdyStreamPrecedence(1, 100, false)),
-      "Cannot set stream to be its own parent");
-  EXPECT_QUICHE_BUG(
-      scheduler_.UpdateStreamPrecedence(1, SpdyStreamPrecedence(1, 100, true)),
-      "Cannot set stream to be its own parent");
-  EXPECT_THAT(scheduler_.GetStreamChildren(0), ElementsAre(1));
-  EXPECT_THAT(scheduler_.GetStreamChildren(1), IsEmpty());
-  ASSERT_TRUE(peer_.ValidateInvariants());
-}
-
-TEST_F(Http2PriorityWriteSchedulerTest, BlockAndUnblock) {
-  /* Create the tree.
-
-             0
-           / | \
-          /  |  \
-         1   2   3
-        / \   \   \
-       4   5   6   7
-      /|  / \  |   |\
-     8 9 10 11 12 13 14
-    / \
-   15 16
-
-  */
-  scheduler_.RegisterStream(1, SpdyStreamPrecedence(0, 100, false));
-  scheduler_.RegisterStream(2, SpdyStreamPrecedence(0, 100, false));
-  scheduler_.RegisterStream(3, SpdyStreamPrecedence(0, 100, false));
-  scheduler_.RegisterStream(4, SpdyStreamPrecedence(1, 100, false));
-  scheduler_.RegisterStream(5, SpdyStreamPrecedence(1, 100, false));
-  scheduler_.RegisterStream(8, SpdyStreamPrecedence(4, 100, false));
-  scheduler_.RegisterStream(9, SpdyStreamPrecedence(4, 100, false));
-  scheduler_.RegisterStream(10, SpdyStreamPrecedence(5, 100, false));
-  scheduler_.RegisterStream(11, SpdyStreamPrecedence(5, 100, false));
-  scheduler_.RegisterStream(15, SpdyStreamPrecedence(8, 100, false));
-  scheduler_.RegisterStream(16, SpdyStreamPrecedence(8, 100, false));
-  scheduler_.RegisterStream(12, SpdyStreamPrecedence(2, 100, false));
-  scheduler_.RegisterStream(6, SpdyStreamPrecedence(2, 100, true));
-  scheduler_.RegisterStream(7, SpdyStreamPrecedence(0, 100, false));
-  scheduler_.RegisterStream(13, SpdyStreamPrecedence(7, 100, true));
-  scheduler_.RegisterStream(14, SpdyStreamPrecedence(7, 100, false));
-  scheduler_.UpdateStreamPrecedence(7, SpdyStreamPrecedence(3, 100, false));
-  EXPECT_EQ(0u, scheduler_.GetStreamPrecedence(1).parent_id());
-  EXPECT_EQ(0u, scheduler_.GetStreamPrecedence(2).parent_id());
-  EXPECT_EQ(0u, scheduler_.GetStreamPrecedence(3).parent_id());
-  EXPECT_EQ(1u, scheduler_.GetStreamPrecedence(4).parent_id());
-  EXPECT_EQ(1u, scheduler_.GetStreamPrecedence(5).parent_id());
-  EXPECT_EQ(2u, scheduler_.GetStreamPrecedence(6).parent_id());
-  EXPECT_EQ(3u, scheduler_.GetStreamPrecedence(7).parent_id());
-  EXPECT_EQ(4u, scheduler_.GetStreamPrecedence(8).parent_id());
-  EXPECT_EQ(4u, scheduler_.GetStreamPrecedence(9).parent_id());
-  EXPECT_EQ(5u, scheduler_.GetStreamPrecedence(10).parent_id());
-  EXPECT_EQ(5u, scheduler_.GetStreamPrecedence(11).parent_id());
-  EXPECT_EQ(6u, scheduler_.GetStreamPrecedence(12).parent_id());
-  EXPECT_EQ(7u, scheduler_.GetStreamPrecedence(13).parent_id());
-  EXPECT_EQ(7u, scheduler_.GetStreamPrecedence(14).parent_id());
-  EXPECT_EQ(8u, scheduler_.GetStreamPrecedence(15).parent_id());
-  EXPECT_EQ(8u, scheduler_.GetStreamPrecedence(16).parent_id());
-  ASSERT_TRUE(peer_.ValidateInvariants());
-
-  EXPECT_EQ(peer_.TotalChildWeights(0),
-            scheduler_.GetStreamPrecedence(1).weight() +
-                scheduler_.GetStreamPrecedence(2).weight() +
-                scheduler_.GetStreamPrecedence(3).weight());
-  EXPECT_EQ(peer_.TotalChildWeights(3),
-            scheduler_.GetStreamPrecedence(7).weight());
-  EXPECT_EQ(peer_.TotalChildWeights(7),
-            scheduler_.GetStreamPrecedence(13).weight() +
-                scheduler_.GetStreamPrecedence(14).weight());
-  EXPECT_EQ(peer_.TotalChildWeights(13), 0);
-  EXPECT_EQ(peer_.TotalChildWeights(14), 0);
-
-  ASSERT_TRUE(peer_.ValidateInvariants());
-}
-
-TEST_F(Http2PriorityWriteSchedulerTest, HasReadyStreams) {
-  EXPECT_FALSE(scheduler_.HasReadyStreams());
-  scheduler_.RegisterStream(1, SpdyStreamPrecedence(0, 10, false));
-  EXPECT_FALSE(scheduler_.HasReadyStreams());
-  scheduler_.MarkStreamReady(1, false);
-  EXPECT_TRUE(scheduler_.HasReadyStreams());
-  EXPECT_TRUE(scheduler_.IsStreamReady(1));
-  scheduler_.MarkStreamNotReady(1);
-  EXPECT_FALSE(scheduler_.HasReadyStreams());
-  EXPECT_FALSE(scheduler_.IsStreamReady(1));
-  scheduler_.MarkStreamReady(1, true);
-  EXPECT_TRUE(scheduler_.HasReadyStreams());
-  EXPECT_TRUE(scheduler_.IsStreamReady(1));
-  scheduler_.UnregisterStream(1);
-  EXPECT_FALSE(scheduler_.HasReadyStreams());
-  ASSERT_TRUE(peer_.ValidateInvariants());
-  EXPECT_QUICHE_BUG(scheduler_.IsStreamReady(1), "Stream 1 not registered");
-}
-
-TEST_F(Http2PriorityWriteSchedulerTest, CalculateRoundedWeights) {
-  /* Create the tree.
-
-           0
-          / \
-         1   2
-       /| |\  |\
-      8 3 4 5 6 7
-  */
-  scheduler_.RegisterStream(3, SpdyStreamPrecedence(0, 100, false));
-  scheduler_.RegisterStream(4, SpdyStreamPrecedence(0, 100, false));
-  scheduler_.RegisterStream(5, SpdyStreamPrecedence(0, 100, false));
-  scheduler_.RegisterStream(1, SpdyStreamPrecedence(0, 10, true));
-  scheduler_.RegisterStream(2, SpdyStreamPrecedence(0, 5, false));
-  scheduler_.RegisterStream(6, SpdyStreamPrecedence(2, 1, false));
-  scheduler_.RegisterStream(7, SpdyStreamPrecedence(2, 1, false));
-  scheduler_.RegisterStream(8, SpdyStreamPrecedence(1, 1, false));
-
-  // Remove higher-level streams.
-  scheduler_.UnregisterStream(1);
-  scheduler_.UnregisterStream(2);
-
-  // 3.3 rounded down = 3.
-  EXPECT_EQ(3, scheduler_.GetStreamPrecedence(3).weight());
-  EXPECT_EQ(3, scheduler_.GetStreamPrecedence(4).weight());
-  EXPECT_EQ(3, scheduler_.GetStreamPrecedence(5).weight());
-  // 2.5 rounded up = 3.
-  EXPECT_EQ(3, scheduler_.GetStreamPrecedence(6).weight());
-  EXPECT_EQ(3, scheduler_.GetStreamPrecedence(7).weight());
-  // 0 is not a valid weight, so round up to 1.
-  EXPECT_EQ(1, scheduler_.GetStreamPrecedence(8).weight());
-  ASSERT_TRUE(peer_.ValidateInvariants());
-}
-
-TEST_F(Http2PriorityWriteSchedulerTest, GetLatestEventWithPrecedence) {
-  EXPECT_QUICHE_BUG(scheduler_.RecordStreamEventTime(3, 5),
-                    "Stream 3 not registered");
-  EXPECT_QUICHE_BUG(EXPECT_EQ(0, scheduler_.GetLatestEventWithPrecedence(4)),
-                    "Stream 4 not registered");
-
-  for (int i = 1; i < 5; ++i) {
-    int weight = SpdyStreamPrecedence(i).weight();
-    scheduler_.RegisterStream(i, SpdyStreamPrecedence(0, weight, false));
-  }
-  for (int i = 1; i < 5; ++i) {
-    EXPECT_EQ(0, scheduler_.GetLatestEventWithPrecedence(i));
-  }
-  for (int i = 1; i < 5; ++i) {
-    scheduler_.RecordStreamEventTime(i, i * 100);
-  }
-  for (int i = 1; i < 5; ++i) {
-    EXPECT_EQ((i - 1) * 100, scheduler_.GetLatestEventWithPrecedence(i));
-  }
-}
-
-// Add ready streams at front and back.
-TEST_F(Http2PriorityWriteSchedulerTest, MarkReadyFrontAndBack) {
-  scheduler_.RegisterStream(1, SpdyStreamPrecedence(0, 10, false));
-  scheduler_.RegisterStream(2, SpdyStreamPrecedence(0, 20, false));
-  scheduler_.RegisterStream(3, SpdyStreamPrecedence(0, 20, false));
-  scheduler_.RegisterStream(4, SpdyStreamPrecedence(0, 20, false));
-  scheduler_.RegisterStream(5, SpdyStreamPrecedence(0, 30, false));
-
-  for (int i = 1; i < 6; ++i) {
-    scheduler_.MarkStreamReady(i, false);
-  }
-  EXPECT_EQ(5u, scheduler_.PopNextReadyStream());
-  EXPECT_EQ(2u, scheduler_.PopNextReadyStream());
-  scheduler_.MarkStreamReady(2, false);
-  EXPECT_EQ(3u, scheduler_.PopNextReadyStream());
-  scheduler_.MarkStreamReady(3, false);
-  EXPECT_EQ(4u, scheduler_.PopNextReadyStream());
-  scheduler_.MarkStreamReady(4, false);
-  EXPECT_EQ(2u, scheduler_.PopNextReadyStream());
-  scheduler_.MarkStreamReady(2, true);
-  EXPECT_EQ(2u, scheduler_.PopNextReadyStream());
-  scheduler_.MarkStreamReady(5, false);
-  scheduler_.MarkStreamReady(2, true);
-  EXPECT_EQ(5u, scheduler_.PopNextReadyStream());
-}
-
-// Add ready streams at front and back and pop them with
-// PopNextReadyStreamAndPrecedence.
-TEST_F(Http2PriorityWriteSchedulerTest, PopNextReadyStreamAndPrecedence) {
-  scheduler_.RegisterStream(1, SpdyStreamPrecedence(0, 10, false));
-  scheduler_.RegisterStream(2, SpdyStreamPrecedence(0, 20, false));
-  scheduler_.RegisterStream(3, SpdyStreamPrecedence(0, 20, false));
-  scheduler_.RegisterStream(4, SpdyStreamPrecedence(0, 20, false));
-  scheduler_.RegisterStream(5, SpdyStreamPrecedence(0, 30, false));
-
-  for (int i = 1; i < 6; ++i) {
-    scheduler_.MarkStreamReady(i, false);
-  }
-  EXPECT_EQ(std::make_tuple(5, SpdyStreamPrecedence(0, 30, false)),
-            scheduler_.PopNextReadyStreamAndPrecedence());
-  EXPECT_EQ(std::make_tuple(2, SpdyStreamPrecedence(0, 20, false)),
-            scheduler_.PopNextReadyStreamAndPrecedence());
-  scheduler_.MarkStreamReady(2, false);
-  EXPECT_EQ(std::make_tuple(3, SpdyStreamPrecedence(0, 20, false)),
-            scheduler_.PopNextReadyStreamAndPrecedence());
-  scheduler_.MarkStreamReady(3, false);
-  EXPECT_EQ(std::make_tuple(4, SpdyStreamPrecedence(0, 20, false)),
-            scheduler_.PopNextReadyStreamAndPrecedence());
-  scheduler_.MarkStreamReady(4, false);
-  EXPECT_EQ(std::make_tuple(2, SpdyStreamPrecedence(0, 20, false)),
-            scheduler_.PopNextReadyStreamAndPrecedence());
-  scheduler_.MarkStreamReady(2, true);
-  EXPECT_EQ(std::make_tuple(2, SpdyStreamPrecedence(0, 20, false)),
-            scheduler_.PopNextReadyStreamAndPrecedence());
-  scheduler_.MarkStreamReady(5, false);
-  scheduler_.MarkStreamReady(2, true);
-  EXPECT_EQ(std::make_tuple(5, SpdyStreamPrecedence(0, 30, false)),
-            scheduler_.PopNextReadyStreamAndPrecedence());
-}
-
-TEST_F(Http2PriorityWriteSchedulerTest, ShouldYield) {
-  /*
-         0
-        /|\
-       1 2 3
-      /|\ \
-     4 5 6 7
-       |
-       8
-
-  */
-  scheduler_.RegisterStream(1, SpdyStreamPrecedence(0, 100, false));
-  scheduler_.RegisterStream(2, SpdyStreamPrecedence(0, 100, false));
-  scheduler_.RegisterStream(3, SpdyStreamPrecedence(0, 100, false));
-  scheduler_.RegisterStream(4, SpdyStreamPrecedence(1, 100, false));
-  scheduler_.RegisterStream(5, SpdyStreamPrecedence(1, 200, false));
-  scheduler_.RegisterStream(6, SpdyStreamPrecedence(1, 255, false));
-  scheduler_.RegisterStream(7, SpdyStreamPrecedence(2, 100, false));
-  scheduler_.RegisterStream(8, SpdyStreamPrecedence(5, 100, false));
-
-  scheduler_.MarkStreamReady(5, false);
-
-  for (int i = 1; i <= 8; ++i) {
-    // Verify only 4 and 8 should yield to 5.
-    if (i == 4 || i == 8) {
-      EXPECT_TRUE(scheduler_.ShouldYield(i)) << "stream_id: " << i;
-    } else {
-      EXPECT_FALSE(scheduler_.ShouldYield(i)) << "stream_id: " << i;
-    }
-  }
-
-  // Marks streams 1 and 2 ready.
-  scheduler_.MarkStreamReady(1, false);
-  scheduler_.MarkStreamReady(2, false);
-  // 1 should not yield.
-  EXPECT_FALSE(scheduler_.ShouldYield(1));
-  // Verify 2 should yield to 1.
-  EXPECT_TRUE(scheduler_.ShouldYield(2));
-}
-
-class PopNextReadyStreamTest : public Http2PriorityWriteSchedulerTest {
- protected:
-  void SetUp() override {
-    /* Create the tree.
-
-             0
-            /|\
-           1 2 3
-          /| |\
-         4 5 6 7
-        /
-       8
-
-    */
-    scheduler_.RegisterStream(1, SpdyStreamPrecedence(0, 100, false));
-    scheduler_.RegisterStream(2, SpdyStreamPrecedence(0, 100, false));
-    scheduler_.RegisterStream(3, SpdyStreamPrecedence(0, 100, false));
-    scheduler_.RegisterStream(4, SpdyStreamPrecedence(1, 100, false));
-    scheduler_.RegisterStream(5, SpdyStreamPrecedence(1, 100, false));
-    scheduler_.RegisterStream(6, SpdyStreamPrecedence(2, 100, false));
-    scheduler_.RegisterStream(7, SpdyStreamPrecedence(2, 100, false));
-    scheduler_.RegisterStream(8, SpdyStreamPrecedence(4, 100, false));
-
-    // Set all nodes ready to write.
-    for (SpdyStreamId id = 1; id <= 8; ++id) {
-      scheduler_.MarkStreamReady(id, false);
-    }
-  }
-
-  AssertionResult PopNextReturnsCycle(
-      std::initializer_list<SpdyStreamId> stream_ids) {
-    int count = 0;
-    const int kNumCyclesToCheck = 2;
-    for (int i = 0; i < kNumCyclesToCheck; i++) {
-      for (SpdyStreamId expected_id : stream_ids) {
-        SpdyStreamId next_id = scheduler_.PopNextReadyStream();
-        scheduler_.MarkStreamReady(next_id, false);
-        if (next_id != expected_id) {
-          return AssertionFailure() << "Pick " << count << ": expected stream "
-                                    << expected_id << " instead of " << next_id;
-        }
-        if (!peer_.ValidateInvariants()) {
-          return AssertionFailure() << "ValidateInvariants failed";
-        }
-        ++count;
-      }
-    }
-    return AssertionSuccess();
-  }
-};
-
-// When all streams are schedulable, only top-level streams should be returned.
-TEST_F(PopNextReadyStreamTest, NoneBlocked) {
-  EXPECT_TRUE(PopNextReturnsCycle({1, 2, 3}));
-}
-
-// When a parent stream is blocked, its children should be scheduled, if
-// priorities allow.
-TEST_F(PopNextReadyStreamTest, SingleStreamBlocked) {
-  scheduler_.MarkStreamNotReady(1);
-
-  // Round-robin only across 2 and 3, since children of 1 have lower priority.
-  EXPECT_TRUE(PopNextReturnsCycle({2, 3}));
-
-  // Make children of 1 have equal priority as 2 and 3, after which they should
-  // be returned as well.
-  scheduler_.UpdateStreamPrecedence(1, SpdyStreamPrecedence(0, 200, false));
-  EXPECT_TRUE(PopNextReturnsCycle({4, 5, 2, 3}));
-}
-
-// Block multiple levels of streams.
-TEST_F(PopNextReadyStreamTest, MultiLevelBlocked) {
-  for (SpdyStreamId stream_id : {1, 4, 5}) {
-    scheduler_.MarkStreamNotReady(stream_id);
-  }
-  // Round-robin only across 2 and 3, since children of 1 have lower priority.
-  EXPECT_TRUE(PopNextReturnsCycle({2, 3}));
-
-  // Make 8 have equal priority as 2 and 3.
-  scheduler_.UpdateStreamPrecedence(1, SpdyStreamPrecedence(0, 200, false));
-  EXPECT_TRUE(PopNextReturnsCycle({8, 2, 3}));
-}
-
-// A removed stream shouldn't be scheduled.
-TEST_F(PopNextReadyStreamTest, RemoveStream) {
-  scheduler_.UnregisterStream(1);
-
-  // Round-robin only across 2 and 3, since previous children of 1 have lower
-  // priority (the weight of 4 and 5 is scaled down when they are elevated to
-  // siblings of 2 and 3).
-  EXPECT_TRUE(PopNextReturnsCycle({2, 3}));
-
-  // Make previous children of 1 have equal priority as 2 and 3.
-  scheduler_.UpdateStreamPrecedence(4, SpdyStreamPrecedence(0, 100, false));
-  scheduler_.UpdateStreamPrecedence(5, SpdyStreamPrecedence(0, 100, false));
-  EXPECT_TRUE(PopNextReturnsCycle({4, 5, 2, 3}));
-}
-
-// Block an entire subtree.
-TEST_F(PopNextReadyStreamTest, SubtreeBlocked) {
-  for (SpdyStreamId stream_id : {1, 4, 5, 8}) {
-    scheduler_.MarkStreamNotReady(stream_id);
-  }
-  EXPECT_TRUE(PopNextReturnsCycle({2, 3}));
-}
-
-// If all parent streams are blocked, children should be returned.
-TEST_F(PopNextReadyStreamTest, ParentsBlocked) {
-  for (SpdyStreamId stream_id : {1, 2, 3}) {
-    scheduler_.MarkStreamNotReady(stream_id);
-  }
-  EXPECT_TRUE(PopNextReturnsCycle({4, 5, 6, 7}));
-}
-
-// Unblocking streams should make them schedulable.
-TEST_F(PopNextReadyStreamTest, BlockAndUnblock) {
-  EXPECT_TRUE(PopNextReturnsCycle({1, 2, 3}));
-  scheduler_.MarkStreamNotReady(2);
-  EXPECT_TRUE(PopNextReturnsCycle({1, 3}));
-  scheduler_.MarkStreamReady(2, false);
-  // Cycle order permuted since 2 effectively appended at tail.
-  EXPECT_TRUE(PopNextReturnsCycle({1, 3, 2}));
-}
-
-// Block nodes in multiple subtrees.
-TEST_F(PopNextReadyStreamTest, ScatteredBlocked) {
-  for (SpdyStreamId stream_id : {1, 2, 6, 7}) {
-    scheduler_.MarkStreamNotReady(stream_id);
-  }
-  // Only 3 returned, since of remaining streams it has highest priority.
-  EXPECT_TRUE(PopNextReturnsCycle({3}));
-
-  // Make children of 1 have priority equal to 3.
-  scheduler_.UpdateStreamPrecedence(1, SpdyStreamPrecedence(0, 200, false));
-  EXPECT_TRUE(PopNextReturnsCycle({4, 5, 3}));
-
-  // When 4 is blocked, its child 8 should take its place, since it has same
-  // priority.
-  scheduler_.MarkStreamNotReady(4);
-  EXPECT_TRUE(PopNextReturnsCycle({8, 5, 3}));
-}
-
-}  // namespace test
-}  // namespace http2
diff --git a/http2/core/priority_write_scheduler.h b/http2/core/priority_write_scheduler.h
index b59e294..87de3a7 100644
--- a/http2/core/priority_write_scheduler.h
+++ b/http2/core/priority_write_scheduler.h
@@ -18,6 +18,7 @@
 #include "absl/strings/str_cat.h"
 #include "http2/core/write_scheduler.h"
 #include "common/platform/api/quiche_bug_tracker.h"
+#include "common/platform/api/quiche_export.h"
 #include "common/platform/api/quiche_logging.h"
 #include "spdy/core/spdy_protocol.h"
 
@@ -37,9 +38,9 @@
 // that priority that are ready to write, as well as a timestamp of the last
 // I/O event that occurred for a stream of that priority.
 //
-// DO NOT USE. Deprecated.
 template <typename StreamIdType>
-class PriorityWriteScheduler : public WriteScheduler<StreamIdType> {
+class QUICHE_EXPORT_PRIVATE PriorityWriteScheduler
+    : public WriteScheduler<StreamIdType> {
  public:
   using typename WriteScheduler<StreamIdType>::StreamPrecedenceType;
 
@@ -286,7 +287,7 @@
 
   // State kept for all registered streams. All ready streams have ready = true
   // and should be present in priority_infos_[priority].ready_list.
-  struct StreamInfo {
+  struct QUICHE_EXPORT_PRIVATE StreamInfo {
     spdy::SpdyPriority priority;
     StreamIdType stream_id;
     bool ready;
@@ -296,7 +297,7 @@
   using ReadyList = std::deque<StreamInfo*>;
 
   // State kept for each priority level.
-  struct PriorityInfo {
+  struct QUICHE_EXPORT_PRIVATE PriorityInfo {
     // IDs of streams that are ready to write.
     ReadyList ready_list;
     // Time of latest write event for stream of this priority, in microseconds.
diff --git a/http2/core/write_scheduler.h b/http2/core/write_scheduler.h
index 4973a2d..3b58c4f 100644
--- a/http2/core/write_scheduler.h
+++ b/http2/core/write_scheduler.h
@@ -22,14 +22,6 @@
 //     where (writable) higher-priority streams are always given precedence
 //     over lower-priority streams.
 //
-// Http2PriorityWriteScheduler: implements SPDY priority-based stream
-//     scheduling coupled with the HTTP/2 stream dependency model. This is only
-//     intended as a transitional step towards Http2WeightedWriteScheduler.
-//
-// Http2WeightedWriteScheduler (coming soon): implements the HTTP/2 stream
-//     dependency model with weighted stream scheduling, fully conforming to
-//     RFC 7540.
-//
 // The type used to represent stream IDs (StreamIdType) is templated in order
 // to allow for use by both SPDY and QUIC codebases. It must be a POD that
 // supports comparison (i.e., a numeric type).