11cb0ef41Sopenharmony_ci/* 21cb0ef41Sopenharmony_ci * nghttp3 31cb0ef41Sopenharmony_ci * 41cb0ef41Sopenharmony_ci * Copyright (c) 2019 nghttp3 contributors 51cb0ef41Sopenharmony_ci * Copyright (c) 2017 ngtcp2 contributors 61cb0ef41Sopenharmony_ci * Copyright (c) 2012 nghttp2 contributors 71cb0ef41Sopenharmony_ci * 81cb0ef41Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining 91cb0ef41Sopenharmony_ci * a copy of this software and associated documentation files (the 101cb0ef41Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 111cb0ef41Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 121cb0ef41Sopenharmony_ci * distribute, sublicense, and/or sell copies of the Software, and to 131cb0ef41Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 141cb0ef41Sopenharmony_ci * the following conditions: 151cb0ef41Sopenharmony_ci * 161cb0ef41Sopenharmony_ci * The above copyright notice and this permission notice shall be 171cb0ef41Sopenharmony_ci * included in all copies or substantial portions of the Software. 181cb0ef41Sopenharmony_ci * 191cb0ef41Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 201cb0ef41Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 211cb0ef41Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 221cb0ef41Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 231cb0ef41Sopenharmony_ci * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 241cb0ef41Sopenharmony_ci * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 251cb0ef41Sopenharmony_ci * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 261cb0ef41Sopenharmony_ci */ 271cb0ef41Sopenharmony_ci#include "nghttp3_pq.h" 281cb0ef41Sopenharmony_ci 291cb0ef41Sopenharmony_ci#include <assert.h> 301cb0ef41Sopenharmony_ci 311cb0ef41Sopenharmony_ci#include "nghttp3_macro.h" 321cb0ef41Sopenharmony_ci 331cb0ef41Sopenharmony_civoid nghttp3_pq_init(nghttp3_pq *pq, nghttp3_less less, 341cb0ef41Sopenharmony_ci const nghttp3_mem *mem) { 351cb0ef41Sopenharmony_ci pq->mem = mem; 361cb0ef41Sopenharmony_ci pq->capacity = 0; 371cb0ef41Sopenharmony_ci pq->q = NULL; 381cb0ef41Sopenharmony_ci pq->length = 0; 391cb0ef41Sopenharmony_ci pq->less = less; 401cb0ef41Sopenharmony_ci} 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_civoid nghttp3_pq_free(nghttp3_pq *pq) { 431cb0ef41Sopenharmony_ci nghttp3_mem_free(pq->mem, pq->q); 441cb0ef41Sopenharmony_ci pq->q = NULL; 451cb0ef41Sopenharmony_ci} 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_cistatic void swap(nghttp3_pq *pq, size_t i, size_t j) { 481cb0ef41Sopenharmony_ci nghttp3_pq_entry *a = pq->q[i]; 491cb0ef41Sopenharmony_ci nghttp3_pq_entry *b = pq->q[j]; 501cb0ef41Sopenharmony_ci 511cb0ef41Sopenharmony_ci pq->q[i] = b; 521cb0ef41Sopenharmony_ci b->index = i; 531cb0ef41Sopenharmony_ci pq->q[j] = a; 541cb0ef41Sopenharmony_ci a->index = j; 551cb0ef41Sopenharmony_ci} 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_cistatic void bubble_up(nghttp3_pq *pq, size_t index) { 581cb0ef41Sopenharmony_ci size_t parent; 591cb0ef41Sopenharmony_ci while (index != 0) { 601cb0ef41Sopenharmony_ci parent = (index - 1) / 2; 611cb0ef41Sopenharmony_ci if (!pq->less(pq->q[index], pq->q[parent])) { 621cb0ef41Sopenharmony_ci return; 631cb0ef41Sopenharmony_ci } 641cb0ef41Sopenharmony_ci swap(pq, parent, index); 651cb0ef41Sopenharmony_ci index = parent; 661cb0ef41Sopenharmony_ci } 671cb0ef41Sopenharmony_ci} 681cb0ef41Sopenharmony_ci 691cb0ef41Sopenharmony_ciint nghttp3_pq_push(nghttp3_pq *pq, nghttp3_pq_entry *item) { 701cb0ef41Sopenharmony_ci if (pq->capacity <= pq->length) { 711cb0ef41Sopenharmony_ci void *nq; 721cb0ef41Sopenharmony_ci size_t ncapacity; 731cb0ef41Sopenharmony_ci 741cb0ef41Sopenharmony_ci ncapacity = nghttp3_max(4, (pq->capacity * 2)); 751cb0ef41Sopenharmony_ci 761cb0ef41Sopenharmony_ci nq = nghttp3_mem_realloc(pq->mem, pq->q, 771cb0ef41Sopenharmony_ci ncapacity * sizeof(nghttp3_pq_entry *)); 781cb0ef41Sopenharmony_ci if (nq == NULL) { 791cb0ef41Sopenharmony_ci return NGHTTP3_ERR_NOMEM; 801cb0ef41Sopenharmony_ci } 811cb0ef41Sopenharmony_ci pq->capacity = ncapacity; 821cb0ef41Sopenharmony_ci pq->q = nq; 831cb0ef41Sopenharmony_ci } 841cb0ef41Sopenharmony_ci pq->q[pq->length] = item; 851cb0ef41Sopenharmony_ci item->index = pq->length; 861cb0ef41Sopenharmony_ci ++pq->length; 871cb0ef41Sopenharmony_ci bubble_up(pq, pq->length - 1); 881cb0ef41Sopenharmony_ci return 0; 891cb0ef41Sopenharmony_ci} 901cb0ef41Sopenharmony_ci 911cb0ef41Sopenharmony_cinghttp3_pq_entry *nghttp3_pq_top(const nghttp3_pq *pq) { 921cb0ef41Sopenharmony_ci assert(pq->length); 931cb0ef41Sopenharmony_ci return pq->q[0]; 941cb0ef41Sopenharmony_ci} 951cb0ef41Sopenharmony_ci 961cb0ef41Sopenharmony_cistatic void bubble_down(nghttp3_pq *pq, size_t index) { 971cb0ef41Sopenharmony_ci size_t i, j, minindex; 981cb0ef41Sopenharmony_ci for (;;) { 991cb0ef41Sopenharmony_ci j = index * 2 + 1; 1001cb0ef41Sopenharmony_ci minindex = index; 1011cb0ef41Sopenharmony_ci for (i = 0; i < 2; ++i, ++j) { 1021cb0ef41Sopenharmony_ci if (j >= pq->length) { 1031cb0ef41Sopenharmony_ci break; 1041cb0ef41Sopenharmony_ci } 1051cb0ef41Sopenharmony_ci if (pq->less(pq->q[j], pq->q[minindex])) { 1061cb0ef41Sopenharmony_ci minindex = j; 1071cb0ef41Sopenharmony_ci } 1081cb0ef41Sopenharmony_ci } 1091cb0ef41Sopenharmony_ci if (minindex == index) { 1101cb0ef41Sopenharmony_ci return; 1111cb0ef41Sopenharmony_ci } 1121cb0ef41Sopenharmony_ci swap(pq, index, minindex); 1131cb0ef41Sopenharmony_ci index = minindex; 1141cb0ef41Sopenharmony_ci } 1151cb0ef41Sopenharmony_ci} 1161cb0ef41Sopenharmony_ci 1171cb0ef41Sopenharmony_civoid nghttp3_pq_pop(nghttp3_pq *pq) { 1181cb0ef41Sopenharmony_ci if (pq->length > 0) { 1191cb0ef41Sopenharmony_ci pq->q[0] = pq->q[pq->length - 1]; 1201cb0ef41Sopenharmony_ci pq->q[0]->index = 0; 1211cb0ef41Sopenharmony_ci --pq->length; 1221cb0ef41Sopenharmony_ci bubble_down(pq, 0); 1231cb0ef41Sopenharmony_ci } 1241cb0ef41Sopenharmony_ci} 1251cb0ef41Sopenharmony_ci 1261cb0ef41Sopenharmony_civoid nghttp3_pq_remove(nghttp3_pq *pq, nghttp3_pq_entry *item) { 1271cb0ef41Sopenharmony_ci assert(pq->q[item->index] == item); 1281cb0ef41Sopenharmony_ci 1291cb0ef41Sopenharmony_ci if (item->index == 0) { 1301cb0ef41Sopenharmony_ci nghttp3_pq_pop(pq); 1311cb0ef41Sopenharmony_ci return; 1321cb0ef41Sopenharmony_ci } 1331cb0ef41Sopenharmony_ci 1341cb0ef41Sopenharmony_ci if (item->index == pq->length - 1) { 1351cb0ef41Sopenharmony_ci --pq->length; 1361cb0ef41Sopenharmony_ci return; 1371cb0ef41Sopenharmony_ci } 1381cb0ef41Sopenharmony_ci 1391cb0ef41Sopenharmony_ci pq->q[item->index] = pq->q[pq->length - 1]; 1401cb0ef41Sopenharmony_ci pq->q[item->index]->index = item->index; 1411cb0ef41Sopenharmony_ci --pq->length; 1421cb0ef41Sopenharmony_ci 1431cb0ef41Sopenharmony_ci if (pq->less(item, pq->q[item->index])) { 1441cb0ef41Sopenharmony_ci bubble_down(pq, item->index); 1451cb0ef41Sopenharmony_ci } else { 1461cb0ef41Sopenharmony_ci bubble_up(pq, item->index); 1471cb0ef41Sopenharmony_ci } 1481cb0ef41Sopenharmony_ci} 1491cb0ef41Sopenharmony_ci 1501cb0ef41Sopenharmony_ciint nghttp3_pq_empty(const nghttp3_pq *pq) { return pq->length == 0; } 1511cb0ef41Sopenharmony_ci 1521cb0ef41Sopenharmony_cisize_t nghttp3_pq_size(const nghttp3_pq *pq) { return pq->length; } 1531cb0ef41Sopenharmony_ci 1541cb0ef41Sopenharmony_ciint nghttp3_pq_each(const nghttp3_pq *pq, nghttp3_pq_item_cb fun, void *arg) { 1551cb0ef41Sopenharmony_ci size_t i; 1561cb0ef41Sopenharmony_ci 1571cb0ef41Sopenharmony_ci if (pq->length == 0) { 1581cb0ef41Sopenharmony_ci return 0; 1591cb0ef41Sopenharmony_ci } 1601cb0ef41Sopenharmony_ci for (i = 0; i < pq->length; ++i) { 1611cb0ef41Sopenharmony_ci if ((*fun)(pq->q[i], arg)) { 1621cb0ef41Sopenharmony_ci return 1; 1631cb0ef41Sopenharmony_ci } 1641cb0ef41Sopenharmony_ci } 1651cb0ef41Sopenharmony_ci return 0; 1661cb0ef41Sopenharmony_ci} 1671cb0ef41Sopenharmony_ci 1681cb0ef41Sopenharmony_civoid nghttp3_pq_clear(nghttp3_pq *pq) { pq->length = 0; } 169