Distribute effective weight among only streams with marked as top
If stream with dpri value of no_data, we check any its descendant has stream with dpri value of top. If so, we have to distribute of its portion of weight to its descendants.
This commit is contained in:
parent
1c1843297c
commit
853c9888d9
|
@ -62,6 +62,7 @@ void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id,
|
|||
stream->weight = weight;
|
||||
stream->effective_weight = stream->weight;
|
||||
stream->sum_dep_weight = 0;
|
||||
stream->sum_norest_weight = 0;
|
||||
|
||||
stream->roots = roots;
|
||||
stream->root_prev = NULL;
|
||||
|
@ -144,7 +145,7 @@ int32_t nghttp2_stream_dep_distributed_weight(nghttp2_stream *stream,
|
|||
int32_t nghttp2_stream_dep_distributed_effective_weight
|
||||
(nghttp2_stream *stream, int32_t weight)
|
||||
{
|
||||
weight = stream->effective_weight * weight / stream->sum_dep_weight;
|
||||
weight = stream->effective_weight * weight / stream->sum_norest_weight;
|
||||
|
||||
return nghttp2_max(1, weight);
|
||||
}
|
||||
|
@ -157,12 +158,22 @@ static void stream_update_dep_effective_weight(nghttp2_stream *stream)
|
|||
nghttp2_stream *si;
|
||||
|
||||
DEBUGF(fprintf(stderr, "stream: update_dep_effective_weight "
|
||||
"stream(%p)=%d, weight=%d\n",
|
||||
stream, stream->stream_id, stream->weight));
|
||||
"stream(%p)=%d, weight=%d, sum_norest_weight=%d\n",
|
||||
stream, stream->stream_id, stream->weight,
|
||||
stream->sum_norest_weight));
|
||||
|
||||
/* stream->sum_norest_weight == 0 means there is no
|
||||
NGHTTP2_STREAM_DPRI_TOP under stream */
|
||||
if(stream->dpri != NGHTTP2_STREAM_DPRI_NO_DATA ||
|
||||
stream->sum_norest_weight == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for(si = stream->dep_next; si; si = si->sib_next) {
|
||||
if(si->dpri != NGHTTP2_STREAM_DPRI_REST) {
|
||||
si->effective_weight = nghttp2_stream_dep_distributed_effective_weight
|
||||
(stream, si->weight);
|
||||
}
|
||||
|
||||
stream_update_dep_effective_weight(si);
|
||||
}
|
||||
|
@ -203,23 +214,13 @@ static void stream_update_dep_set_rest(nghttp2_stream *stream)
|
|||
static int stream_update_dep_set_top(nghttp2_stream *stream, nghttp2_pq *pq)
|
||||
{
|
||||
int rv;
|
||||
|
||||
if(stream == NULL) {
|
||||
return 0;
|
||||
}
|
||||
nghttp2_stream *si;
|
||||
|
||||
if(stream->dpri == NGHTTP2_STREAM_DPRI_TOP) {
|
||||
rv = stream_update_dep_set_top(stream->sib_next, pq);
|
||||
|
||||
if(rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(stream->dpri == NGHTTP2_STREAM_DPRI_REST) {
|
||||
|
||||
DEBUGF(fprintf(stderr, "stream: stream=%d data is top\n",
|
||||
stream->stream_id));
|
||||
|
||||
|
@ -233,32 +234,58 @@ static int stream_update_dep_set_top(nghttp2_stream *stream, nghttp2_pq *pq)
|
|||
|
||||
stream->dpri = NGHTTP2_STREAM_DPRI_TOP;
|
||||
|
||||
rv = stream_update_dep_set_top(stream->sib_next, pq);
|
||||
|
||||
if(rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(stream->dpri == NGHTTP2_STREAM_DPRI_NO_DATA);
|
||||
|
||||
rv = stream_update_dep_set_top(stream->sib_next, pq);
|
||||
for(si = stream->dep_next; si; si = si->sib_next) {
|
||||
rv = stream_update_dep_set_top(si, pq);
|
||||
|
||||
if(rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = stream_update_dep_set_top(stream->dep_next, pq);
|
||||
|
||||
if(rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Updates stream->sum_norest_weight recursively. We have to gather
|
||||
* effective sum of weight of descendants. If stream->dpri ==
|
||||
* NGHTTP2_STREAM_DPRI_NO_DATA, we have to go deeper and check that
|
||||
* any of its descendants has dpri value of NGHTTP2_STREAM_DPRI_TOP.
|
||||
* If so, we have to add weight of its direct descendants to
|
||||
* stream->sum_norest_weight. To make this work, this function
|
||||
* returns 1 if any of its descendants has dpri value of
|
||||
* NGHTTP2_STREAM_DPRI_TOP, otherwise 0.
|
||||
*/
|
||||
static int stream_update_dep_sum_norest_weight(nghttp2_stream *stream)
|
||||
{
|
||||
nghttp2_stream *si;
|
||||
int rv;
|
||||
|
||||
stream->sum_norest_weight = 0;
|
||||
|
||||
if(stream->dpri == NGHTTP2_STREAM_DPRI_TOP) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(stream->dpri == NGHTTP2_STREAM_DPRI_REST) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
rv = 0;
|
||||
|
||||
for(si = stream->dep_next; si; si = si->sib_next) {
|
||||
|
||||
if(stream_update_dep_sum_norest_weight(si)) {
|
||||
rv = 1;
|
||||
stream->sum_norest_weight += si->weight;
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int stream_update_dep_on_attach_data(nghttp2_stream *stream,
|
||||
nghttp2_pq *pq)
|
||||
{
|
||||
|
@ -279,6 +306,9 @@ static int stream_update_dep_on_attach_data(nghttp2_stream *stream,
|
|||
return rv;
|
||||
}
|
||||
|
||||
stream_update_dep_sum_norest_weight(root_stream);
|
||||
stream_update_dep_effective_weight(root_stream);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -288,12 +318,6 @@ static int stream_update_dep_on_detach_data(nghttp2_stream *stream,
|
|||
int rv;
|
||||
nghttp2_stream *root_stream;
|
||||
|
||||
if(stream->dpri != NGHTTP2_STREAM_DPRI_TOP) {
|
||||
stream->dpri = NGHTTP2_STREAM_DPRI_NO_DATA;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
stream->dpri = NGHTTP2_STREAM_DPRI_NO_DATA;
|
||||
|
||||
root_stream = nghttp2_stream_get_dep_root(stream);
|
||||
|
@ -304,6 +328,9 @@ static int stream_update_dep_on_detach_data(nghttp2_stream *stream,
|
|||
return rv;
|
||||
}
|
||||
|
||||
stream_update_dep_sum_norest_weight(root_stream);
|
||||
stream_update_dep_effective_weight(root_stream);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -454,6 +481,7 @@ void nghttp2_stream_dep_insert(nghttp2_stream *dep_stream,
|
|||
nghttp2_stream *stream)
|
||||
{
|
||||
nghttp2_stream *si;
|
||||
nghttp2_stream *root_stream;
|
||||
|
||||
assert(stream->data_item == NULL);
|
||||
|
||||
|
@ -477,8 +505,10 @@ void nghttp2_stream_dep_insert(nghttp2_stream *dep_stream,
|
|||
dep_stream->dep_next = stream;
|
||||
stream->dep_prev = dep_stream;
|
||||
|
||||
stream_update_dep_length(dep_stream, 1);
|
||||
stream_update_dep_effective_weight(dep_stream);
|
||||
root_stream = stream_update_dep_length(dep_stream, 1);
|
||||
|
||||
stream_update_dep_sum_norest_weight(root_stream);
|
||||
stream_update_dep_effective_weight(root_stream);
|
||||
|
||||
++stream->roots->num_streams;
|
||||
}
|
||||
|
@ -487,6 +517,7 @@ void nghttp2_stream_dep_add(nghttp2_stream *dep_stream,
|
|||
nghttp2_stream *stream)
|
||||
{
|
||||
nghttp2_stream *last_sib;
|
||||
nghttp2_stream *root_stream;
|
||||
|
||||
assert(stream->data_item == NULL);
|
||||
|
||||
|
@ -495,7 +526,7 @@ void nghttp2_stream_dep_add(nghttp2_stream *dep_stream,
|
|||
dep_stream, dep_stream->stream_id,
|
||||
stream, stream->stream_id));
|
||||
|
||||
stream_update_dep_length(dep_stream, 1);
|
||||
root_stream = stream_update_dep_length(dep_stream, 1);
|
||||
|
||||
dep_stream->sum_dep_weight += stream->weight;
|
||||
|
||||
|
@ -508,16 +539,19 @@ void nghttp2_stream_dep_add(nghttp2_stream *dep_stream,
|
|||
stream->sib_prev = last_sib;
|
||||
}
|
||||
|
||||
stream_update_dep_effective_weight(dep_stream);
|
||||
stream_update_dep_sum_norest_weight(root_stream);
|
||||
stream_update_dep_effective_weight(root_stream);
|
||||
|
||||
++stream->roots->num_streams;
|
||||
}
|
||||
|
||||
void nghttp2_stream_dep_remove(nghttp2_stream *stream)
|
||||
{
|
||||
nghttp2_stream *prev, *next, *dep_next, *dep_prev, *si;
|
||||
nghttp2_stream *prev, *next, *dep_next, *dep_prev, *si, *root_stream;
|
||||
int32_t sum_dep_weight_delta;
|
||||
|
||||
root_stream = NULL;
|
||||
|
||||
DEBUGF(fprintf(stderr, "stream: dep_remove stream(%p)=%d\n",
|
||||
stream, stream->stream_id));
|
||||
|
||||
|
@ -535,7 +569,7 @@ void nghttp2_stream_dep_remove(nghttp2_stream *stream)
|
|||
dep_prev = prev->dep_prev;
|
||||
|
||||
if(dep_prev) {
|
||||
stream_update_dep_length(dep_prev, -1);
|
||||
root_stream = stream_update_dep_length(dep_prev, -1);
|
||||
|
||||
dep_prev->sum_dep_weight += sum_dep_weight_delta;
|
||||
}
|
||||
|
@ -608,8 +642,9 @@ void nghttp2_stream_dep_remove(nghttp2_stream *stream)
|
|||
next->sib_prev = prev;
|
||||
}
|
||||
|
||||
if(dep_prev) {
|
||||
stream_update_dep_effective_weight(dep_prev);
|
||||
if(root_stream) {
|
||||
stream_update_dep_sum_norest_weight(root_stream);
|
||||
stream_update_dep_effective_weight(root_stream);
|
||||
}
|
||||
|
||||
stream->num_substreams = 1;
|
||||
|
@ -675,8 +710,6 @@ int nghttp2_stream_dep_insert_subtree(nghttp2_stream *dep_stream,
|
|||
dep_stream->sum_dep_weight = stream->weight;
|
||||
}
|
||||
|
||||
stream_update_dep_effective_weight(dep_stream);
|
||||
|
||||
root_stream = stream_update_dep_length(dep_stream, delta_substreams);
|
||||
|
||||
rv = stream_update_dep_set_top(root_stream, pq);
|
||||
|
@ -685,6 +718,9 @@ int nghttp2_stream_dep_insert_subtree(nghttp2_stream *dep_stream,
|
|||
return rv;
|
||||
}
|
||||
|
||||
stream_update_dep_sum_norest_weight(root_stream);
|
||||
stream_update_dep_effective_weight(root_stream);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -718,8 +754,6 @@ int nghttp2_stream_dep_add_subtree(nghttp2_stream *dep_stream,
|
|||
dep_stream->sum_dep_weight = stream->weight;
|
||||
}
|
||||
|
||||
stream_update_dep_effective_weight(dep_stream);
|
||||
|
||||
root_stream = stream_update_dep_length(dep_stream, stream->num_substreams);
|
||||
|
||||
rv = stream_update_dep_set_top(root_stream, pq);
|
||||
|
@ -728,12 +762,15 @@ int nghttp2_stream_dep_add_subtree(nghttp2_stream *dep_stream,
|
|||
return rv;
|
||||
}
|
||||
|
||||
stream_update_dep_sum_norest_weight(root_stream);
|
||||
stream_update_dep_effective_weight(root_stream);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void nghttp2_stream_dep_remove_subtree(nghttp2_stream *stream)
|
||||
{
|
||||
nghttp2_stream *prev, *next, *dep_prev;
|
||||
nghttp2_stream *prev, *next, *dep_prev, *root_stream;
|
||||
|
||||
DEBUGF(fprintf(stderr, "stream: dep_remove_subtree stream(%p)=%d\n",
|
||||
stream, stream->stream_id));
|
||||
|
@ -771,9 +808,10 @@ void nghttp2_stream_dep_remove_subtree(nghttp2_stream *stream)
|
|||
if(dep_prev) {
|
||||
dep_prev->sum_dep_weight -= stream->weight;
|
||||
|
||||
stream_update_dep_effective_weight(dep_prev);
|
||||
root_stream = stream_update_dep_length(dep_prev, -stream->num_substreams);
|
||||
|
||||
stream_update_dep_length(dep_prev, -stream->num_substreams);
|
||||
stream_update_dep_sum_norest_weight(root_stream);
|
||||
stream_update_dep_effective_weight(root_stream);
|
||||
}
|
||||
|
||||
stream->sib_prev = NULL;
|
||||
|
@ -794,14 +832,15 @@ int nghttp2_stream_dep_make_root(nghttp2_stream *stream, nghttp2_pq *pq)
|
|||
|
||||
stream->effective_weight = stream->weight;
|
||||
|
||||
stream_update_dep_effective_weight(stream);
|
||||
|
||||
rv = stream_update_dep_set_top(stream, pq);
|
||||
|
||||
if(rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
stream_update_dep_sum_norest_weight(stream);
|
||||
stream_update_dep_effective_weight(stream);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -164,6 +164,10 @@ struct nghttp2_stream {
|
|||
int32_t effective_weight;
|
||||
/* sum of weight (not effective_weight) of direct descendants */
|
||||
int32_t sum_dep_weight;
|
||||
/* sum of weight of direct descendants which have at least one
|
||||
descendant with dpri == NGHTTP2_STREAM_DPRI_TOP. We use this
|
||||
value to calculate effective weight. */
|
||||
int32_t sum_norest_weight;
|
||||
nghttp2_stream_state state;
|
||||
/* This is bitwise-OR of 0 or more of nghttp2_stream_flag. */
|
||||
uint8_t flags;
|
||||
|
|
|
@ -228,8 +228,6 @@ int main(int argc, char* argv[])
|
|||
test_nghttp2_session_stream_attach_data) ||
|
||||
!CU_add_test(pSuite, "session_stream_attach_data_subtree",
|
||||
test_nghttp2_session_stream_attach_data_subtree) ||
|
||||
!CU_add_test(pSuite, "session_stream_dep_effective_weight",
|
||||
test_nghttp2_session_stream_dep_effective_weight) ||
|
||||
!CU_add_test(pSuite, "session_stream_keep_closed_stream",
|
||||
test_nghttp2_session_keep_closed_stream) ||
|
||||
!CU_add_test(pSuite, "frame_pack_headers",
|
||||
|
|
|
@ -5523,17 +5523,6 @@ void test_nghttp2_session_stream_dep_all_your_stream_are_belong_to_us(void)
|
|||
nghttp2_session_del(session);
|
||||
}
|
||||
|
||||
static nghttp2_outbound_item* create_data_ob_item(void)
|
||||
{
|
||||
nghttp2_outbound_item *item;
|
||||
|
||||
item = malloc(sizeof(nghttp2_outbound_item));
|
||||
memset(item, 0, sizeof(nghttp2_outbound_item));
|
||||
item->frame_cat = NGHTTP2_CAT_DATA;
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
void test_nghttp2_session_stream_attach_data(void)
|
||||
{
|
||||
nghttp2_session *session;
|
||||
|
@ -5566,6 +5555,10 @@ void test_nghttp2_session_stream_attach_data(void)
|
|||
CU_ASSERT(NGHTTP2_STREAM_DPRI_NO_DATA == c->dpri);
|
||||
CU_ASSERT(NGHTTP2_STREAM_DPRI_NO_DATA == d->dpri);
|
||||
|
||||
CU_ASSERT(16 == b->effective_weight);
|
||||
|
||||
CU_ASSERT(16 == a->sum_norest_weight);
|
||||
|
||||
CU_ASSERT(1 == db->queued);
|
||||
|
||||
dc = create_data_ob_item();
|
||||
|
@ -5577,6 +5570,11 @@ void test_nghttp2_session_stream_attach_data(void)
|
|||
CU_ASSERT(NGHTTP2_STREAM_DPRI_TOP == c->dpri);
|
||||
CU_ASSERT(NGHTTP2_STREAM_DPRI_NO_DATA == d->dpri);
|
||||
|
||||
CU_ASSERT(16 * 16 / 32 == b->effective_weight);
|
||||
CU_ASSERT(16 * 16 / 32 == c->effective_weight);
|
||||
|
||||
CU_ASSERT(32 == a->sum_norest_weight);
|
||||
|
||||
CU_ASSERT(1 == dc->queued);
|
||||
|
||||
da = create_data_ob_item();
|
||||
|
@ -5588,6 +5586,8 @@ void test_nghttp2_session_stream_attach_data(void)
|
|||
CU_ASSERT(NGHTTP2_STREAM_DPRI_REST == c->dpri);
|
||||
CU_ASSERT(NGHTTP2_STREAM_DPRI_NO_DATA == d->dpri);
|
||||
|
||||
CU_ASSERT(16 == a->effective_weight);
|
||||
|
||||
CU_ASSERT(1 == da->queued);
|
||||
|
||||
nghttp2_stream_detach_data(a, &session->ob_pq);
|
||||
|
@ -5597,6 +5597,9 @@ void test_nghttp2_session_stream_attach_data(void)
|
|||
CU_ASSERT(NGHTTP2_STREAM_DPRI_TOP == c->dpri);
|
||||
CU_ASSERT(NGHTTP2_STREAM_DPRI_NO_DATA == d->dpri);
|
||||
|
||||
CU_ASSERT(16 * 16 / 32 == b->effective_weight);
|
||||
CU_ASSERT(16 * 16 / 32 == c->effective_weight);
|
||||
|
||||
dd = create_data_ob_item();
|
||||
|
||||
nghttp2_stream_attach_data(d, dd, &session->ob_pq);
|
||||
|
@ -5606,6 +5609,9 @@ void test_nghttp2_session_stream_attach_data(void)
|
|||
CU_ASSERT(NGHTTP2_STREAM_DPRI_TOP == c->dpri);
|
||||
CU_ASSERT(NGHTTP2_STREAM_DPRI_REST == d->dpri);
|
||||
|
||||
CU_ASSERT(16 * 16 / 32 == b->effective_weight);
|
||||
CU_ASSERT(16 * 16 / 32 == c->effective_weight);
|
||||
|
||||
CU_ASSERT(0 == dd->queued);
|
||||
|
||||
nghttp2_stream_detach_data(c, &session->ob_pq);
|
||||
|
@ -5615,6 +5621,9 @@ void test_nghttp2_session_stream_attach_data(void)
|
|||
CU_ASSERT(NGHTTP2_STREAM_DPRI_NO_DATA == c->dpri);
|
||||
CU_ASSERT(NGHTTP2_STREAM_DPRI_TOP == d->dpri);
|
||||
|
||||
CU_ASSERT(16 * 16 / 32 == b->effective_weight);
|
||||
CU_ASSERT(16 * 16 / 32 == d->effective_weight);
|
||||
|
||||
CU_ASSERT(1 == dd->queued);
|
||||
|
||||
nghttp2_session_del(session);
|
||||
|
@ -5661,6 +5670,9 @@ void test_nghttp2_session_stream_attach_data_subtree(void)
|
|||
CU_ASSERT(NGHTTP2_STREAM_DPRI_TOP == e->dpri);
|
||||
CU_ASSERT(NGHTTP2_STREAM_DPRI_NO_DATA == f->dpri);
|
||||
|
||||
CU_ASSERT(16 == b->effective_weight);
|
||||
CU_ASSERT(16 == e->effective_weight);
|
||||
|
||||
/* Insert subtree e under a */
|
||||
|
||||
nghttp2_stream_dep_remove_subtree(e);
|
||||
|
@ -5683,6 +5695,8 @@ void test_nghttp2_session_stream_attach_data_subtree(void)
|
|||
CU_ASSERT(NGHTTP2_STREAM_DPRI_TOP == e->dpri);
|
||||
CU_ASSERT(NGHTTP2_STREAM_DPRI_NO_DATA == f->dpri);
|
||||
|
||||
CU_ASSERT(16 == e->effective_weight);
|
||||
|
||||
/* Remove subtree b */
|
||||
|
||||
nghttp2_stream_dep_remove_subtree(b);
|
||||
|
@ -5706,6 +5720,9 @@ void test_nghttp2_session_stream_attach_data_subtree(void)
|
|||
CU_ASSERT(NGHTTP2_STREAM_DPRI_TOP == e->dpri);
|
||||
CU_ASSERT(NGHTTP2_STREAM_DPRI_NO_DATA == f->dpri);
|
||||
|
||||
CU_ASSERT(16 == b->effective_weight);
|
||||
CU_ASSERT(16 == e->effective_weight);
|
||||
|
||||
/* Remove subtree a */
|
||||
|
||||
nghttp2_stream_dep_remove_subtree(a);
|
||||
|
@ -5764,6 +5781,13 @@ void test_nghttp2_session_stream_attach_data_subtree(void)
|
|||
CU_ASSERT(NGHTTP2_STREAM_DPRI_TOP == e->dpri);
|
||||
CU_ASSERT(NGHTTP2_STREAM_DPRI_NO_DATA == f->dpri);
|
||||
|
||||
CU_ASSERT(16 == b->effective_weight);
|
||||
CU_ASSERT(16 * 16 / 32 == e->effective_weight);
|
||||
CU_ASSERT(16 * 16 / 32 == d->effective_weight);
|
||||
|
||||
CU_ASSERT(32 == a->sum_norest_weight);
|
||||
CU_ASSERT(16 == c->sum_norest_weight);
|
||||
|
||||
/* Insert b under a */
|
||||
|
||||
nghttp2_stream_dep_remove_subtree(b);
|
||||
|
@ -5786,6 +5810,11 @@ void test_nghttp2_session_stream_attach_data_subtree(void)
|
|||
CU_ASSERT(NGHTTP2_STREAM_DPRI_REST == e->dpri);
|
||||
CU_ASSERT(NGHTTP2_STREAM_DPRI_NO_DATA == f->dpri);
|
||||
|
||||
CU_ASSERT(16 == b->effective_weight);
|
||||
|
||||
CU_ASSERT(16 == a->sum_norest_weight);
|
||||
CU_ASSERT(0 == b->sum_norest_weight);
|
||||
|
||||
/* Remove subtree b */
|
||||
|
||||
nghttp2_stream_dep_remove_subtree(b);
|
||||
|
@ -5806,287 +5835,8 @@ void test_nghttp2_session_stream_attach_data_subtree(void)
|
|||
CU_ASSERT(NGHTTP2_STREAM_DPRI_REST == e->dpri);
|
||||
CU_ASSERT(NGHTTP2_STREAM_DPRI_NO_DATA == f->dpri);
|
||||
|
||||
nghttp2_session_del(session);
|
||||
}
|
||||
|
||||
void test_nghttp2_session_stream_dep_effective_weight(void)
|
||||
{
|
||||
nghttp2_session *session;
|
||||
nghttp2_session_callbacks callbacks;
|
||||
nghttp2_stream *a, *b, *c, *d, *e, *f, *g;
|
||||
|
||||
memset(&callbacks, 0, sizeof(callbacks));
|
||||
|
||||
nghttp2_session_server_new(&session, &callbacks, NULL);
|
||||
|
||||
a = open_stream(session, 1);
|
||||
b = open_stream_with_dep_weight(session, 3, 8, a);
|
||||
c = open_stream_with_dep_weight(session, 5, 4, a);
|
||||
d = open_stream_with_dep_weight(session, 7, 1, c);
|
||||
e = open_stream_with_dep_weight(session, 9, 2, c);
|
||||
|
||||
/* a
|
||||
* |
|
||||
* b--c
|
||||
* |
|
||||
* d--e
|
||||
*/
|
||||
|
||||
CU_ASSERT(NGHTTP2_DEFAULT_WEIGHT == a->effective_weight);
|
||||
CU_ASSERT(16 * 8 / 12 == b->effective_weight);
|
||||
CU_ASSERT(16 * 4 / 12 == c->effective_weight);
|
||||
CU_ASSERT((16 * 4 / 12) * 1 / 3 == d->effective_weight);
|
||||
CU_ASSERT((16 * 4 / 12) * 2 / 3 == e->effective_weight);
|
||||
|
||||
/* Remove a */
|
||||
|
||||
nghttp2_stream_dep_remove(a);
|
||||
|
||||
/*
|
||||
* b c
|
||||
* |
|
||||
* d--e
|
||||
*/
|
||||
|
||||
CU_ASSERT(16 * 8 / 12 == b->effective_weight);
|
||||
CU_ASSERT(16 * 4 / 12 == c->effective_weight);
|
||||
CU_ASSERT((16 * 4 / 12) * 1 / 3 == d->effective_weight);
|
||||
CU_ASSERT((16 * 4 / 12) * 2 / 3 == e->effective_weight);
|
||||
|
||||
/* weight is updated for b and c */
|
||||
CU_ASSERT(16 * 8 / 12 == b->weight);
|
||||
CU_ASSERT(16 * 4 / 12 == c->weight);
|
||||
/* weight remains same for d and e */
|
||||
CU_ASSERT(1 == d->weight);
|
||||
CU_ASSERT(2 == e->weight);
|
||||
|
||||
/* Remove d */
|
||||
|
||||
nghttp2_stream_dep_remove(d);
|
||||
|
||||
/*
|
||||
* c d
|
||||
* |
|
||||
* e
|
||||
*/
|
||||
|
||||
CU_ASSERT(16 * 4 / 12 == c->effective_weight);
|
||||
CU_ASSERT(16 * 4 / 12 == e->effective_weight);
|
||||
|
||||
nghttp2_session_del(session);
|
||||
|
||||
nghttp2_session_server_new(&session, &callbacks, NULL);
|
||||
|
||||
a = open_stream(session, 1);
|
||||
b = open_stream_with_dep_weight(session, 3, 8, a);
|
||||
c = open_stream_with_dep_weight(session, 5, 4, a);
|
||||
d = open_stream_with_dep_weight(session, 7, 1, c);
|
||||
e = open_stream_with_dep_weight(session, 9, 2, c);
|
||||
|
||||
/* a
|
||||
* |
|
||||
* b--c
|
||||
* |
|
||||
* d--e
|
||||
*/
|
||||
|
||||
/* Remove c */
|
||||
|
||||
nghttp2_stream_dep_remove(c);
|
||||
|
||||
/* a
|
||||
* |
|
||||
* b--d--e
|
||||
*/
|
||||
|
||||
/* weight for d and e is updated */
|
||||
CU_ASSERT(1/*4 * 1 / 3*/ == d->weight);
|
||||
CU_ASSERT(4 * 2 / 3 == e->weight);
|
||||
|
||||
CU_ASSERT(16 * 8 / 11 == b->effective_weight);
|
||||
CU_ASSERT(16 * 1 / 11 == d->effective_weight);
|
||||
CU_ASSERT(16 * 2 / 11 == e->effective_weight);
|
||||
|
||||
nghttp2_session_del(session);
|
||||
|
||||
nghttp2_session_server_new(&session, &callbacks, NULL);
|
||||
|
||||
a = open_stream(session, 1);
|
||||
b = open_stream_with_dep_weight(session, 3, 8, a);
|
||||
c = open_stream_with_dep_weight(session, 5, 4, a);
|
||||
d = open_stream_with_dep_weight(session, 7, 1, c);
|
||||
e = open_stream_with_dep_weight(session, 9, 2, c);
|
||||
|
||||
/* a
|
||||
* |
|
||||
* b--c
|
||||
* |
|
||||
* d--e
|
||||
*/
|
||||
|
||||
/* Insert f under a */
|
||||
f = open_stream_with_dep_excl(session, 11, a);
|
||||
|
||||
/* a
|
||||
* |
|
||||
* f
|
||||
* |
|
||||
* b--c
|
||||
* |
|
||||
* d--e
|
||||
*/
|
||||
|
||||
CU_ASSERT(NGHTTP2_DEFAULT_WEIGHT == a->effective_weight);
|
||||
CU_ASSERT(NGHTTP2_DEFAULT_WEIGHT == f->effective_weight);
|
||||
CU_ASSERT(16 * 8 / 12 == b->effective_weight);
|
||||
CU_ASSERT(16 * 4 / 12 == c->effective_weight);
|
||||
CU_ASSERT((16 * 4 / 12) * 1 / 3 == d->effective_weight);
|
||||
CU_ASSERT((16 * 4 / 12) * 2 / 3 == e->effective_weight);
|
||||
|
||||
/* Add g under f */
|
||||
g = open_stream_with_dep_weight(session, 13, 2, f);
|
||||
|
||||
/* a
|
||||
* |
|
||||
* f
|
||||
* |
|
||||
* b--c--g
|
||||
* |
|
||||
* d--e
|
||||
*/
|
||||
|
||||
CU_ASSERT(NGHTTP2_DEFAULT_WEIGHT == a->effective_weight);
|
||||
CU_ASSERT(NGHTTP2_DEFAULT_WEIGHT == f->effective_weight);
|
||||
CU_ASSERT(16 * 8 / 14 == b->effective_weight);
|
||||
CU_ASSERT(16 * 4 / 14 == c->effective_weight);
|
||||
CU_ASSERT(16 * 2 / 14 == g->effective_weight);
|
||||
CU_ASSERT((16 * 4 / 14) * 1 / 3 == d->effective_weight);
|
||||
CU_ASSERT((16 * 4 / 14) * 2 / 3 == e->effective_weight);
|
||||
|
||||
nghttp2_session_del(session);
|
||||
|
||||
nghttp2_session_server_new(&session, &callbacks, NULL);
|
||||
|
||||
a = open_stream(session, 1);
|
||||
b = open_stream_with_dep_weight(session, 3, 8, a);
|
||||
c = open_stream_with_dep_weight(session, 5, 4, a);
|
||||
d = open_stream_with_dep_weight(session, 7, 1, c);
|
||||
|
||||
e = open_stream(session, 9);
|
||||
f = open_stream_with_dep_weight(session, 11, 12, e);
|
||||
|
||||
/* a e
|
||||
* | |
|
||||
* b--c f
|
||||
* |
|
||||
* d
|
||||
*/
|
||||
|
||||
/* Insert e under a */
|
||||
nghttp2_stream_dep_insert_subtree(a, e, &session->ob_pq);
|
||||
|
||||
/* a
|
||||
* |
|
||||
* e
|
||||
* |
|
||||
* b--c--f
|
||||
* |
|
||||
* d
|
||||
*/
|
||||
|
||||
CU_ASSERT(NGHTTP2_DEFAULT_WEIGHT == e->effective_weight);
|
||||
CU_ASSERT(16 * 8 / 24 == b->effective_weight);
|
||||
CU_ASSERT(16 * 4 / 24 == c->effective_weight);
|
||||
CU_ASSERT(16 * 12 / 24 == f->effective_weight);
|
||||
CU_ASSERT(16 * 4 / 24 == d->effective_weight);
|
||||
|
||||
/* Remove subtree c */
|
||||
nghttp2_stream_dep_remove_subtree(c);
|
||||
nghttp2_stream_dep_make_root(c, &session->ob_pq);
|
||||
|
||||
/* a c
|
||||
* | |
|
||||
* e d
|
||||
* |
|
||||
* b--f
|
||||
*/
|
||||
|
||||
CU_ASSERT(NGHTTP2_DEFAULT_WEIGHT == e->effective_weight);
|
||||
CU_ASSERT(16 * 8 / 20 == b->effective_weight);
|
||||
CU_ASSERT(16 * 12 / 20 == f->effective_weight);
|
||||
|
||||
CU_ASSERT(4 == c->effective_weight);
|
||||
CU_ASSERT(4 == d->effective_weight);
|
||||
|
||||
/* Add subtree c under a */
|
||||
nghttp2_stream_dep_add_subtree(a, c, &session->ob_pq);
|
||||
|
||||
/* a
|
||||
* |
|
||||
* e-----c
|
||||
* | |
|
||||
* b--f d
|
||||
*/
|
||||
|
||||
CU_ASSERT(16 * 16 / 20 == e->effective_weight);
|
||||
CU_ASSERT(16 * 4 / 20 == c->effective_weight);
|
||||
|
||||
CU_ASSERT((16 * 16 / 20) * 8 / 20 == b->effective_weight);
|
||||
CU_ASSERT((16 * 16 / 20) * 12 / 20 == f->effective_weight);
|
||||
|
||||
CU_ASSERT(16 * 4 / 20 == d->effective_weight);
|
||||
|
||||
nghttp2_session_del(session);
|
||||
|
||||
nghttp2_session_server_new(&session, &callbacks, NULL);
|
||||
|
||||
a = open_stream(session, 1);
|
||||
b = open_stream_with_dep_weight(session, 3, 8, a);
|
||||
c = open_stream_with_dep_weight(session, 5, 4, a);
|
||||
d = open_stream_with_dep_weight(session, 7, 1, c);
|
||||
|
||||
e = open_stream(session, 9);
|
||||
f = open_stream_with_dep_weight(session, 11, 12, e);
|
||||
|
||||
/* a e
|
||||
* | |
|
||||
* b--c f
|
||||
* |
|
||||
* d
|
||||
*/
|
||||
|
||||
CU_ASSERT(e->roots->head == e);
|
||||
CU_ASSERT(a == e->root_next);
|
||||
|
||||
/* Insert e under stream 0 */
|
||||
nghttp2_stream_dep_remove_subtree(e);
|
||||
|
||||
CU_ASSERT(a == e->roots->head);
|
||||
|
||||
CU_ASSERT(0 == nghttp2_stream_dep_all_your_stream_are_belong_to_us
|
||||
(e, &session->ob_pq));
|
||||
|
||||
/* e
|
||||
* |
|
||||
* f--a
|
||||
* |
|
||||
* b--c
|
||||
* |
|
||||
* d
|
||||
*/
|
||||
|
||||
CU_ASSERT(6 == e->num_substreams);
|
||||
CU_ASSERT(28 == e->sum_dep_weight);
|
||||
|
||||
CU_ASSERT(16 == e->effective_weight);
|
||||
|
||||
CU_ASSERT(16 * 16 / 28 == a->effective_weight);
|
||||
CU_ASSERT(16 * 12 / 28 == f->effective_weight);
|
||||
|
||||
CU_ASSERT((16 * 16 / 28) * 8 / 12 == b->effective_weight);
|
||||
CU_ASSERT((16 * 16 / 28) * 4 / 12 == c->effective_weight);
|
||||
|
||||
CU_ASSERT((16 * 16 / 28) * 4 / 12 == d->effective_weight);
|
||||
CU_ASSERT(0 == a->sum_norest_weight);
|
||||
CU_ASSERT(0 == b->sum_norest_weight);
|
||||
|
||||
nghttp2_session_del(session);
|
||||
}
|
||||
|
|
|
@ -106,7 +106,6 @@ void test_nghttp2_session_stream_dep_remove_subtree(void);
|
|||
void test_nghttp2_session_stream_dep_all_your_stream_are_belong_to_us(void);
|
||||
void test_nghttp2_session_stream_attach_data(void);
|
||||
void test_nghttp2_session_stream_attach_data_subtree(void);
|
||||
void test_nghttp2_session_stream_dep_effective_weight(void);
|
||||
void test_nghttp2_session_keep_closed_stream(void);
|
||||
|
||||
#endif /* NGHTTP2_SESSION_TEST_H */
|
||||
|
|
|
@ -232,11 +232,22 @@ void bufs_large_init(nghttp2_bufs *bufs, size_t chunk_size)
|
|||
nghttp2_bufs_init2(bufs, chunk_size, 16, NGHTTP2_FRAME_HDLEN + 2);
|
||||
}
|
||||
|
||||
nghttp2_stream* open_stream(nghttp2_session *session, int32_t stream_id)
|
||||
static nghttp2_stream* open_stream_with_all(nghttp2_session *session,
|
||||
int32_t stream_id,
|
||||
int32_t weight,
|
||||
uint8_t exclusive,
|
||||
nghttp2_stream *dep_stream)
|
||||
{
|
||||
nghttp2_priority_spec pri_spec;
|
||||
int32_t dep_stream_id;
|
||||
|
||||
nghttp2_priority_spec_default_init(&pri_spec);
|
||||
if(dep_stream) {
|
||||
dep_stream_id = dep_stream->stream_id;
|
||||
} else {
|
||||
dep_stream_id = 0;
|
||||
}
|
||||
|
||||
nghttp2_priority_spec_init(&pri_spec, dep_stream_id, weight, exclusive);
|
||||
|
||||
return nghttp2_session_open_stream(session, stream_id,
|
||||
NGHTTP2_STREAM_FLAG_NONE,
|
||||
|
@ -245,12 +256,19 @@ nghttp2_stream* open_stream(nghttp2_session *session, int32_t stream_id)
|
|||
NULL);
|
||||
}
|
||||
|
||||
|
||||
nghttp2_stream* open_stream(nghttp2_session *session, int32_t stream_id)
|
||||
{
|
||||
return open_stream_with_all(session, stream_id, NGHTTP2_DEFAULT_WEIGHT, 0,
|
||||
NULL);
|
||||
}
|
||||
|
||||
nghttp2_stream* open_stream_with_dep(nghttp2_session *session,
|
||||
int32_t stream_id,
|
||||
nghttp2_stream *dep_stream)
|
||||
{
|
||||
return open_stream_with_dep_weight(session, stream_id,
|
||||
NGHTTP2_DEFAULT_WEIGHT, dep_stream);
|
||||
return open_stream_with_all(session, stream_id, NGHTTP2_DEFAULT_WEIGHT, 0,
|
||||
dep_stream);
|
||||
}
|
||||
|
||||
nghttp2_stream* open_stream_with_dep_weight(nghttp2_session *session,
|
||||
|
@ -258,29 +276,25 @@ nghttp2_stream* open_stream_with_dep_weight(nghttp2_session *session,
|
|||
int32_t weight,
|
||||
nghttp2_stream *dep_stream)
|
||||
{
|
||||
nghttp2_priority_spec pri_spec;
|
||||
|
||||
nghttp2_priority_spec_init(&pri_spec, dep_stream->stream_id, weight, 0);
|
||||
|
||||
return nghttp2_session_open_stream(session, stream_id,
|
||||
NGHTTP2_STREAM_FLAG_NONE,
|
||||
&pri_spec,
|
||||
NGHTTP2_STREAM_OPENED,
|
||||
NULL);
|
||||
return open_stream_with_all(session, stream_id, weight, 0, dep_stream);
|
||||
}
|
||||
|
||||
nghttp2_stream* open_stream_with_dep_excl(nghttp2_session *session,
|
||||
int32_t stream_id,
|
||||
nghttp2_stream *dep_stream)
|
||||
{
|
||||
nghttp2_priority_spec pri_spec;
|
||||
|
||||
nghttp2_priority_spec_init(&pri_spec, dep_stream->stream_id,
|
||||
NGHTTP2_DEFAULT_WEIGHT, 1);
|
||||
|
||||
return nghttp2_session_open_stream(session, stream_id,
|
||||
NGHTTP2_STREAM_FLAG_NONE,
|
||||
&pri_spec,
|
||||
NGHTTP2_STREAM_OPENED,
|
||||
NULL);
|
||||
return open_stream_with_all(session, stream_id, NGHTTP2_DEFAULT_WEIGHT, 1,
|
||||
dep_stream);
|
||||
}
|
||||
|
||||
nghttp2_outbound_item* create_data_ob_item(void)
|
||||
{
|
||||
nghttp2_outbound_item *item;
|
||||
|
||||
item = malloc(sizeof(nghttp2_outbound_item));
|
||||
memset(item, 0, sizeof(nghttp2_outbound_item));
|
||||
item->frame_cat = NGHTTP2_CAT_DATA;
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
|
|
|
@ -98,4 +98,6 @@ nghttp2_stream* open_stream_with_dep_excl(nghttp2_session *session,
|
|||
int32_t stream_id,
|
||||
nghttp2_stream *dep_stream);
|
||||
|
||||
nghttp2_outbound_item* create_data_ob_item(void);
|
||||
|
||||
#endif /* NGHTTP2_TEST_HELPER_H */
|
||||
|
|
Loading…
Reference in New Issue