11cb0ef41Sopenharmony_ci/* 21cb0ef41Sopenharmony_ci * ngtcp2 31cb0ef41Sopenharmony_ci * 41cb0ef41Sopenharmony_ci * Copyright (c) 2018 ngtcp2 contributors 51cb0ef41Sopenharmony_ci * 61cb0ef41Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining 71cb0ef41Sopenharmony_ci * a copy of this software and associated documentation files (the 81cb0ef41Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 91cb0ef41Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 101cb0ef41Sopenharmony_ci * distribute, sublicense, and/or sell copies of the Software, and to 111cb0ef41Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 121cb0ef41Sopenharmony_ci * the following conditions: 131cb0ef41Sopenharmony_ci * 141cb0ef41Sopenharmony_ci * The above copyright notice and this permission notice shall be 151cb0ef41Sopenharmony_ci * included in all copies or substantial portions of the Software. 161cb0ef41Sopenharmony_ci * 171cb0ef41Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 181cb0ef41Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 191cb0ef41Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 201cb0ef41Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 211cb0ef41Sopenharmony_ci * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 221cb0ef41Sopenharmony_ci * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 231cb0ef41Sopenharmony_ci * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 241cb0ef41Sopenharmony_ci */ 251cb0ef41Sopenharmony_ci#ifndef NGTCP2_KSL_H 261cb0ef41Sopenharmony_ci#define NGTCP2_KSL_H 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ci#ifdef HAVE_CONFIG_H 291cb0ef41Sopenharmony_ci# include <config.h> 301cb0ef41Sopenharmony_ci#endif /* HAVE_CONFIG_H */ 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_ci#include <stdlib.h> 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ci#include <ngtcp2/ngtcp2.h> 351cb0ef41Sopenharmony_ci 361cb0ef41Sopenharmony_ci#include "ngtcp2_objalloc.h" 371cb0ef41Sopenharmony_ci 381cb0ef41Sopenharmony_ci/* 391cb0ef41Sopenharmony_ci * Skip List using single key instead of range. 401cb0ef41Sopenharmony_ci */ 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_ci#define NGTCP2_KSL_DEGR 16 431cb0ef41Sopenharmony_ci/* NGTCP2_KSL_MAX_NBLK is the maximum number of nodes which a single 441cb0ef41Sopenharmony_ci block can contain. */ 451cb0ef41Sopenharmony_ci#define NGTCP2_KSL_MAX_NBLK (2 * NGTCP2_KSL_DEGR - 1) 461cb0ef41Sopenharmony_ci/* NGTCP2_KSL_MIN_NBLK is the minimum number of nodes which a single 471cb0ef41Sopenharmony_ci block other than root must contains. */ 481cb0ef41Sopenharmony_ci#define NGTCP2_KSL_MIN_NBLK (NGTCP2_KSL_DEGR - 1) 491cb0ef41Sopenharmony_ci 501cb0ef41Sopenharmony_ci/* 511cb0ef41Sopenharmony_ci * ngtcp2_ksl_key represents key in ngtcp2_ksl. 521cb0ef41Sopenharmony_ci */ 531cb0ef41Sopenharmony_citypedef void ngtcp2_ksl_key; 541cb0ef41Sopenharmony_ci 551cb0ef41Sopenharmony_citypedef struct ngtcp2_ksl_node ngtcp2_ksl_node; 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_citypedef struct ngtcp2_ksl_blk ngtcp2_ksl_blk; 581cb0ef41Sopenharmony_ci 591cb0ef41Sopenharmony_ci/* 601cb0ef41Sopenharmony_ci * ngtcp2_ksl_node is a node which contains either ngtcp2_ksl_blk or 611cb0ef41Sopenharmony_ci * opaque data. If a node is an internal node, it contains 621cb0ef41Sopenharmony_ci * ngtcp2_ksl_blk. Otherwise, it has data. The key is stored at the 631cb0ef41Sopenharmony_ci * location starting at key. 641cb0ef41Sopenharmony_ci */ 651cb0ef41Sopenharmony_cistruct ngtcp2_ksl_node { 661cb0ef41Sopenharmony_ci union { 671cb0ef41Sopenharmony_ci ngtcp2_ksl_blk *blk; 681cb0ef41Sopenharmony_ci void *data; 691cb0ef41Sopenharmony_ci }; 701cb0ef41Sopenharmony_ci union { 711cb0ef41Sopenharmony_ci uint64_t align; 721cb0ef41Sopenharmony_ci /* key is a buffer to include key associated to this node. 731cb0ef41Sopenharmony_ci Because the length of key is unknown until ngtcp2_ksl_init is 741cb0ef41Sopenharmony_ci called, the actual buffer will be allocated after this 751cb0ef41Sopenharmony_ci field. */ 761cb0ef41Sopenharmony_ci uint8_t key[1]; 771cb0ef41Sopenharmony_ci }; 781cb0ef41Sopenharmony_ci}; 791cb0ef41Sopenharmony_ci 801cb0ef41Sopenharmony_ci/* 811cb0ef41Sopenharmony_ci * ngtcp2_ksl_blk contains ngtcp2_ksl_node objects. 821cb0ef41Sopenharmony_ci */ 831cb0ef41Sopenharmony_cistruct ngtcp2_ksl_blk { 841cb0ef41Sopenharmony_ci union { 851cb0ef41Sopenharmony_ci struct { 861cb0ef41Sopenharmony_ci /* next points to the next block if leaf field is nonzero. */ 871cb0ef41Sopenharmony_ci ngtcp2_ksl_blk *next; 881cb0ef41Sopenharmony_ci /* prev points to the previous block if leaf field is nonzero. */ 891cb0ef41Sopenharmony_ci ngtcp2_ksl_blk *prev; 901cb0ef41Sopenharmony_ci /* n is the number of nodes this object contains in nodes. */ 911cb0ef41Sopenharmony_ci uint32_t n; 921cb0ef41Sopenharmony_ci /* leaf is nonzero if this block contains leaf nodes. */ 931cb0ef41Sopenharmony_ci uint32_t leaf; 941cb0ef41Sopenharmony_ci union { 951cb0ef41Sopenharmony_ci uint64_t align; 961cb0ef41Sopenharmony_ci /* nodes is a buffer to contain NGTCP2_KSL_MAX_NBLK 971cb0ef41Sopenharmony_ci ngtcp2_ksl_node objects. Because ngtcp2_ksl_node object is 981cb0ef41Sopenharmony_ci allocated along with the additional variable length key 991cb0ef41Sopenharmony_ci storage, the size of buffer is unknown until ngtcp2_ksl_init is 1001cb0ef41Sopenharmony_ci called. */ 1011cb0ef41Sopenharmony_ci uint8_t nodes[1]; 1021cb0ef41Sopenharmony_ci }; 1031cb0ef41Sopenharmony_ci }; 1041cb0ef41Sopenharmony_ci 1051cb0ef41Sopenharmony_ci ngtcp2_opl_entry oplent; 1061cb0ef41Sopenharmony_ci }; 1071cb0ef41Sopenharmony_ci}; 1081cb0ef41Sopenharmony_ci 1091cb0ef41Sopenharmony_cingtcp2_objalloc_def(ksl_blk, ngtcp2_ksl_blk, oplent); 1101cb0ef41Sopenharmony_ci 1111cb0ef41Sopenharmony_ci/* 1121cb0ef41Sopenharmony_ci * ngtcp2_ksl_compar is a function type which returns nonzero if key 1131cb0ef41Sopenharmony_ci * |lhs| should be placed before |rhs|. It returns 0 otherwise. 1141cb0ef41Sopenharmony_ci */ 1151cb0ef41Sopenharmony_citypedef int (*ngtcp2_ksl_compar)(const ngtcp2_ksl_key *lhs, 1161cb0ef41Sopenharmony_ci const ngtcp2_ksl_key *rhs); 1171cb0ef41Sopenharmony_ci 1181cb0ef41Sopenharmony_citypedef struct ngtcp2_ksl ngtcp2_ksl; 1191cb0ef41Sopenharmony_ci 1201cb0ef41Sopenharmony_citypedef struct ngtcp2_ksl_it ngtcp2_ksl_it; 1211cb0ef41Sopenharmony_ci 1221cb0ef41Sopenharmony_ci/* 1231cb0ef41Sopenharmony_ci * ngtcp2_ksl_it is a forward iterator to iterate nodes. 1241cb0ef41Sopenharmony_ci */ 1251cb0ef41Sopenharmony_cistruct ngtcp2_ksl_it { 1261cb0ef41Sopenharmony_ci const ngtcp2_ksl *ksl; 1271cb0ef41Sopenharmony_ci ngtcp2_ksl_blk *blk; 1281cb0ef41Sopenharmony_ci size_t i; 1291cb0ef41Sopenharmony_ci}; 1301cb0ef41Sopenharmony_ci 1311cb0ef41Sopenharmony_ci/* 1321cb0ef41Sopenharmony_ci * ngtcp2_ksl is a deterministic paged skip list. 1331cb0ef41Sopenharmony_ci */ 1341cb0ef41Sopenharmony_cistruct ngtcp2_ksl { 1351cb0ef41Sopenharmony_ci ngtcp2_objalloc blkalloc; 1361cb0ef41Sopenharmony_ci /* head points to the root block. */ 1371cb0ef41Sopenharmony_ci ngtcp2_ksl_blk *head; 1381cb0ef41Sopenharmony_ci /* front points to the first leaf block. */ 1391cb0ef41Sopenharmony_ci ngtcp2_ksl_blk *front; 1401cb0ef41Sopenharmony_ci /* back points to the last leaf block. */ 1411cb0ef41Sopenharmony_ci ngtcp2_ksl_blk *back; 1421cb0ef41Sopenharmony_ci ngtcp2_ksl_compar compar; 1431cb0ef41Sopenharmony_ci size_t n; 1441cb0ef41Sopenharmony_ci /* keylen is the size of key */ 1451cb0ef41Sopenharmony_ci size_t keylen; 1461cb0ef41Sopenharmony_ci /* nodelen is the actual size of ngtcp2_ksl_node including key 1471cb0ef41Sopenharmony_ci storage. */ 1481cb0ef41Sopenharmony_ci size_t nodelen; 1491cb0ef41Sopenharmony_ci}; 1501cb0ef41Sopenharmony_ci 1511cb0ef41Sopenharmony_ci/* 1521cb0ef41Sopenharmony_ci * ngtcp2_ksl_init initializes |ksl|. |compar| specifies compare 1531cb0ef41Sopenharmony_ci * function. |keylen| is the length of key. 1541cb0ef41Sopenharmony_ci */ 1551cb0ef41Sopenharmony_civoid ngtcp2_ksl_init(ngtcp2_ksl *ksl, ngtcp2_ksl_compar compar, size_t keylen, 1561cb0ef41Sopenharmony_ci const ngtcp2_mem *mem); 1571cb0ef41Sopenharmony_ci 1581cb0ef41Sopenharmony_ci/* 1591cb0ef41Sopenharmony_ci * ngtcp2_ksl_free frees resources allocated for |ksl|. If |ksl| is 1601cb0ef41Sopenharmony_ci * NULL, this function does nothing. It does not free the memory 1611cb0ef41Sopenharmony_ci * region pointed by |ksl| itself. 1621cb0ef41Sopenharmony_ci */ 1631cb0ef41Sopenharmony_civoid ngtcp2_ksl_free(ngtcp2_ksl *ksl); 1641cb0ef41Sopenharmony_ci 1651cb0ef41Sopenharmony_ci/* 1661cb0ef41Sopenharmony_ci * ngtcp2_ksl_insert inserts |key| with its associated |data|. On 1671cb0ef41Sopenharmony_ci * successful insertion, the iterator points to the inserted node is 1681cb0ef41Sopenharmony_ci * stored in |*it|. 1691cb0ef41Sopenharmony_ci * 1701cb0ef41Sopenharmony_ci * This function returns 0 if it succeeds, or one of the following 1711cb0ef41Sopenharmony_ci * negative error codes: 1721cb0ef41Sopenharmony_ci * 1731cb0ef41Sopenharmony_ci * NGTCP2_ERR_NOMEM 1741cb0ef41Sopenharmony_ci * Out of memory. 1751cb0ef41Sopenharmony_ci * NGTCP2_ERR_INVALID_ARGUMENT 1761cb0ef41Sopenharmony_ci * |key| already exists. 1771cb0ef41Sopenharmony_ci */ 1781cb0ef41Sopenharmony_ciint ngtcp2_ksl_insert(ngtcp2_ksl *ksl, ngtcp2_ksl_it *it, 1791cb0ef41Sopenharmony_ci const ngtcp2_ksl_key *key, void *data); 1801cb0ef41Sopenharmony_ci 1811cb0ef41Sopenharmony_ci/* 1821cb0ef41Sopenharmony_ci * ngtcp2_ksl_remove removes the |key| from |ksl|. 1831cb0ef41Sopenharmony_ci * 1841cb0ef41Sopenharmony_ci * This function assigns the iterator to |*it|, which points to the 1851cb0ef41Sopenharmony_ci * node which is located at the right next of the removed node if |it| 1861cb0ef41Sopenharmony_ci * is not NULL. If |key| is not found, no deletion takes place and 1871cb0ef41Sopenharmony_ci * the return value of ngtcp2_ksl_end(ksl) is assigned to |*it|. 1881cb0ef41Sopenharmony_ci * 1891cb0ef41Sopenharmony_ci * This function returns 0 if it succeeds, or one of the following 1901cb0ef41Sopenharmony_ci * negative error codes: 1911cb0ef41Sopenharmony_ci * 1921cb0ef41Sopenharmony_ci * NGTCP2_ERR_INVALID_ARGUMENT 1931cb0ef41Sopenharmony_ci * |key| does not exist. 1941cb0ef41Sopenharmony_ci */ 1951cb0ef41Sopenharmony_ciint ngtcp2_ksl_remove(ngtcp2_ksl *ksl, ngtcp2_ksl_it *it, 1961cb0ef41Sopenharmony_ci const ngtcp2_ksl_key *key); 1971cb0ef41Sopenharmony_ci 1981cb0ef41Sopenharmony_ci/* 1991cb0ef41Sopenharmony_ci * ngtcp2_ksl_remove_hint removes the |key| from |ksl|. |hint| must 2001cb0ef41Sopenharmony_ci * point to the same node denoted by |key|. |hint| is used to remove 2011cb0ef41Sopenharmony_ci * a node efficiently in some cases. Other than that, it behaves 2021cb0ef41Sopenharmony_ci * exactly like ngtcp2_ksl_remove. |it| and |hint| can point to the 2031cb0ef41Sopenharmony_ci * same object. 2041cb0ef41Sopenharmony_ci */ 2051cb0ef41Sopenharmony_ciint ngtcp2_ksl_remove_hint(ngtcp2_ksl *ksl, ngtcp2_ksl_it *it, 2061cb0ef41Sopenharmony_ci const ngtcp2_ksl_it *hint, 2071cb0ef41Sopenharmony_ci const ngtcp2_ksl_key *key); 2081cb0ef41Sopenharmony_ci 2091cb0ef41Sopenharmony_ci/* 2101cb0ef41Sopenharmony_ci * ngtcp2_ksl_lower_bound returns the iterator which points to the 2111cb0ef41Sopenharmony_ci * first node which has the key which is equal to |key| or the last 2121cb0ef41Sopenharmony_ci * node which satisfies !compar(&node->key, key). If there is no such 2131cb0ef41Sopenharmony_ci * node, it returns the iterator which satisfies ngtcp2_ksl_it_end(it) 2141cb0ef41Sopenharmony_ci * != 0. 2151cb0ef41Sopenharmony_ci */ 2161cb0ef41Sopenharmony_cingtcp2_ksl_it ngtcp2_ksl_lower_bound(ngtcp2_ksl *ksl, 2171cb0ef41Sopenharmony_ci const ngtcp2_ksl_key *key); 2181cb0ef41Sopenharmony_ci 2191cb0ef41Sopenharmony_ci/* 2201cb0ef41Sopenharmony_ci * ngtcp2_ksl_lower_bound_compar works like ngtcp2_ksl_lower_bound, 2211cb0ef41Sopenharmony_ci * but it takes custom function |compar| to do lower bound search. 2221cb0ef41Sopenharmony_ci */ 2231cb0ef41Sopenharmony_cingtcp2_ksl_it ngtcp2_ksl_lower_bound_compar(ngtcp2_ksl *ksl, 2241cb0ef41Sopenharmony_ci const ngtcp2_ksl_key *key, 2251cb0ef41Sopenharmony_ci ngtcp2_ksl_compar compar); 2261cb0ef41Sopenharmony_ci 2271cb0ef41Sopenharmony_ci/* 2281cb0ef41Sopenharmony_ci * ngtcp2_ksl_update_key replaces the key of nodes which has |old_key| 2291cb0ef41Sopenharmony_ci * with |new_key|. |new_key| must be strictly greater than the 2301cb0ef41Sopenharmony_ci * previous node and strictly smaller than the next node. 2311cb0ef41Sopenharmony_ci */ 2321cb0ef41Sopenharmony_civoid ngtcp2_ksl_update_key(ngtcp2_ksl *ksl, const ngtcp2_ksl_key *old_key, 2331cb0ef41Sopenharmony_ci const ngtcp2_ksl_key *new_key); 2341cb0ef41Sopenharmony_ci 2351cb0ef41Sopenharmony_ci/* 2361cb0ef41Sopenharmony_ci * ngtcp2_ksl_begin returns the iterator which points to the first 2371cb0ef41Sopenharmony_ci * node. If there is no node in |ksl|, it returns the iterator which 2381cb0ef41Sopenharmony_ci * satisfies ngtcp2_ksl_it_end(it) != 0. 2391cb0ef41Sopenharmony_ci */ 2401cb0ef41Sopenharmony_cingtcp2_ksl_it ngtcp2_ksl_begin(const ngtcp2_ksl *ksl); 2411cb0ef41Sopenharmony_ci 2421cb0ef41Sopenharmony_ci/* 2431cb0ef41Sopenharmony_ci * ngtcp2_ksl_end returns the iterator which points to the node 2441cb0ef41Sopenharmony_ci * following the last node. The returned object satisfies 2451cb0ef41Sopenharmony_ci * ngtcp2_ksl_it_end(). If there is no node in |ksl|, it returns the 2461cb0ef41Sopenharmony_ci * iterator which satisfies ngtcp2_ksl_it_begin(it) != 0. 2471cb0ef41Sopenharmony_ci */ 2481cb0ef41Sopenharmony_cingtcp2_ksl_it ngtcp2_ksl_end(const ngtcp2_ksl *ksl); 2491cb0ef41Sopenharmony_ci 2501cb0ef41Sopenharmony_ci/* 2511cb0ef41Sopenharmony_ci * ngtcp2_ksl_len returns the number of elements stored in |ksl|. 2521cb0ef41Sopenharmony_ci */ 2531cb0ef41Sopenharmony_cisize_t ngtcp2_ksl_len(ngtcp2_ksl *ksl); 2541cb0ef41Sopenharmony_ci 2551cb0ef41Sopenharmony_ci/* 2561cb0ef41Sopenharmony_ci * ngtcp2_ksl_clear removes all elements stored in |ksl|. 2571cb0ef41Sopenharmony_ci */ 2581cb0ef41Sopenharmony_civoid ngtcp2_ksl_clear(ngtcp2_ksl *ksl); 2591cb0ef41Sopenharmony_ci 2601cb0ef41Sopenharmony_ci/* 2611cb0ef41Sopenharmony_ci * ngtcp2_ksl_nth_node returns the |n|th node under |blk|. 2621cb0ef41Sopenharmony_ci */ 2631cb0ef41Sopenharmony_ci#define ngtcp2_ksl_nth_node(KSL, BLK, N) \ 2641cb0ef41Sopenharmony_ci ((ngtcp2_ksl_node *)(void *)((BLK)->nodes + (KSL)->nodelen * (N))) 2651cb0ef41Sopenharmony_ci 2661cb0ef41Sopenharmony_ci/* 2671cb0ef41Sopenharmony_ci * ngtcp2_ksl_print prints its internal state in stderr. It assumes 2681cb0ef41Sopenharmony_ci * that the key is of type int64_t. This function should be used for 2691cb0ef41Sopenharmony_ci * the debugging purpose only. 2701cb0ef41Sopenharmony_ci */ 2711cb0ef41Sopenharmony_civoid ngtcp2_ksl_print(ngtcp2_ksl *ksl); 2721cb0ef41Sopenharmony_ci 2731cb0ef41Sopenharmony_ci/* 2741cb0ef41Sopenharmony_ci * ngtcp2_ksl_it_init initializes |it|. 2751cb0ef41Sopenharmony_ci */ 2761cb0ef41Sopenharmony_civoid ngtcp2_ksl_it_init(ngtcp2_ksl_it *it, const ngtcp2_ksl *ksl, 2771cb0ef41Sopenharmony_ci ngtcp2_ksl_blk *blk, size_t i); 2781cb0ef41Sopenharmony_ci 2791cb0ef41Sopenharmony_ci/* 2801cb0ef41Sopenharmony_ci * ngtcp2_ksl_it_get returns the data associated to the node which 2811cb0ef41Sopenharmony_ci * |it| points to. It is undefined to call this function when 2821cb0ef41Sopenharmony_ci * ngtcp2_ksl_it_end(it) returns nonzero. 2831cb0ef41Sopenharmony_ci */ 2841cb0ef41Sopenharmony_ci#define ngtcp2_ksl_it_get(IT) \ 2851cb0ef41Sopenharmony_ci ngtcp2_ksl_nth_node((IT)->ksl, (IT)->blk, (IT)->i)->data 2861cb0ef41Sopenharmony_ci 2871cb0ef41Sopenharmony_ci/* 2881cb0ef41Sopenharmony_ci * ngtcp2_ksl_it_next advances the iterator by one. It is undefined 2891cb0ef41Sopenharmony_ci * if this function is called when ngtcp2_ksl_it_end(it) returns 2901cb0ef41Sopenharmony_ci * nonzero. 2911cb0ef41Sopenharmony_ci */ 2921cb0ef41Sopenharmony_ci#define ngtcp2_ksl_it_next(IT) \ 2931cb0ef41Sopenharmony_ci (++(IT)->i == (IT)->blk->n && (IT)->blk->next \ 2941cb0ef41Sopenharmony_ci ? ((IT)->blk = (IT)->blk->next, (IT)->i = 0) \ 2951cb0ef41Sopenharmony_ci : 0) 2961cb0ef41Sopenharmony_ci 2971cb0ef41Sopenharmony_ci/* 2981cb0ef41Sopenharmony_ci * ngtcp2_ksl_it_prev moves backward the iterator by one. It is 2991cb0ef41Sopenharmony_ci * undefined if this function is called when ngtcp2_ksl_it_begin(it) 3001cb0ef41Sopenharmony_ci * returns nonzero. 3011cb0ef41Sopenharmony_ci */ 3021cb0ef41Sopenharmony_civoid ngtcp2_ksl_it_prev(ngtcp2_ksl_it *it); 3031cb0ef41Sopenharmony_ci 3041cb0ef41Sopenharmony_ci/* 3051cb0ef41Sopenharmony_ci * ngtcp2_ksl_it_end returns nonzero if |it| points to the beyond the 3061cb0ef41Sopenharmony_ci * last node. 3071cb0ef41Sopenharmony_ci */ 3081cb0ef41Sopenharmony_ci#define ngtcp2_ksl_it_end(IT) \ 3091cb0ef41Sopenharmony_ci ((IT)->blk->n == (IT)->i && (IT)->blk->next == NULL) 3101cb0ef41Sopenharmony_ci 3111cb0ef41Sopenharmony_ci/* 3121cb0ef41Sopenharmony_ci * ngtcp2_ksl_it_begin returns nonzero if |it| points to the first 3131cb0ef41Sopenharmony_ci * node. |it| might satisfy both ngtcp2_ksl_it_begin(&it) and 3141cb0ef41Sopenharmony_ci * ngtcp2_ksl_it_end(&it) if the skip list has no node. 3151cb0ef41Sopenharmony_ci */ 3161cb0ef41Sopenharmony_ciint ngtcp2_ksl_it_begin(const ngtcp2_ksl_it *it); 3171cb0ef41Sopenharmony_ci 3181cb0ef41Sopenharmony_ci/* 3191cb0ef41Sopenharmony_ci * ngtcp2_ksl_key returns the key of the node which |it| points to. 3201cb0ef41Sopenharmony_ci * It is undefined to call this function when ngtcp2_ksl_it_end(it) 3211cb0ef41Sopenharmony_ci * returns nonzero. 3221cb0ef41Sopenharmony_ci */ 3231cb0ef41Sopenharmony_ci#define ngtcp2_ksl_it_key(IT) \ 3241cb0ef41Sopenharmony_ci ((ngtcp2_ksl_key *)ngtcp2_ksl_nth_node((IT)->ksl, (IT)->blk, (IT)->i)->key) 3251cb0ef41Sopenharmony_ci 3261cb0ef41Sopenharmony_ci/* 3271cb0ef41Sopenharmony_ci * ngtcp2_ksl_range_compar is an implementation of ngtcp2_ksl_compar. 3281cb0ef41Sopenharmony_ci * lhs->ptr and rhs->ptr must point to ngtcp2_range object and the 3291cb0ef41Sopenharmony_ci * function returns nonzero if (const ngtcp2_range *)(lhs->ptr)->begin 3301cb0ef41Sopenharmony_ci * < (const ngtcp2_range *)(rhs->ptr)->begin. 3311cb0ef41Sopenharmony_ci */ 3321cb0ef41Sopenharmony_ciint ngtcp2_ksl_range_compar(const ngtcp2_ksl_key *lhs, 3331cb0ef41Sopenharmony_ci const ngtcp2_ksl_key *rhs); 3341cb0ef41Sopenharmony_ci 3351cb0ef41Sopenharmony_ci/* 3361cb0ef41Sopenharmony_ci * ngtcp2_ksl_range_exclusive_compar is an implementation of 3371cb0ef41Sopenharmony_ci * ngtcp2_ksl_compar. lhs->ptr and rhs->ptr must point to 3381cb0ef41Sopenharmony_ci * ngtcp2_range object and the function returns nonzero if (const 3391cb0ef41Sopenharmony_ci * ngtcp2_range *)(lhs->ptr)->begin < (const ngtcp2_range 3401cb0ef41Sopenharmony_ci * *)(rhs->ptr)->begin and the 2 ranges do not intersect. 3411cb0ef41Sopenharmony_ci */ 3421cb0ef41Sopenharmony_ciint ngtcp2_ksl_range_exclusive_compar(const ngtcp2_ksl_key *lhs, 3431cb0ef41Sopenharmony_ci const ngtcp2_ksl_key *rhs); 3441cb0ef41Sopenharmony_ci 3451cb0ef41Sopenharmony_ci#endif /* NGTCP2_KSL_H */ 346