Commit ebad3d47 authored by Tatsuhiro Tsujikawa's avatar Tatsuhiro Tsujikawa

Port new ngtcp2 map implementation

parent d4fd0681
......@@ -50,8 +50,7 @@ OBJECTS = nghttp2_pq.c nghttp2_map.c nghttp2_queue.c \
nghttp2_mem.c \
nghttp2_http.c \
nghttp2_rcbuf.c \
nghttp2_debug.c \
nghttp2_ksl.c
nghttp2_debug.c
HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \
nghttp2_frame.h \
......@@ -67,8 +66,7 @@ HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \
nghttp2_mem.h \
nghttp2_http.h \
nghttp2_rcbuf.h \
nghttp2_debug.h \
nghttp2_ksl.h
nghttp2_debug.h
libnghttp2_la_SOURCES = $(HFILES) $(OBJECTS)
libnghttp2_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined \
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -33,30 +33,23 @@
#include <nghttp2/nghttp2.h>
#include "nghttp2_mem.h"
#include "nghttp2_ksl.h"
/* Implementation of unordered map */
typedef int32_t key_type;
typedef struct nghttp2_map_entry {
union {
key_type key;
/* we requires 8 bytes aligment */
int64_t pad;
};
} nghttp2_map_entry;
typedef int32_t nghttp2_map_key_type;
typedef struct nghttp2_map_bucket {
nghttp2_map_entry *ptr;
nghttp2_ksl *ksl;
uint32_t hash;
nghttp2_map_key_type key;
void *data;
} nghttp2_map_bucket;
typedef struct {
typedef struct nghttp2_map {
nghttp2_map_bucket *table;
nghttp2_mem *mem;
size_t size;
uint32_t tablelen;
uint32_t tablelenbits;
} nghttp2_map;
/*
......@@ -80,21 +73,14 @@ void nghttp2_map_free(nghttp2_map *map);
/*
* Deallocates each entries using |func| function and any resources
* allocated for |map|. The |func| function is responsible for freeing
* given the |entry| object. The |ptr| will be passed to the |func| as
* given the |data| object. The |ptr| will be passed to the |func| as
* send argument. The return value of the |func| will be ignored.
*/
void nghttp2_map_each_free(nghttp2_map *map,
int (*func)(nghttp2_map_entry *entry, void *ptr),
void nghttp2_map_each_free(nghttp2_map *map, int (*func)(void *data, void *ptr),
void *ptr);
/*
* Initializes the |entry| with the |key|. All entries to be inserted
* to the map must be initialized with this function.
*/
void nghttp2_map_entry_init(nghttp2_map_entry *entry, key_type key);
/*
* Inserts the new |entry| with the key |entry->key| to the map |map|.
* Inserts the new |data| with the |key| to the map |map|.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
......@@ -104,25 +90,25 @@ void nghttp2_map_entry_init(nghttp2_map_entry *entry, key_type key);
* NGHTTP2_ERR_NOMEM
* Out of memory
*/
int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_entry *entry);
int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_key_type key, void *data);
/*
* Returns the entry associated by the key |key|. If there is no such
* entry, this function returns NULL.
* Returns the data associated by the key |key|. If there is no such
* data, this function returns NULL.
*/
nghttp2_map_entry *nghttp2_map_find(nghttp2_map *map, key_type key);
void *nghttp2_map_find(nghttp2_map *map, nghttp2_map_key_type key);
/*
* Removes the entry associated by the key |key| from the |map|. The
* removed entry is not freed by this function.
* Removes the data associated by the key |key| from the |map|. The
* removed data is not freed by this function.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* NGHTTP2_ERR_INVALID_ARGUMENT
* The entry associated by |key| does not exist.
* The data associated by |key| does not exist.
*/
int nghttp2_map_remove(nghttp2_map *map, key_type key);
int nghttp2_map_remove(nghttp2_map *map, nghttp2_map_key_type key);
/*
* Removes all entries from |map|.
......@@ -135,21 +121,22 @@ void nghttp2_map_clear(nghttp2_map *map);
size_t nghttp2_map_size(nghttp2_map *map);
/*
* Applies the function |func| to each entry in the |map| with the
* Applies the function |func| to each data in the |map| with the
* optional user supplied pointer |ptr|.
*
* If the |func| returns 0, this function calls the |func| with the
* next entry. If the |func| returns nonzero, it will not call the
* next data. If the |func| returns nonzero, it will not call the
* |func| for further entries and return the return value of the
* |func| immediately. Thus, this function returns 0 if all the
* invocations of the |func| return 0, or nonzero value which the last
* invocation of |func| returns.
*
* Don't use this function to free each entry. Use
* Don't use this function to free each data. Use
* nghttp2_map_each_free() instead.
*/
int nghttp2_map_each(nghttp2_map *map,
int (*func)(nghttp2_map_entry *entry, void *ptr),
int nghttp2_map_each(nghttp2_map *map, int (*func)(void *data, void *ptr),
void *ptr);
void nghttp2_map_print_distance(nghttp2_map *map);
#endif /* NGHTTP2_MAP_H */
......@@ -666,7 +666,7 @@ int nghttp2_session_server_new3(nghttp2_session **session_ptr,
return 0;
}
static int free_streams(nghttp2_map_entry *entry, void *ptr) {
static int free_streams(void *entry, void *ptr) {
nghttp2_session *session;
nghttp2_stream *stream;
nghttp2_outbound_item *item;
......@@ -1102,7 +1102,7 @@ nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session,
(int32_t)session->local_settings.initial_window_size,
stream_user_data, mem);
rv = nghttp2_map_insert(&session->streams, &stream->map_entry);
rv = nghttp2_map_insert(&session->streams, stream_id, stream);
if (rv != 0) {
nghttp2_stream_free(stream);
nghttp2_mem_free(mem, stream);
......@@ -2424,7 +2424,7 @@ static int session_call_on_frame_send(nghttp2_session *session,
return 0;
}
static int find_stream_on_goaway_func(nghttp2_map_entry *entry, void *ptr) {
static int find_stream_on_goaway_func(void *entry, void *ptr) {
nghttp2_close_stream_on_goaway_arg *arg;
nghttp2_stream *stream;
......@@ -4194,8 +4194,7 @@ static int session_process_rst_stream_frame(nghttp2_session *session) {
return nghttp2_session_on_rst_stream_received(session, frame);
}
static int update_remote_initial_window_size_func(nghttp2_map_entry *entry,
void *ptr) {
static int update_remote_initial_window_size_func(void *entry, void *ptr) {
int rv;
nghttp2_update_window_size_arg *arg;
nghttp2_stream *stream;
......@@ -4248,8 +4247,7 @@ session_update_remote_initial_window_size(nghttp2_session *session,
update_remote_initial_window_size_func, &arg);
}
static int update_local_initial_window_size_func(nghttp2_map_entry *entry,
void *ptr) {
static int update_local_initial_window_size_func(void *entry, void *ptr) {
int rv;
nghttp2_update_window_size_arg *arg;
nghttp2_stream *stream;
......
......@@ -62,7 +62,6 @@ void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id,
int32_t weight, int32_t remote_initial_window_size,
int32_t local_initial_window_size,
void *stream_user_data, nghttp2_mem *mem) {
nghttp2_map_entry_init(&stream->map_entry, (key_type)stream_id);
nghttp2_pq_init(&stream->obq, stream_less, mem);
stream->stream_id = stream_id;
......
......@@ -135,8 +135,6 @@ typedef enum {
} nghttp2_http_flag;
struct nghttp2_stream {
/* Intrusive Map */
nghttp2_map_entry map_entry;
/* Entry for dep_prev->obq */
nghttp2_pq_entry pq_entry;
/* Priority Queue storing direct descendant (nghttp2_stream). Only
......
/*
* nghttp2 - HTTP/2 C Library
*
* Copyright (c) 2012 Tatsuhiro Tsujikawa
* Copyright (c) 2017 ngtcp2 contributors
* Copyright (c) 2012 nghttp2 contributors
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
......@@ -29,12 +30,13 @@
#include "nghttp2_map.h"
typedef struct strentry {
nghttp2_map_entry map_entry;
nghttp2_map_key_type key;
const char *str;
} strentry;
static void strentry_init(strentry *entry, key_type key, const char *str) {
nghttp2_map_entry_init(&entry->map_entry, key);
static void strentry_init(strentry *entry, nghttp2_map_key_type key,
const char *str) {
entry->key = key;
entry->str = str;
}
......@@ -49,23 +51,23 @@ void test_nghttp2_map(void) {
strentry_init(&baz, 3, "baz");
strentry_init(&shrubbery, 4, "shrubbery");
CU_ASSERT(0 == nghttp2_map_insert(&map, &foo.map_entry));
CU_ASSERT(0 == nghttp2_map_insert(&map, foo.key, &foo));
CU_ASSERT(strcmp("foo", ((strentry *)nghttp2_map_find(&map, 1))->str) == 0);
CU_ASSERT(1 == nghttp2_map_size(&map));
CU_ASSERT(NGHTTP2_ERR_INVALID_ARGUMENT ==
nghttp2_map_insert(&map, &FOO.map_entry));
nghttp2_map_insert(&map, FOO.key, &FOO));
CU_ASSERT(1 == nghttp2_map_size(&map));
CU_ASSERT(strcmp("foo", ((strentry *)nghttp2_map_find(&map, 1))->str) == 0);
CU_ASSERT(0 == nghttp2_map_insert(&map, &bar.map_entry));
CU_ASSERT(0 == nghttp2_map_insert(&map, bar.key, &bar));
CU_ASSERT(2 == nghttp2_map_size(&map));
CU_ASSERT(0 == nghttp2_map_insert(&map, &baz.map_entry));
CU_ASSERT(0 == nghttp2_map_insert(&map, baz.key, &baz));
CU_ASSERT(3 == nghttp2_map_size(&map));
CU_ASSERT(0 == nghttp2_map_insert(&map, &shrubbery.map_entry));
CU_ASSERT(0 == nghttp2_map_insert(&map, shrubbery.key, &shrubbery));
CU_ASSERT(4 == nghttp2_map_size(&map));
CU_ASSERT(strcmp("baz", ((strentry *)nghttp2_map_find(&map, 3))->str) == 0);
......@@ -100,8 +102,8 @@ static void shuffle(int *a, int n) {
}
}
static int eachfun(nghttp2_map_entry *entry, void *ptr) {
(void)entry;
static int eachfun(void *data, void *ptr) {
(void)data;
(void)ptr;
return 0;
......@@ -114,51 +116,56 @@ static int order[NUM_ENT];
void test_nghttp2_map_functional(void) {
nghttp2_map map;
int i;
strentry *ent;
nghttp2_map_init(&map, nghttp2_mem_default());
for (i = 0; i < NUM_ENT; ++i) {
strentry_init(&arr[i], i + 1, "foo");
strentry_init(&arr[i], (nghttp2_map_key_type)(i + 1), "foo");
order[i] = i + 1;
}
/* insertion */
shuffle(order, NUM_ENT);
for (i = 0; i < NUM_ENT; ++i) {
CU_ASSERT(0 == nghttp2_map_insert(&map, &arr[order[i] - 1].map_entry));
ent = &arr[order[i] - 1];
CU_ASSERT(0 == nghttp2_map_insert(&map, ent->key, ent));
}
CU_ASSERT(NUM_ENT == nghttp2_map_size(&map));
/* traverse */
nghttp2_map_each(&map, eachfun, NULL);
/* find */
shuffle(order, NUM_ENT);
for (i = 0; i < NUM_ENT; ++i) {
nghttp2_map_find(&map, order[i]);
CU_ASSERT(NULL != nghttp2_map_find(&map, (nghttp2_map_key_type)order[i]));
}
/* remove */
shuffle(order, NUM_ENT);
for (i = 0; i < NUM_ENT; ++i) {
CU_ASSERT(0 == nghttp2_map_remove(&map, order[i]));
CU_ASSERT(0 == nghttp2_map_remove(&map, (nghttp2_map_key_type)order[i]));
}
/* each_free (but no op function for testing purpose) */
for (i = 0; i < NUM_ENT; ++i) {
strentry_init(&arr[i], i + 1, "foo");
strentry_init(&arr[i], (nghttp2_map_key_type)(i + 1), "foo");
}
/* insert once again */
for (i = 0; i < NUM_ENT; ++i) {
CU_ASSERT(0 == nghttp2_map_insert(&map, &arr[i].map_entry));
ent = &arr[i];
CU_ASSERT(0 == nghttp2_map_insert(&map, ent->key, ent));
}
nghttp2_map_each_free(&map, eachfun, NULL);
nghttp2_map_free(&map);
}
static int entry_free(nghttp2_map_entry *entry, void *ptr) {
nghttp2_mem *mem = ptr;
static int entry_free(void *data, void *ptr) {
const nghttp2_mem *mem = ptr;
mem->free(entry, NULL);
mem->free(data, NULL);
return 0;
}
void test_nghttp2_map_each_free(void) {
nghttp2_mem *mem = nghttp2_mem_default();
const nghttp2_mem *mem = nghttp2_mem_default();
strentry *foo = mem->malloc(sizeof(strentry), NULL),
*bar = mem->malloc(sizeof(strentry), NULL),
*baz = mem->malloc(sizeof(strentry), NULL),
......@@ -171,11 +178,29 @@ void test_nghttp2_map_each_free(void) {
strentry_init(baz, 3, "baz");
strentry_init(shrubbery, 4, "shrubbery");
nghttp2_map_insert(&map, &foo->map_entry);
nghttp2_map_insert(&map, &bar->map_entry);
nghttp2_map_insert(&map, &baz->map_entry);
nghttp2_map_insert(&map, &shrubbery->map_entry);
nghttp2_map_insert(&map, foo->key, foo);
nghttp2_map_insert(&map, bar->key, bar);
nghttp2_map_insert(&map, baz->key, baz);
nghttp2_map_insert(&map, shrubbery->key, shrubbery);
nghttp2_map_each_free(&map, entry_free, (void *)mem);
nghttp2_map_free(&map);
}
void test_nghttp2_map_clear(void) {
nghttp2_mem *mem = nghttp2_mem_default();
nghttp2_map map;
strentry foo;
strentry_init(&foo, 1, "foo");
nghttp2_map_init(&map, mem);
CU_ASSERT(0 == nghttp2_map_insert(&map, foo.key, &foo));
nghttp2_map_clear(&map);
CU_ASSERT(0 == nghttp2_map_size(&map));
nghttp2_map_each_free(&map, entry_free, mem);
nghttp2_map_free(&map);
}
/*
* nghttp2 - HTTP/2 C Library
*
* Copyright (c) 2012 Tatsuhiro Tsujikawa
* Copyright (c) 2017 ngtcp2 contributors
* Copyright (c) 2012 nghttp2 contributors
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
......@@ -32,5 +33,6 @@
void test_nghttp2_map(void);
void test_nghttp2_map_functional(void);
void test_nghttp2_map_each_free(void);
void test_nghttp2_map_clear(void);
#endif /* NGHTTP2_MAP_TEST_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment