Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
N
nghttp2
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
nghttp2
Commits
1ce62852
Commit
1ce62852
authored
Jul 26, 2020
by
Tatsuhiro Tsujikawa
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
nghttp2_map backed by nghttp2_ksl
parent
6089353d
Changes
5
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
1244 additions
and
62 deletions
+1244
-62
lib/Makefile.am
lib/Makefile.am
+4
-2
lib/nghttp2_ksl.c
lib/nghttp2_ksl.c
+707
-0
lib/nghttp2_ksl.h
lib/nghttp2_ksl.h
+315
-0
lib/nghttp2_map.c
lib/nghttp2_map.c
+203
-57
lib/nghttp2_map.h
lib/nghttp2_map.h
+15
-3
No files found.
lib/Makefile.am
View file @
1ce62852
...
...
@@ -49,7 +49,8 @@ OBJECTS = nghttp2_pq.c nghttp2_map.c nghttp2_queue.c \
nghttp2_mem.c
\
nghttp2_http.c
\
nghttp2_rcbuf.c
\
nghttp2_debug.c
nghttp2_debug.c
\
nghttp2_ksl.c
HFILES
=
nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h
\
nghttp2_frame.h
\
...
...
@@ -65,7 +66,8 @@ 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_debug.h
\
nghttp2_ksl.h
libnghttp2_la_SOURCES
=
$(HFILES)
$(OBJECTS)
libnghttp2_la_LDFLAGS
=
-no-undefined
\
...
...
lib/nghttp2_ksl.c
0 → 100644
View file @
1ce62852
This diff is collapsed.
Click to expand it.
lib/nghttp2_ksl.h
0 → 100644
View file @
1ce62852
This diff is collapsed.
Click to expand it.
lib/nghttp2_map.c
View file @
1ce62852
/*
* 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
...
...
@@ -25,6 +26,9 @@
#include "nghttp2_map.h"
#include <string.h>
#include <assert.h>
#include "nghttp2_helper.h"
#define INITIAL_TABLE_LENGTH 256
...
...
@@ -32,7 +36,7 @@ int nghttp2_map_init(nghttp2_map *map, nghttp2_mem *mem) {
map
->
mem
=
mem
;
map
->
tablelen
=
INITIAL_TABLE_LENGTH
;
map
->
table
=
nghttp2_mem_calloc
(
mem
,
map
->
tablelen
,
sizeof
(
nghttp2_map_
entry
*
));
nghttp2_mem_calloc
(
mem
,
map
->
tablelen
,
sizeof
(
nghttp2_map_
bucket
));
if
(
map
->
table
==
NULL
)
{
return
NGHTTP2_ERR_NOMEM
;
}
...
...
@@ -43,6 +47,21 @@ int nghttp2_map_init(nghttp2_map *map, nghttp2_mem *mem) {
}
void
nghttp2_map_free
(
nghttp2_map
*
map
)
{
size_t
i
;
nghttp2_map_bucket
*
bkt
;
if
(
!
map
)
{
return
;
}
for
(
i
=
0
;
i
<
map
->
tablelen
;
++
i
)
{
bkt
=
&
map
->
table
[
i
];
if
(
bkt
->
ksl
)
{
nghttp2_ksl_free
(
bkt
->
ksl
);
nghttp2_mem_free
(
map
->
mem
,
bkt
->
ksl
);
}
}
nghttp2_mem_free
(
map
->
mem
,
map
->
table
);
}
...
...
@@ -50,14 +69,29 @@ void nghttp2_map_each_free(nghttp2_map *map,
int
(
*
func
)(
nghttp2_map_entry
*
entry
,
void
*
ptr
),
void
*
ptr
)
{
uint32_t
i
;
nghttp2_map_bucket
*
bkt
;
nghttp2_ksl_it
it
;
for
(
i
=
0
;
i
<
map
->
tablelen
;
++
i
)
{
nghttp2_map_entry
*
entry
;
for
(
entry
=
map
->
table
[
i
];
entry
;)
{
nghttp2_map_entry
*
next
=
entry
->
next
;
func
(
entry
,
ptr
);
entry
=
next
;
bkt
=
&
map
->
table
[
i
];
if
(
bkt
->
ptr
)
{
func
(
bkt
->
ptr
,
ptr
);
bkt
->
ptr
=
NULL
;
assert
(
bkt
->
ksl
==
NULL
||
nghttp2_ksl_len
(
bkt
->
ksl
)
==
0
);
continue
;
}
if
(
bkt
->
ksl
)
{
for
(
it
=
nghttp2_ksl_begin
(
bkt
->
ksl
);
!
nghttp2_ksl_it_end
(
&
it
);
nghttp2_ksl_it_next
(
&
it
))
{
func
(
nghttp2_ksl_it_get
(
&
it
),
ptr
);
}
nghttp2_ksl_free
(
bkt
->
ksl
);
nghttp2_mem_free
(
map
->
mem
,
bkt
->
ksl
);
bkt
->
ksl
=
NULL
;
}
map
->
table
[
i
]
=
NULL
;
}
}
...
...
@@ -66,13 +100,29 @@ int nghttp2_map_each(nghttp2_map *map,
void
*
ptr
)
{
int
rv
;
uint32_t
i
;
nghttp2_map_bucket
*
bkt
;
nghttp2_ksl_it
it
;
for
(
i
=
0
;
i
<
map
->
tablelen
;
++
i
)
{
nghttp2_map_entry
*
entry
;
for
(
entry
=
map
->
table
[
i
];
entry
;
entry
=
entry
->
next
)
{
rv
=
func
(
entry
,
ptr
);
bkt
=
&
map
->
table
[
i
];
if
(
bkt
->
ptr
)
{
rv
=
func
(
bkt
->
ptr
,
ptr
);
if
(
rv
!=
0
)
{
return
rv
;
}
assert
(
bkt
->
ksl
==
NULL
||
nghttp2_ksl_len
(
bkt
->
ksl
)
==
0
);
continue
;
}
if
(
bkt
->
ksl
)
{
for
(
it
=
nghttp2_ksl_begin
(
bkt
->
ksl
);
!
nghttp2_ksl_it_end
(
&
it
);
nghttp2_ksl_it_next
(
&
it
))
{
rv
=
func
(
nghttp2_ksl_it_get
(
&
it
),
ptr
);
if
(
rv
!=
0
)
{
return
rv
;
}
}
}
}
return
0
;
...
...
@@ -83,72 +133,133 @@ void nghttp2_map_entry_init(nghttp2_map_entry *entry, key_type key) {
entry
->
next
=
NULL
;
}
/* Same hash function in android HashMap source code. */
/* The |mod| must be power of 2 */
static
uint32_t
hash
(
int32_t
key
,
uint32_t
mod
)
{
uint32_t
h
=
(
uint32_t
)
key
;
h
^=
(
h
>>
20
)
^
(
h
>>
12
);
h
^=
(
h
>>
7
)
^
(
h
>>
4
);
/* FNV1a hash */
static
uint32_t
hash
(
key_type
key
,
uint32_t
mod
)
{
uint8_t
*
p
,
*
end
;
uint32_t
h
=
0x811C9DC5u
;
p
=
(
uint8_t
*
)
&
key
;
end
=
p
+
sizeof
(
key_type
);
for
(;
p
!=
end
;)
{
h
^=
*
p
++
;
h
+=
(
h
<<
1
)
+
(
h
<<
4
)
+
(
h
<<
7
)
+
(
h
<<
8
)
+
(
h
<<
24
);
}
return
h
&
(
mod
-
1
);
}
static
int
insert
(
nghttp2_map_entry
**
table
,
uint32_t
tablelen
,
nghttp2_map_entry
*
entry
)
{
static
int
less
(
const
nghttp2_ksl_key
*
lhs
,
const
nghttp2_ksl_key
*
rhs
)
{
return
*
(
key_type
*
)
lhs
<
*
(
key_type
*
)
rhs
;
}
static
int
map_insert
(
nghttp2_map
*
map
,
nghttp2_map_bucket
*
table
,
uint32_t
tablelen
,
nghttp2_map_entry
*
entry
)
{
uint32_t
h
=
hash
(
entry
->
key
,
tablelen
);
if
(
table
[
h
]
==
NULL
)
{
table
[
h
]
=
entry
;
}
else
{
nghttp2_map_entry
*
p
;
/* We won't allow duplicated key, so check it out. */
for
(
p
=
table
[
h
];
p
;
p
=
p
->
next
)
{
if
(
p
->
key
==
entry
->
key
)
{
return
NGHTTP2_ERR_INVALID_ARGUMENT
;
}
nghttp2_map_bucket
*
bkt
=
&
table
[
h
];
nghttp2_mem
*
mem
=
map
->
mem
;
int
rv
;
if
(
bkt
->
ptr
==
NULL
&&
(
bkt
->
ksl
==
NULL
||
nghttp2_ksl_len
(
bkt
->
ksl
)
==
0
))
{
bkt
->
ptr
=
entry
;
return
0
;
}
if
(
!
bkt
->
ksl
)
{
bkt
->
ksl
=
nghttp2_mem_malloc
(
mem
,
sizeof
(
*
bkt
->
ksl
));
if
(
bkt
->
ksl
==
NULL
)
{
return
NGHTTP2_ERR_NOMEM
;
}
entry
->
next
=
table
[
h
];
table
[
h
]
=
entry
;
nghttp2_ksl_init
(
bkt
->
ksl
,
less
,
sizeof
(
key_type
),
mem
);
}
return
0
;
if
(
bkt
->
ptr
)
{
rv
=
nghttp2_ksl_insert
(
bkt
->
ksl
,
NULL
,
&
bkt
->
ptr
->
key
,
bkt
->
ptr
);
if
(
rv
!=
0
)
{
return
rv
;
}
bkt
->
ptr
=
NULL
;
}
return
nghttp2_ksl_insert
(
bkt
->
ksl
,
NULL
,
&
entry
->
key
,
entry
);
}
/* new_tablelen must be power of 2 */
static
int
resize
(
nghttp2_map
*
map
,
uint32_t
new_tablelen
)
{
static
int
map_
resize
(
nghttp2_map
*
map
,
uint32_t
new_tablelen
)
{
uint32_t
i
;
nghttp2_map_entry
**
new_table
;
nghttp2_map_bucket
*
new_table
;
nghttp2_map_bucket
*
bkt
;
nghttp2_ksl_it
it
;
int
rv
;
new_table
=
nghttp2_mem_calloc
(
map
->
mem
,
new_tablelen
,
sizeof
(
nghttp2_map_
entry
*
));
nghttp2_mem_calloc
(
map
->
mem
,
new_tablelen
,
sizeof
(
nghttp2_map_
bucket
));
if
(
new_table
==
NULL
)
{
return
NGHTTP2_ERR_NOMEM
;
}
for
(
i
=
0
;
i
<
map
->
tablelen
;
++
i
)
{
nghttp2_map_entry
*
entry
;
for
(
entry
=
map
->
table
[
i
];
entry
;)
{
nghttp2_map_entry
*
next
=
entry
->
next
;
entry
->
next
=
NULL
;
/* This function must succeed */
insert
(
new_table
,
new_tablelen
,
entry
);
entry
=
next
;
bkt
=
&
map
->
table
[
i
];
if
(
bkt
->
ptr
)
{
rv
=
map_insert
(
map
,
new_table
,
new_tablelen
,
bkt
->
ptr
);
if
(
rv
!=
0
)
{
goto
fail
;
}
assert
(
bkt
->
ksl
==
NULL
||
nghttp2_ksl_len
(
bkt
->
ksl
)
==
0
);
continue
;
}
if
(
bkt
->
ksl
)
{
for
(
it
=
nghttp2_ksl_begin
(
bkt
->
ksl
);
!
nghttp2_ksl_it_end
(
&
it
);
nghttp2_ksl_it_next
(
&
it
))
{
rv
=
map_insert
(
map
,
new_table
,
new_tablelen
,
nghttp2_ksl_it_get
(
&
it
));
if
(
rv
!=
0
)
{
goto
fail
;
}
}
}
}
for
(
i
=
0
;
i
<
map
->
tablelen
;
++
i
)
{
bkt
=
&
map
->
table
[
i
];
if
(
bkt
->
ksl
)
{
nghttp2_ksl_free
(
bkt
->
ksl
);
nghttp2_mem_free
(
map
->
mem
,
bkt
->
ksl
);
}
}
nghttp2_mem_free
(
map
->
mem
,
map
->
table
);
map
->
tablelen
=
new_tablelen
;
map
->
table
=
new_table
;
return
0
;
fail:
for
(
i
=
0
;
i
<
new_tablelen
;
++
i
)
{
bkt
=
&
new_table
[
i
];
if
(
bkt
->
ksl
)
{
nghttp2_ksl_free
(
bkt
->
ksl
);
nghttp2_mem_free
(
map
->
mem
,
bkt
->
ksl
);
}
}
return
rv
;
}
int
nghttp2_map_insert
(
nghttp2_map
*
map
,
nghttp2_map_entry
*
new_entry
)
{
int
rv
;
/* Load factor is 0.75 */
if
((
map
->
size
+
1
)
*
4
>
map
->
tablelen
*
3
)
{
rv
=
resize
(
map
,
map
->
tablelen
*
2
);
rv
=
map_
resize
(
map
,
map
->
tablelen
*
2
);
if
(
rv
!=
0
)
{
return
rv
;
}
}
rv
=
insert
(
map
->
table
,
map
->
tablelen
,
new_entry
);
rv
=
map_insert
(
map
,
map
->
table
,
map
->
tablelen
,
new_entry
);
if
(
rv
!=
0
)
{
return
rv
;
}
...
...
@@ -157,33 +268,68 @@ int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_entry *new_entry) {
}
nghttp2_map_entry
*
nghttp2_map_find
(
nghttp2_map
*
map
,
key_type
key
)
{
uint32_t
h
;
nghttp2_map_entry
*
entry
;
h
=
hash
(
key
,
map
->
tablelen
);
for
(
entry
=
map
->
table
[
h
];
entry
;
entry
=
entry
->
next
)
{
if
(
entry
->
key
==
key
)
{
return
entry
;
nghttp2_map_bucket
*
bkt
=
&
map
->
table
[
hash
(
key
,
map
->
tablelen
)];
nghttp2_ksl_it
it
;
if
(
bkt
->
ptr
)
{
if
(
bkt
->
ptr
->
key
==
key
)
{
return
bkt
->
ptr
;
}
return
NULL
;
}
if
(
bkt
->
ksl
)
{
it
=
nghttp2_ksl_lower_bound
(
bkt
->
ksl
,
&
key
);
if
(
nghttp2_ksl_it_end
(
&
it
)
||
*
(
key_type
*
)
nghttp2_ksl_it_key
(
&
it
)
!=
key
)
{
return
NULL
;
}
return
nghttp2_ksl_it_get
(
&
it
);
}
return
NULL
;
}
int
nghttp2_map_remove
(
nghttp2_map
*
map
,
key_type
key
)
{
uint32_t
h
;
nghttp2_map_entry
**
dst
;
h
=
hash
(
key
,
map
->
tablelen
);
nghttp2_map_bucket
*
bkt
=
&
map
->
table
[
hash
(
key
,
map
->
tablelen
)];
int
rv
;
for
(
dst
=
&
map
->
table
[
h
];
*
dst
;
dst
=
&
(
*
dst
)
->
next
)
{
if
((
*
dst
)
->
key
!=
key
)
{
continue
;
if
(
bkt
->
ptr
)
{
if
(
bkt
->
ptr
->
key
==
key
)
{
bkt
->
ptr
=
NULL
;
--
map
->
size
;
return
0
;
}
return
NGHTTP2_ERR_INVALID_ARGUMENT
;
}
*
dst
=
(
*
dst
)
->
next
;
if
(
bkt
->
ksl
)
{
rv
=
nghttp2_ksl_remove
(
bkt
->
ksl
,
NULL
,
&
key
);
if
(
rv
!=
0
)
{
return
rv
;
}
--
map
->
size
;
return
0
;
}
return
NGHTTP2_ERR_INVALID_ARGUMENT
;
}
void
nghttp2_map_clear
(
nghttp2_map
*
map
)
{
uint32_t
i
;
nghttp2_map_bucket
*
bkt
;
for
(
i
=
0
;
i
<
map
->
tablelen
;
++
i
)
{
bkt
=
&
map
->
table
[
i
];
bkt
->
ptr
=
NULL
;
if
(
bkt
->
ksl
)
{
nghttp2_ksl_free
(
bkt
->
ksl
);
nghttp2_mem_free
(
map
->
mem
,
bkt
->
ksl
);
bkt
->
ksl
=
NULL
;
}
}
map
->
size
=
0
;
}
size_t
nghttp2_map_size
(
nghttp2_map
*
map
)
{
return
map
->
size
;
}
lib/nghttp2_map.h
View file @
1ce62852
/*
* 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
...
...
@@ -30,8 +31,9 @@
#endif
/* HAVE_CONFIG_H */
#include <nghttp2/nghttp2.h>
#include "nghttp2_int.h"
#include "nghttp2_mem.h"
#include "nghttp2_ksl.h"
/* Implementation of unordered map */
...
...
@@ -46,8 +48,13 @@ typedef struct nghttp2_map_entry {
#endif
}
nghttp2_map_entry
;
typedef
struct
nghttp2_map_bucket
{
nghttp2_map_entry
*
ptr
;
nghttp2_ksl
*
ksl
;
}
nghttp2_map_bucket
;
typedef
struct
{
nghttp2_map_
entry
*
*
table
;
nghttp2_map_
bucket
*
table
;
nghttp2_mem
*
mem
;
size_t
size
;
uint32_t
tablelen
;
...
...
@@ -118,6 +125,11 @@ nghttp2_map_entry *nghttp2_map_find(nghttp2_map *map, key_type key);
*/
int
nghttp2_map_remove
(
nghttp2_map
*
map
,
key_type
key
);
/*
* Removes all entries from |map|.
*/
void
nghttp2_map_clear
(
nghttp2_map
*
map
);
/*
* Returns the number of items stored in the map |map|.
*/
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment