gfe-relnote: Fix Http2PriorityWriteScheduler::UpdateStreamParent. Not used in prod. Not protected.
Current UpdateStreamParent() early returns if parent does not change. But exclusive bit should be considered as well.
PiperOrigin-RevId: 260496394
Change-Id: I9401a41140e12d19fbb36e9d5d13dcf58090be47
diff --git a/spdy/core/http2_priority_write_scheduler.h b/spdy/core/http2_priority_write_scheduler.h
index a35e076..f89dc8d 100644
--- a/spdy/core/http2_priority_write_scheduler.h
+++ b/spdy/core/http2_priority_write_scheduler.h
@@ -405,8 +405,10 @@
return;
}
- // If the new parent is already the stream's parent, we're done.
- if (stream_info->parent == new_parent) {
+ if (stream_info->parent == new_parent &&
+ (!exclusive || new_parent->children.size() == 1)) {
+ // If the new parent is already the stream's parent, and exclusivity (if
+ // specified) is already satisfied, we are done.
return;
}
diff --git a/spdy/core/http2_priority_write_scheduler_test.cc b/spdy/core/http2_priority_write_scheduler_test.cc
index e498c37..0629de9 100644
--- a/spdy/core/http2_priority_write_scheduler_test.cc
+++ b/spdy/core/http2_priority_write_scheduler_test.cc
@@ -426,16 +426,139 @@
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, 3));
- EXPECT_THAT(scheduler_.GetStreamChildren(2), IsEmpty());
+ EXPECT_THAT(scheduler_.GetStreamChildren(1), UnorderedElementsAre(2));
+ EXPECT_THAT(scheduler_.GetStreamChildren(2), UnorderedElementsAre(3));
EXPECT_THAT(scheduler_.GetStreamChildren(3), IsEmpty());
}
ASSERT_TRUE(peer_.ValidateInvariants());