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