Skip to content

Commit

Permalink
Merge pull request #277 from ngtcp2/ksl-search
Browse files Browse the repository at this point in the history
Port ngtcp2_ksl changes that introduced ngtcp2_ksl_search
  • Loading branch information
tatsuhiro-t authored Nov 8, 2024
2 parents 26aa257 + 3408226 commit 8828bfd
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 44 deletions.
1 change: 1 addition & 0 deletions .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
- munit_void_test_decl
- nghttp3_ksl_search_def
- nghttp3_max_def
- nghttp3_min_def
- nghttp3_objalloc_decl
Expand Down
16 changes: 8 additions & 8 deletions lib/nghttp3_gaptr.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
#include <assert.h>

void nghttp3_gaptr_init(nghttp3_gaptr *gaptr, const nghttp3_mem *mem) {
nghttp3_ksl_init(&gaptr->gap, nghttp3_ksl_range_compar, sizeof(nghttp3_range),
mem);
nghttp3_ksl_init(&gaptr->gap, nghttp3_ksl_range_compar,
nghttp3_ksl_range_search, sizeof(nghttp3_range), mem);

gaptr->mem = mem;
}
Expand Down Expand Up @@ -62,8 +62,8 @@ int nghttp3_gaptr_push(nghttp3_gaptr *gaptr, uint64_t offset,
}
}

it = nghttp3_ksl_lower_bound_compar(&gaptr->gap, &q,
nghttp3_ksl_range_exclusive_compar);
it = nghttp3_ksl_lower_bound_search(&gaptr->gap, &q,
nghttp3_ksl_range_exclusive_search);

for (; !nghttp3_ksl_it_end(&it);) {
k = *(nghttp3_range *)nghttp3_ksl_it_key(&it);
Expand Down Expand Up @@ -120,8 +120,8 @@ nghttp3_range nghttp3_gaptr_get_first_gap_after(nghttp3_gaptr *gaptr,
return r;
}

it = nghttp3_ksl_lower_bound_compar(&gaptr->gap, &q,
nghttp3_ksl_range_exclusive_compar);
it = nghttp3_ksl_lower_bound_search(&gaptr->gap, &q,
nghttp3_ksl_range_exclusive_search);

assert(!nghttp3_ksl_it_end(&it));

Expand All @@ -138,8 +138,8 @@ int nghttp3_gaptr_is_pushed(nghttp3_gaptr *gaptr, uint64_t offset,
return 0;
}

it = nghttp3_ksl_lower_bound_compar(&gaptr->gap, &q,
nghttp3_ksl_range_exclusive_compar);
it = nghttp3_ksl_lower_bound_search(&gaptr->gap, &q,
nghttp3_ksl_range_exclusive_search);
m = nghttp3_range_intersect(&q, (nghttp3_range *)nghttp3_ksl_it_key(&it));

return nghttp3_range_len(&m) == 0;
Expand Down
73 changes: 51 additions & 22 deletions lib/nghttp3_ksl.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ static void ksl_node_set_key(nghttp3_ksl *ksl, nghttp3_ksl_node *node,
}

void nghttp3_ksl_init(nghttp3_ksl *ksl, nghttp3_ksl_compar compar,
size_t keylen, const nghttp3_mem *mem) {
nghttp3_ksl_search search, size_t keylen,
const nghttp3_mem *mem) {
size_t nodelen = ksl_nodelen(keylen);

nghttp3_objalloc_init(&ksl->blkalloc,
Expand All @@ -68,6 +69,7 @@ void nghttp3_ksl_init(nghttp3_ksl *ksl, nghttp3_ksl_compar compar,
ksl->head = NULL;
ksl->front = ksl->back = NULL;
ksl->compar = compar;
ksl->search = search;
ksl->n = 0;
ksl->keylen = keylen;
ksl->nodelen = nodelen;
Expand Down Expand Up @@ -274,20 +276,6 @@ static void ksl_insert_node(nghttp3_ksl *ksl, nghttp3_ksl_blk *blk, size_t i,
++blk->n;
}

static size_t ksl_search(const nghttp3_ksl *ksl, nghttp3_ksl_blk *blk,
const nghttp3_ksl_key *key,
nghttp3_ksl_compar compar) {
size_t i;
nghttp3_ksl_node *node;

for (i = 0, node = (nghttp3_ksl_node *)(void *)blk->nodes;
i < blk->n && compar((nghttp3_ksl_key *)node->key, key);
++i, node = (nghttp3_ksl_node *)(void *)((uint8_t *)node + ksl->nodelen))
;

return i;
}

int nghttp3_ksl_insert(nghttp3_ksl *ksl, nghttp3_ksl_it *it,
const nghttp3_ksl_key *key, void *data) {
nghttp3_ksl_blk *blk;
Expand All @@ -312,7 +300,7 @@ int nghttp3_ksl_insert(nghttp3_ksl *ksl, nghttp3_ksl_it *it,
blk = ksl->head;

for (;;) {
i = ksl_search(ksl, blk, key, ksl->compar);
i = ksl->search(ksl, blk, key);

if (blk->leaf) {
if (i < blk->n &&
Expand Down Expand Up @@ -571,7 +559,7 @@ int nghttp3_ksl_remove(nghttp3_ksl *ksl, nghttp3_ksl_it *it,
}

for (;;) {
i = ksl_search(ksl, blk, key, ksl->compar);
i = ksl->search(ksl, blk, key);

if (i == blk->n) {
if (it) {
Expand Down Expand Up @@ -642,12 +630,12 @@ int nghttp3_ksl_remove(nghttp3_ksl *ksl, nghttp3_ksl_it *it,

nghttp3_ksl_it nghttp3_ksl_lower_bound(const nghttp3_ksl *ksl,
const nghttp3_ksl_key *key) {
return nghttp3_ksl_lower_bound_compar(ksl, key, ksl->compar);
return nghttp3_ksl_lower_bound_search(ksl, key, ksl->search);
}

nghttp3_ksl_it nghttp3_ksl_lower_bound_compar(const nghttp3_ksl *ksl,
nghttp3_ksl_it nghttp3_ksl_lower_bound_search(const nghttp3_ksl *ksl,
const nghttp3_ksl_key *key,
nghttp3_ksl_compar compar) {
nghttp3_ksl_search search) {
nghttp3_ksl_blk *blk = ksl->head;
nghttp3_ksl_it it;
size_t i;
Expand All @@ -658,7 +646,7 @@ nghttp3_ksl_it nghttp3_ksl_lower_bound_compar(const nghttp3_ksl *ksl,
}

for (;;) {
i = ksl_search(ksl, blk, key, compar);
i = search(ksl, blk, key);

if (blk->leaf) {
if (i == blk->n && blk->next) {
Expand Down Expand Up @@ -702,7 +690,7 @@ void nghttp3_ksl_update_key(nghttp3_ksl *ksl, const nghttp3_ksl_key *old_key,
assert(ksl->head);

for (;;) {
i = ksl_search(ksl, blk, old_key, ksl->compar);
i = ksl->search(ksl, blk, old_key);

assert(i < blk->n);
node = nghttp3_ksl_nth_node(ksl, blk, i);
Expand Down Expand Up @@ -825,9 +813,50 @@ int nghttp3_ksl_range_compar(const nghttp3_ksl_key *lhs,
return a->begin < b->begin;
}

nghttp3_ksl_search_def(range, nghttp3_ksl_range_compar)

size_t nghttp3_ksl_range_search(const nghttp3_ksl *ksl, nghttp3_ksl_blk *blk,
const nghttp3_ksl_key *key) {
return ksl_range_search(ksl, blk, key);
}

int nghttp3_ksl_range_exclusive_compar(const nghttp3_ksl_key *lhs,
const nghttp3_ksl_key *rhs) {
const nghttp3_range *a = lhs, *b = rhs;
return a->begin < b->begin && !(nghttp3_max_uint64(a->begin, b->begin) <
nghttp3_min_uint64(a->end, b->end));
}

nghttp3_ksl_search_def(range_exclusive, nghttp3_ksl_range_exclusive_compar)

size_t nghttp3_ksl_range_exclusive_search(const nghttp3_ksl *ksl,
nghttp3_ksl_blk *blk,
const nghttp3_ksl_key *key) {
return ksl_range_exclusive_search(ksl, blk, key);
}

int nghttp3_ksl_uint64_less(const nghttp3_ksl_key *lhs,
const nghttp3_ksl_key *rhs) {
return *(uint64_t *)lhs < *(uint64_t *)rhs;
}

nghttp3_ksl_search_def(uint64_less, nghttp3_ksl_uint64_less)

size_t nghttp3_ksl_uint64_less_search(const nghttp3_ksl *ksl,
nghttp3_ksl_blk *blk,
const nghttp3_ksl_key *key) {
return ksl_uint64_less_search(ksl, blk, key);
}

int nghttp3_ksl_int64_greater(const nghttp3_ksl_key *lhs,
const nghttp3_ksl_key *rhs) {
return *(int64_t *)lhs > *(int64_t *)rhs;
}

nghttp3_ksl_search_def(int64_greater, nghttp3_ksl_int64_greater)

size_t nghttp3_ksl_int64_greater_search(const nghttp3_ksl *ksl,
nghttp3_ksl_blk *blk,
const nghttp3_ksl_key *key) {
return ksl_int64_greater_search(ksl, blk, key);
}
107 changes: 93 additions & 14 deletions lib/nghttp3_ksl.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,35 @@ typedef int (*nghttp3_ksl_compar)(const nghttp3_ksl_key *lhs,

typedef struct nghttp3_ksl nghttp3_ksl;

/*
* nghttp3_ksl_search is a function to search for the first element in
* |blk|->nodes which is not ordered before |key|. It returns the
* index of such element. It returns |blk|->n if there is no such
* element.
*/
typedef size_t (*nghttp3_ksl_search)(const nghttp3_ksl *ksl,
nghttp3_ksl_blk *blk,
const nghttp3_ksl_key *key);

/*
* nghttp3_ksl_search_def is a macro to implement nghttp3_ksl_search
* with COMPAR which is supposed to be nghttp3_ksl_compar.
*/
#define nghttp3_ksl_search_def(NAME, COMPAR) \
static size_t ksl_##NAME##_search(const nghttp3_ksl *ksl, \
nghttp3_ksl_blk *blk, \
const nghttp3_ksl_key *key) { \
size_t i; \
nghttp3_ksl_node *node; \
\
for (i = 0, node = (nghttp3_ksl_node *)(void *)blk->nodes; \
i < blk->n && COMPAR((nghttp3_ksl_key *)node->key, key); ++i, \
node = (nghttp3_ksl_node *)(void *)((uint8_t *)node + ksl->nodelen)) \
; \
\
return i; \
}

typedef struct nghttp3_ksl_it nghttp3_ksl_it;

/*
Expand All @@ -138,6 +167,7 @@ struct nghttp3_ksl {
/* back points to the last leaf block. */
nghttp3_ksl_blk *back;
nghttp3_ksl_compar compar;
nghttp3_ksl_search search;
/* n is the number of elements stored. */
size_t n;
/* keylen is the size of key */
Expand All @@ -149,11 +179,13 @@ struct nghttp3_ksl {

/*
* nghttp3_ksl_init initializes |ksl|. |compar| specifies compare
* function. |keylen| is the length of key and must be at least
* function. |search| is a search function which must use |compar|.
* |keylen| is the length of key and must be at least
* sizeof(uint64_t).
*/
void nghttp3_ksl_init(nghttp3_ksl *ksl, nghttp3_ksl_compar compar,
size_t keylen, const nghttp3_mem *mem);
nghttp3_ksl_search search, size_t keylen,
const nghttp3_mem *mem);

/*
* nghttp3_ksl_free frees resources allocated for |ksl|. If |ksl| is
Expand Down Expand Up @@ -218,12 +250,12 @@ nghttp3_ksl_it nghttp3_ksl_lower_bound(const nghttp3_ksl *ksl,
const nghttp3_ksl_key *key);

/*
* nghttp3_ksl_lower_bound_compar works like nghttp3_ksl_lower_bound,
* but it takes custom function |compar| to do lower bound search.
* nghttp3_ksl_lower_bound_search works like nghttp3_ksl_lower_bound,
* but it takes custom function |search| to do lower bound search.
*/
nghttp3_ksl_it nghttp3_ksl_lower_bound_compar(const nghttp3_ksl *ksl,
nghttp3_ksl_it nghttp3_ksl_lower_bound_search(const nghttp3_ksl *ksl,
const nghttp3_ksl_key *key,
nghttp3_ksl_compar compar);
nghttp3_ksl_search search);

/*
* nghttp3_ksl_update_key replaces the key of nodes which has
Expand Down Expand Up @@ -330,22 +362,69 @@ int nghttp3_ksl_it_begin(const nghttp3_ksl_it *it);

/*
* nghttp3_ksl_range_compar is an implementation of
* nghttp3_ksl_compar. lhs->ptr and rhs->ptr must point to
* nghttp3_range object and the function returns nonzero if (const
* nghttp3_range *)(lhs->ptr)->begin < (const nghttp3_range
* *)(rhs->ptr)->begin.
* nghttp3_ksl_compar. |lhs| and |rhs| must point to nghttp3_range
* object, and the function returns nonzero if ((const nghttp3_range
* *)lhs)->begin < ((const nghttp3_range *)rhs)->begin.
*/
int nghttp3_ksl_range_compar(const nghttp3_ksl_key *lhs,
const nghttp3_ksl_key *rhs);

/*
* nghttp3_ksl_range_search is an implementation of nghttp3_ksl_search
* that uses nghttp3_ksl_range_compar.
*/
size_t nghttp3_ksl_range_search(const nghttp3_ksl *ksl, nghttp3_ksl_blk *blk,
const nghttp3_ksl_key *key);

/*
* nghttp3_ksl_range_exclusive_compar is an implementation of
* nghttp3_ksl_compar. lhs->ptr and rhs->ptr must point to
* nghttp3_range object and the function returns nonzero if (const
* nghttp3_range *)(lhs->ptr)->begin < (const nghttp3_range
* *)(rhs->ptr)->begin and the 2 ranges do not intersect.
* nghttp3_ksl_compar. |lhs| and |rhs| must point to nghttp3_range
* object, and the function returns nonzero if ((const nghttp3_range
* *)lhs)->begin < ((const nghttp3_range *)rhs)->begin, and the 2
* ranges do not intersect.
*/
int nghttp3_ksl_range_exclusive_compar(const nghttp3_ksl_key *lhs,
const nghttp3_ksl_key *rhs);

/*
* nghttp3_ksl_range_exclusive_search is an implementation of
* nghttp3_ksl_search that uses nghttp3_ksl_range_exclusive_compar.
*/
size_t nghttp3_ksl_range_exclusive_search(const nghttp3_ksl *ksl,
nghttp3_ksl_blk *blk,
const nghttp3_ksl_key *key);

/*
* nghttp3_ksl_uint64_less is an implementation of nghttp3_ksl_compar.
* |lhs| and |rhs| must point to uint64_t objects, and the function
* returns nonzero if *(uint64_t *)|lhs| < *(uint64_t *)|rhs|.
*/
int nghttp3_ksl_uint64_less(const nghttp3_ksl_key *lhs,
const nghttp3_ksl_key *rhs);

/*
* nghttp3_ksl_uint64_less_search is an implementation of
* nghttp3_ksl_search that uses nghttp3_ksl_uint64_less.
*/
size_t nghttp3_ksl_uint64_less_search(const nghttp3_ksl *ksl,
nghttp3_ksl_blk *blk,
const nghttp3_ksl_key *key);

/*
* nghttp3_ksl_int64_greater is an implementation of
* nghttp3_ksl_compar. |lhs| and |rhs| must point to int64_t objects,
* and the function returns nonzero if *(int64_t *)|lhs| > *(int64_t
* *)|rhs|.
*/
int nghttp3_ksl_int64_greater(const nghttp3_ksl_key *lhs,
const nghttp3_ksl_key *rhs);

/*
* nghttp3_ksl_int64_greater_search is an implementation of
* nghttp3_ksl_search that uses nghttp3_ksl_int64_greater.
*/
size_t nghttp3_ksl_int64_greater_search(const nghttp3_ksl *ksl,
nghttp3_ksl_blk *blk,
const nghttp3_ksl_key *key);

#endif /* !defined(NGHTTP3_KSL_H) */
3 changes: 3 additions & 0 deletions lib/nghttp3_qpack.c
Original file line number Diff line number Diff line change
Expand Up @@ -898,6 +898,8 @@ static int max_cnt_greater(const nghttp3_ksl_key *lhs,
return a->max_cnt > b->max_cnt || (a->max_cnt == b->max_cnt && a->id < b->id);
}

nghttp3_ksl_search_def(max_cnt_greater, max_cnt_greater)

int nghttp3_qpack_encoder_init(nghttp3_qpack_encoder *encoder,
size_t hard_max_dtable_capacity,
const nghttp3_mem *mem) {
Expand All @@ -911,6 +913,7 @@ int nghttp3_qpack_encoder_init(nghttp3_qpack_encoder *encoder,
nghttp3_map_init(&encoder->streams, mem);

nghttp3_ksl_init(&encoder->blocked_streams, max_cnt_greater,
ksl_max_cnt_greater_search,
sizeof(nghttp3_blocked_streams_key), mem);

qpack_map_init(&encoder->dtable_map);
Expand Down

0 comments on commit 8828bfd

Please sign in to comment.