diff --git a/BUILD b/BUILD
index a5998824fb699..dfc5eac40d29e 100644
--- a/BUILD
+++ b/BUILD
@@ -2826,6 +2826,17 @@ grpc_cc_library(
],
)
+grpc_cc_library(
+ name = "hpack_constants",
+ hdrs = [
+ "src/core/ext/transport/chttp2/transport/hpack_constants.h",
+ ],
+ language = "c++",
+ deps = [
+ "gpr_platform",
+ ],
+)
+
grpc_cc_library(
name = "hpack_encoder_index",
hdrs = [
@@ -2840,6 +2851,24 @@ grpc_cc_library(
],
)
+grpc_cc_library(
+ name = "hpack_encoder_table",
+ srcs = [
+ "src/core/ext/transport/chttp2/transport/hpack_encoder_table.cc",
+ ],
+ hdrs = [
+ "src/core/ext/transport/chttp2/transport/hpack_encoder_table.h",
+ ],
+ external_deps = [
+ "absl/container:inlined_vector",
+ ],
+ language = "c++",
+ deps = [
+ "gpr",
+ "hpack_constants",
+ ],
+)
+
grpc_cc_library(
name = "grpc_transport_chttp2",
srcs = [
@@ -2858,7 +2887,8 @@ grpc_cc_library(
"src/core/ext/transport/chttp2/transport/frame_window_update.cc",
"src/core/ext/transport/chttp2/transport/hpack_encoder.cc",
"src/core/ext/transport/chttp2/transport/hpack_parser.cc",
- "src/core/ext/transport/chttp2/transport/hpack_table.cc",
+ "src/core/ext/transport/chttp2/transport/hpack_parser_table.cc",
+ "src/core/ext/transport/chttp2/transport/hpack_utils.cc",
"src/core/ext/transport/chttp2/transport/http2_settings.cc",
"src/core/ext/transport/chttp2/transport/huffsyms.cc",
"src/core/ext/transport/chttp2/transport/incoming_metadata.cc",
@@ -2884,7 +2914,8 @@ grpc_cc_library(
"src/core/ext/transport/chttp2/transport/frame_window_update.h",
"src/core/ext/transport/chttp2/transport/hpack_encoder.h",
"src/core/ext/transport/chttp2/transport/hpack_parser.h",
- "src/core/ext/transport/chttp2/transport/hpack_table.h",
+ "src/core/ext/transport/chttp2/transport/hpack_parser_table.h",
+ "src/core/ext/transport/chttp2/transport/hpack_utils.h",
"src/core/ext/transport/chttp2/transport/http2_settings.h",
"src/core/ext/transport/chttp2/transport/huffsyms.h",
"src/core/ext/transport/chttp2/transport/incoming_metadata.h",
@@ -2907,7 +2938,9 @@ grpc_cc_library(
"grpc_http_filters",
"grpc_trace",
"grpc_transport_chttp2_alpn",
+ "hpack_constants",
"hpack_encoder_index",
+ "hpack_encoder_table",
"match",
"popularity_count",
],
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 888192f1d300a..19ec6964ad4a4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -633,8 +633,8 @@ if(gRPC_BUILD_TESTS)
add_dependencies(buildtests_c histogram_test)
add_dependencies(buildtests_c host_port_test)
add_dependencies(buildtests_c hpack_encoder_test)
+ add_dependencies(buildtests_c hpack_parser_table_test)
add_dependencies(buildtests_c hpack_parser_test)
- add_dependencies(buildtests_c hpack_table_test)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_c httpcli_test)
endif()
@@ -1654,8 +1654,10 @@ add_library(grpc
src/core/ext/transport/chttp2/transport/frame_settings.cc
src/core/ext/transport/chttp2/transport/frame_window_update.cc
src/core/ext/transport/chttp2/transport/hpack_encoder.cc
+ src/core/ext/transport/chttp2/transport/hpack_encoder_table.cc
src/core/ext/transport/chttp2/transport/hpack_parser.cc
- src/core/ext/transport/chttp2/transport/hpack_table.cc
+ src/core/ext/transport/chttp2/transport/hpack_parser_table.cc
+ src/core/ext/transport/chttp2/transport/hpack_utils.cc
src/core/ext/transport/chttp2/transport/http2_settings.cc
src/core/ext/transport/chttp2/transport/huffsyms.cc
src/core/ext/transport/chttp2/transport/incoming_metadata.cc
@@ -2479,8 +2481,10 @@ add_library(grpc_unsecure
src/core/ext/transport/chttp2/transport/frame_settings.cc
src/core/ext/transport/chttp2/transport/frame_window_update.cc
src/core/ext/transport/chttp2/transport/hpack_encoder.cc
+ src/core/ext/transport/chttp2/transport/hpack_encoder_table.cc
src/core/ext/transport/chttp2/transport/hpack_parser.cc
- src/core/ext/transport/chttp2/transport/hpack_table.cc
+ src/core/ext/transport/chttp2/transport/hpack_parser_table.cc
+ src/core/ext/transport/chttp2/transport/hpack_utils.cc
src/core/ext/transport/chttp2/transport/http2_settings.cc
src/core/ext/transport/chttp2/transport/huffsyms.cc
src/core/ext/transport/chttp2/transport/incoming_metadata.cc
@@ -5831,11 +5835,11 @@ target_link_libraries(hpack_encoder_test
endif()
if(gRPC_BUILD_TESTS)
-add_executable(hpack_parser_test
- test/core/transport/chttp2/hpack_parser_test.cc
+add_executable(hpack_parser_table_test
+ test/core/transport/chttp2/hpack_parser_table_test.cc
)
-target_include_directories(hpack_parser_test
+target_include_directories(hpack_parser_table_test
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
@@ -5849,7 +5853,7 @@ target_include_directories(hpack_parser_test
${_gRPC_ZLIB_INCLUDE_DIR}
)
-target_link_libraries(hpack_parser_test
+target_link_libraries(hpack_parser_table_test
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
)
@@ -5858,11 +5862,11 @@ target_link_libraries(hpack_parser_test
endif()
if(gRPC_BUILD_TESTS)
-add_executable(hpack_table_test
- test/core/transport/chttp2/hpack_table_test.cc
+add_executable(hpack_parser_test
+ test/core/transport/chttp2/hpack_parser_test.cc
)
-target_include_directories(hpack_table_test
+target_include_directories(hpack_parser_test
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
@@ -5876,7 +5880,7 @@ target_include_directories(hpack_table_test
${_gRPC_ZLIB_INCLUDE_DIR}
)
-target_link_libraries(hpack_table_test
+target_link_libraries(hpack_parser_test
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
)
diff --git a/Makefile b/Makefile
index a59895e0b10d9..da2a37915e954 100644
--- a/Makefile
+++ b/Makefile
@@ -1144,8 +1144,10 @@ LIBGRPC_SRC = \
src/core/ext/transport/chttp2/transport/frame_settings.cc \
src/core/ext/transport/chttp2/transport/frame_window_update.cc \
src/core/ext/transport/chttp2/transport/hpack_encoder.cc \
+ src/core/ext/transport/chttp2/transport/hpack_encoder_table.cc \
src/core/ext/transport/chttp2/transport/hpack_parser.cc \
- src/core/ext/transport/chttp2/transport/hpack_table.cc \
+ src/core/ext/transport/chttp2/transport/hpack_parser_table.cc \
+ src/core/ext/transport/chttp2/transport/hpack_utils.cc \
src/core/ext/transport/chttp2/transport/http2_settings.cc \
src/core/ext/transport/chttp2/transport/huffsyms.cc \
src/core/ext/transport/chttp2/transport/incoming_metadata.cc \
@@ -1817,8 +1819,10 @@ LIBGRPC_UNSECURE_SRC = \
src/core/ext/transport/chttp2/transport/frame_settings.cc \
src/core/ext/transport/chttp2/transport/frame_window_update.cc \
src/core/ext/transport/chttp2/transport/hpack_encoder.cc \
+ src/core/ext/transport/chttp2/transport/hpack_encoder_table.cc \
src/core/ext/transport/chttp2/transport/hpack_parser.cc \
- src/core/ext/transport/chttp2/transport/hpack_table.cc \
+ src/core/ext/transport/chttp2/transport/hpack_parser_table.cc \
+ src/core/ext/transport/chttp2/transport/hpack_utils.cc \
src/core/ext/transport/chttp2/transport/http2_settings.cc \
src/core/ext/transport/chttp2/transport/huffsyms.cc \
src/core/ext/transport/chttp2/transport/incoming_metadata.cc \
diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml
index a07338f3c69a5..fabcebbbad056 100644
--- a/build_autogenerated.yaml
+++ b/build_autogenerated.yaml
@@ -512,10 +512,13 @@ libs:
- src/core/ext/transport/chttp2/transport/frame_rst_stream.h
- src/core/ext/transport/chttp2/transport/frame_settings.h
- src/core/ext/transport/chttp2/transport/frame_window_update.h
+ - src/core/ext/transport/chttp2/transport/hpack_constants.h
- src/core/ext/transport/chttp2/transport/hpack_encoder.h
- src/core/ext/transport/chttp2/transport/hpack_encoder_index.h
+ - src/core/ext/transport/chttp2/transport/hpack_encoder_table.h
- src/core/ext/transport/chttp2/transport/hpack_parser.h
- - src/core/ext/transport/chttp2/transport/hpack_table.h
+ - src/core/ext/transport/chttp2/transport/hpack_parser_table.h
+ - src/core/ext/transport/chttp2/transport/hpack_utils.h
- src/core/ext/transport/chttp2/transport/http2_settings.h
- src/core/ext/transport/chttp2/transport/huffsyms.h
- src/core/ext/transport/chttp2/transport/incoming_metadata.h
@@ -1051,8 +1054,10 @@ libs:
- src/core/ext/transport/chttp2/transport/frame_settings.cc
- src/core/ext/transport/chttp2/transport/frame_window_update.cc
- src/core/ext/transport/chttp2/transport/hpack_encoder.cc
+ - src/core/ext/transport/chttp2/transport/hpack_encoder_table.cc
- src/core/ext/transport/chttp2/transport/hpack_parser.cc
- - src/core/ext/transport/chttp2/transport/hpack_table.cc
+ - src/core/ext/transport/chttp2/transport/hpack_parser_table.cc
+ - src/core/ext/transport/chttp2/transport/hpack_utils.cc
- src/core/ext/transport/chttp2/transport/http2_settings.cc
- src/core/ext/transport/chttp2/transport/huffsyms.cc
- src/core/ext/transport/chttp2/transport/incoming_metadata.cc
@@ -1743,10 +1748,13 @@ libs:
- src/core/ext/transport/chttp2/transport/frame_rst_stream.h
- src/core/ext/transport/chttp2/transport/frame_settings.h
- src/core/ext/transport/chttp2/transport/frame_window_update.h
+ - src/core/ext/transport/chttp2/transport/hpack_constants.h
- src/core/ext/transport/chttp2/transport/hpack_encoder.h
- src/core/ext/transport/chttp2/transport/hpack_encoder_index.h
+ - src/core/ext/transport/chttp2/transport/hpack_encoder_table.h
- src/core/ext/transport/chttp2/transport/hpack_parser.h
- - src/core/ext/transport/chttp2/transport/hpack_table.h
+ - src/core/ext/transport/chttp2/transport/hpack_parser_table.h
+ - src/core/ext/transport/chttp2/transport/hpack_utils.h
- src/core/ext/transport/chttp2/transport/http2_settings.h
- src/core/ext/transport/chttp2/transport/huffsyms.h
- src/core/ext/transport/chttp2/transport/incoming_metadata.h
@@ -2007,8 +2015,10 @@ libs:
- src/core/ext/transport/chttp2/transport/frame_settings.cc
- src/core/ext/transport/chttp2/transport/frame_window_update.cc
- src/core/ext/transport/chttp2/transport/hpack_encoder.cc
+ - src/core/ext/transport/chttp2/transport/hpack_encoder_table.cc
- src/core/ext/transport/chttp2/transport/hpack_parser.cc
- - src/core/ext/transport/chttp2/transport/hpack_table.cc
+ - src/core/ext/transport/chttp2/transport/hpack_parser_table.cc
+ - src/core/ext/transport/chttp2/transport/hpack_utils.cc
- src/core/ext/transport/chttp2/transport/http2_settings.cc
- src/core/ext/transport/chttp2/transport/huffsyms.cc
- src/core/ext/transport/chttp2/transport/incoming_metadata.cc
@@ -3517,21 +3527,21 @@ targets:
deps:
- grpc_test_util
uses_polling: false
-- name: hpack_parser_test
+- name: hpack_parser_table_test
build: test
language: c
headers: []
src:
- - test/core/transport/chttp2/hpack_parser_test.cc
+ - test/core/transport/chttp2/hpack_parser_table_test.cc
deps:
- grpc_test_util
uses_polling: false
-- name: hpack_table_test
+- name: hpack_parser_test
build: test
language: c
headers: []
src:
- - test/core/transport/chttp2/hpack_table_test.cc
+ - test/core/transport/chttp2/hpack_parser_test.cc
deps:
- grpc_test_util
uses_polling: false
diff --git a/config.m4 b/config.m4
index a89624e2bd948..4864f75b53e8b 100644
--- a/config.m4
+++ b/config.m4
@@ -139,8 +139,10 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/transport/chttp2/transport/frame_settings.cc \
src/core/ext/transport/chttp2/transport/frame_window_update.cc \
src/core/ext/transport/chttp2/transport/hpack_encoder.cc \
+ src/core/ext/transport/chttp2/transport/hpack_encoder_table.cc \
src/core/ext/transport/chttp2/transport/hpack_parser.cc \
- src/core/ext/transport/chttp2/transport/hpack_table.cc \
+ src/core/ext/transport/chttp2/transport/hpack_parser_table.cc \
+ src/core/ext/transport/chttp2/transport/hpack_utils.cc \
src/core/ext/transport/chttp2/transport/http2_settings.cc \
src/core/ext/transport/chttp2/transport/huffsyms.cc \
src/core/ext/transport/chttp2/transport/incoming_metadata.cc \
diff --git a/config.w32 b/config.w32
index ae75259da0453..66eb917b8b9c5 100644
--- a/config.w32
+++ b/config.w32
@@ -105,8 +105,10 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\transport\\chttp2\\transport\\frame_settings.cc " +
"src\\core\\ext\\transport\\chttp2\\transport\\frame_window_update.cc " +
"src\\core\\ext\\transport\\chttp2\\transport\\hpack_encoder.cc " +
+ "src\\core\\ext\\transport\\chttp2\\transport\\hpack_encoder_table.cc " +
"src\\core\\ext\\transport\\chttp2\\transport\\hpack_parser.cc " +
- "src\\core\\ext\\transport\\chttp2\\transport\\hpack_table.cc " +
+ "src\\core\\ext\\transport\\chttp2\\transport\\hpack_parser_table.cc " +
+ "src\\core\\ext\\transport\\chttp2\\transport\\hpack_utils.cc " +
"src\\core\\ext\\transport\\chttp2\\transport\\http2_settings.cc " +
"src\\core\\ext\\transport\\chttp2\\transport\\huffsyms.cc " +
"src\\core\\ext\\transport\\chttp2\\transport\\incoming_metadata.cc " +
diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec
index 484171bd451a3..cf72b0f4f520a 100644
--- a/gRPC-C++.podspec
+++ b/gRPC-C++.podspec
@@ -282,10 +282,13 @@ Pod::Spec.new do |s|
'src/core/ext/transport/chttp2/transport/frame_rst_stream.h',
'src/core/ext/transport/chttp2/transport/frame_settings.h',
'src/core/ext/transport/chttp2/transport/frame_window_update.h',
+ 'src/core/ext/transport/chttp2/transport/hpack_constants.h',
'src/core/ext/transport/chttp2/transport/hpack_encoder.h',
'src/core/ext/transport/chttp2/transport/hpack_encoder_index.h',
+ 'src/core/ext/transport/chttp2/transport/hpack_encoder_table.h',
'src/core/ext/transport/chttp2/transport/hpack_parser.h',
- 'src/core/ext/transport/chttp2/transport/hpack_table.h',
+ 'src/core/ext/transport/chttp2/transport/hpack_parser_table.h',
+ 'src/core/ext/transport/chttp2/transport/hpack_utils.h',
'src/core/ext/transport/chttp2/transport/http2_settings.h',
'src/core/ext/transport/chttp2/transport/huffsyms.h',
'src/core/ext/transport/chttp2/transport/incoming_metadata.h',
@@ -946,10 +949,13 @@ Pod::Spec.new do |s|
'src/core/ext/transport/chttp2/transport/frame_rst_stream.h',
'src/core/ext/transport/chttp2/transport/frame_settings.h',
'src/core/ext/transport/chttp2/transport/frame_window_update.h',
+ 'src/core/ext/transport/chttp2/transport/hpack_constants.h',
'src/core/ext/transport/chttp2/transport/hpack_encoder.h',
'src/core/ext/transport/chttp2/transport/hpack_encoder_index.h',
+ 'src/core/ext/transport/chttp2/transport/hpack_encoder_table.h',
'src/core/ext/transport/chttp2/transport/hpack_parser.h',
- 'src/core/ext/transport/chttp2/transport/hpack_table.h',
+ 'src/core/ext/transport/chttp2/transport/hpack_parser_table.h',
+ 'src/core/ext/transport/chttp2/transport/hpack_utils.h',
'src/core/ext/transport/chttp2/transport/http2_settings.h',
'src/core/ext/transport/chttp2/transport/huffsyms.h',
'src/core/ext/transport/chttp2/transport/incoming_metadata.h',
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index 964433810617b..cefc6ada925a4 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -371,13 +371,18 @@ Pod::Spec.new do |s|
'src/core/ext/transport/chttp2/transport/frame_settings.h',
'src/core/ext/transport/chttp2/transport/frame_window_update.cc',
'src/core/ext/transport/chttp2/transport/frame_window_update.h',
+ 'src/core/ext/transport/chttp2/transport/hpack_constants.h',
'src/core/ext/transport/chttp2/transport/hpack_encoder.cc',
'src/core/ext/transport/chttp2/transport/hpack_encoder.h',
'src/core/ext/transport/chttp2/transport/hpack_encoder_index.h',
+ 'src/core/ext/transport/chttp2/transport/hpack_encoder_table.cc',
+ 'src/core/ext/transport/chttp2/transport/hpack_encoder_table.h',
'src/core/ext/transport/chttp2/transport/hpack_parser.cc',
'src/core/ext/transport/chttp2/transport/hpack_parser.h',
- 'src/core/ext/transport/chttp2/transport/hpack_table.cc',
- 'src/core/ext/transport/chttp2/transport/hpack_table.h',
+ 'src/core/ext/transport/chttp2/transport/hpack_parser_table.cc',
+ 'src/core/ext/transport/chttp2/transport/hpack_parser_table.h',
+ 'src/core/ext/transport/chttp2/transport/hpack_utils.cc',
+ 'src/core/ext/transport/chttp2/transport/hpack_utils.h',
'src/core/ext/transport/chttp2/transport/http2_settings.cc',
'src/core/ext/transport/chttp2/transport/http2_settings.h',
'src/core/ext/transport/chttp2/transport/huffsyms.cc',
@@ -1527,10 +1532,13 @@ Pod::Spec.new do |s|
'src/core/ext/transport/chttp2/transport/frame_rst_stream.h',
'src/core/ext/transport/chttp2/transport/frame_settings.h',
'src/core/ext/transport/chttp2/transport/frame_window_update.h',
+ 'src/core/ext/transport/chttp2/transport/hpack_constants.h',
'src/core/ext/transport/chttp2/transport/hpack_encoder.h',
'src/core/ext/transport/chttp2/transport/hpack_encoder_index.h',
+ 'src/core/ext/transport/chttp2/transport/hpack_encoder_table.h',
'src/core/ext/transport/chttp2/transport/hpack_parser.h',
- 'src/core/ext/transport/chttp2/transport/hpack_table.h',
+ 'src/core/ext/transport/chttp2/transport/hpack_parser_table.h',
+ 'src/core/ext/transport/chttp2/transport/hpack_utils.h',
'src/core/ext/transport/chttp2/transport/http2_settings.h',
'src/core/ext/transport/chttp2/transport/huffsyms.h',
'src/core/ext/transport/chttp2/transport/incoming_metadata.h',
diff --git a/grpc.gemspec b/grpc.gemspec
index 9d639c72cbc0b..bc51e13ae2960 100644
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -284,13 +284,18 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/transport/chttp2/transport/frame_settings.h )
s.files += %w( src/core/ext/transport/chttp2/transport/frame_window_update.cc )
s.files += %w( src/core/ext/transport/chttp2/transport/frame_window_update.h )
+ s.files += %w( src/core/ext/transport/chttp2/transport/hpack_constants.h )
s.files += %w( src/core/ext/transport/chttp2/transport/hpack_encoder.cc )
s.files += %w( src/core/ext/transport/chttp2/transport/hpack_encoder.h )
s.files += %w( src/core/ext/transport/chttp2/transport/hpack_encoder_index.h )
+ s.files += %w( src/core/ext/transport/chttp2/transport/hpack_encoder_table.cc )
+ s.files += %w( src/core/ext/transport/chttp2/transport/hpack_encoder_table.h )
s.files += %w( src/core/ext/transport/chttp2/transport/hpack_parser.cc )
s.files += %w( src/core/ext/transport/chttp2/transport/hpack_parser.h )
- s.files += %w( src/core/ext/transport/chttp2/transport/hpack_table.cc )
- s.files += %w( src/core/ext/transport/chttp2/transport/hpack_table.h )
+ s.files += %w( src/core/ext/transport/chttp2/transport/hpack_parser_table.cc )
+ s.files += %w( src/core/ext/transport/chttp2/transport/hpack_parser_table.h )
+ s.files += %w( src/core/ext/transport/chttp2/transport/hpack_utils.cc )
+ s.files += %w( src/core/ext/transport/chttp2/transport/hpack_utils.h )
s.files += %w( src/core/ext/transport/chttp2/transport/http2_settings.cc )
s.files += %w( src/core/ext/transport/chttp2/transport/http2_settings.h )
s.files += %w( src/core/ext/transport/chttp2/transport/huffsyms.cc )
diff --git a/grpc.gyp b/grpc.gyp
index 78f80288a0272..d3272f865da7c 100644
--- a/grpc.gyp
+++ b/grpc.gyp
@@ -585,8 +585,10 @@
'src/core/ext/transport/chttp2/transport/frame_settings.cc',
'src/core/ext/transport/chttp2/transport/frame_window_update.cc',
'src/core/ext/transport/chttp2/transport/hpack_encoder.cc',
+ 'src/core/ext/transport/chttp2/transport/hpack_encoder_table.cc',
'src/core/ext/transport/chttp2/transport/hpack_parser.cc',
- 'src/core/ext/transport/chttp2/transport/hpack_table.cc',
+ 'src/core/ext/transport/chttp2/transport/hpack_parser_table.cc',
+ 'src/core/ext/transport/chttp2/transport/hpack_utils.cc',
'src/core/ext/transport/chttp2/transport/http2_settings.cc',
'src/core/ext/transport/chttp2/transport/huffsyms.cc',
'src/core/ext/transport/chttp2/transport/incoming_metadata.cc',
@@ -1233,8 +1235,10 @@
'src/core/ext/transport/chttp2/transport/frame_settings.cc',
'src/core/ext/transport/chttp2/transport/frame_window_update.cc',
'src/core/ext/transport/chttp2/transport/hpack_encoder.cc',
+ 'src/core/ext/transport/chttp2/transport/hpack_encoder_table.cc',
'src/core/ext/transport/chttp2/transport/hpack_parser.cc',
- 'src/core/ext/transport/chttp2/transport/hpack_table.cc',
+ 'src/core/ext/transport/chttp2/transport/hpack_parser_table.cc',
+ 'src/core/ext/transport/chttp2/transport/hpack_utils.cc',
'src/core/ext/transport/chttp2/transport/http2_settings.cc',
'src/core/ext/transport/chttp2/transport/huffsyms.cc',
'src/core/ext/transport/chttp2/transport/incoming_metadata.cc',
diff --git a/package.xml b/package.xml
index 70dd88d63433b..7ffebca6da7c7 100644
--- a/package.xml
+++ b/package.xml
@@ -264,13 +264,18 @@
+
+
+
-
-
+
+
+
+
diff --git a/src/core/ext/transport/chttp2/transport/hpack_constants.h b/src/core/ext/transport/chttp2/transport/hpack_constants.h
new file mode 100644
index 0000000000000..fb98917ff8414
--- /dev/null
+++ b/src/core/ext/transport/chttp2/transport/hpack_constants.h
@@ -0,0 +1,41 @@
+// Copyright 2021 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_CONSTANTS_H
+#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_CONSTANTS_H
+
+#include
+
+#include
+
+namespace grpc_core {
+namespace hpack_constants {
+// Per entry overhead bytes as per the spec
+static constexpr uint32_t kEntryOverhead = 32;
+// Initial table size as per the spec
+static constexpr uint32_t kInitialTableSize = 4096;
+
+// last index in the static table
+static constexpr uint32_t kLastStaticEntry = 61;
+
+static constexpr uint32_t EntriesForBytes(uint32_t bytes) noexcept {
+ return (bytes + kEntryOverhead - 1) / kEntryOverhead;
+}
+
+static constexpr uint32_t kInitialTableEntries =
+ EntriesForBytes(kInitialTableSize);
+} // namespace hpack_constants
+} // namespace grpc_core
+
+#endif // GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_CONSTANTS_H
diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc
index 98cda589f6140..109bdbc671ea6 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc
+++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc
@@ -32,7 +32,7 @@
#include
#include "src/core/ext/transport/chttp2/transport/bin_encoder.h"
-#include "src/core/ext/transport/chttp2/transport/hpack_table.h"
+#include "src/core/ext/transport/chttp2/transport/hpack_utils.h"
#include "src/core/ext/transport/chttp2/transport/varint.h"
#include "src/core/lib/debug/stats.h"
#include "src/core/lib/slice/slice_internal.h"
@@ -198,55 +198,12 @@ static uint8_t* add_tiny_header_data(framer_state* st, size_t len) {
return grpc_slice_buffer_tiny_add(st->output, len);
}
-static void evict_entry(grpc_chttp2_hpack_compressor* c) {
- c->tail_remote_index++;
- GPR_ASSERT(c->tail_remote_index > 0);
- GPR_ASSERT(c->table_size >=
- c->table_elem_size[c->tail_remote_index % c->cap_table_elems]);
- GPR_ASSERT(c->table_elems > 0);
- c->table_size = static_cast(
- c->table_size -
- c->table_elem_size[c->tail_remote_index % c->cap_table_elems]);
- c->table_elems--;
-}
-
-// Reserve space in table for the new element, evict entries if needed.
-// Return the new index of the element. Return 0 to indicate not adding to
-// table.
-static uint32_t prepare_space_for_new_elem(grpc_chttp2_hpack_compressor* c,
- size_t elem_size) {
- uint32_t new_index = c->tail_remote_index + c->table_elems + 1;
- GPR_DEBUG_ASSERT(elem_size < 65536);
-
- // TODO(arjunroy): Re-examine semantics
- if (elem_size > c->max_table_size) {
- while (c->table_size > 0) {
- evict_entry(c);
- }
- return 0;
- }
-
- /* Reserve space for this element in the remote table: if this overflows
- the current table, drop elements until it fits, matching the decompressor
- algorithm */
- while (c->table_size + elem_size > c->max_table_size) {
- evict_entry(c);
- }
- GPR_ASSERT(c->table_elems < c->max_table_size);
- c->table_elem_size[new_index % c->cap_table_elems] =
- static_cast(elem_size);
- c->table_size = static_cast(c->table_size + elem_size);
- c->table_elems++;
-
- return new_index;
-}
-
// Add a key to the dynamic table. Both key and value will be added to table at
// the decoder.
static void AddKeyWithIndex(grpc_chttp2_hpack_compressor* c,
grpc_slice_refcount* key_ref, uint32_t new_index,
uint32_t key_hash) {
- c->key_table->Insert(
+ c->key_index->Insert(
grpc_chttp2_hpack_compressor::KeySliceRef(key_ref, key_hash), new_index);
}
@@ -255,14 +212,14 @@ static void AddElemWithIndex(grpc_chttp2_hpack_compressor* c, grpc_mdelem elem,
uint32_t new_index, uint32_t elem_hash,
uint32_t key_hash) {
GPR_DEBUG_ASSERT(GRPC_MDELEM_IS_INTERNED(elem));
- c->elem_table->Insert(grpc_chttp2_hpack_compressor::KeyElem(elem, elem_hash),
+ c->elem_index->Insert(grpc_chttp2_hpack_compressor::KeyElem(elem, elem_hash),
new_index);
AddKeyWithIndex(c, GRPC_MDKEY(elem).refcount, new_index, key_hash);
}
static void add_elem(grpc_chttp2_hpack_compressor* c, grpc_mdelem elem,
size_t elem_size, uint32_t elem_hash, uint32_t key_hash) {
- uint32_t new_index = prepare_space_for_new_elem(c, elem_size);
+ uint32_t new_index = c->table->AllocateIndex(elem_size);
if (new_index != 0) {
AddElemWithIndex(c, elem, new_index, elem_hash, key_hash);
}
@@ -270,7 +227,7 @@ static void add_elem(grpc_chttp2_hpack_compressor* c, grpc_mdelem elem,
static void add_key(grpc_chttp2_hpack_compressor* c, grpc_mdelem elem,
size_t elem_size, uint32_t key_hash) {
- uint32_t new_index = prepare_space_for_new_elem(c, elem_size);
+ uint32_t new_index = c->table->AllocateIndex(elem_size);
if (new_index != 0) {
AddKeyWithIndex(c, GRPC_MDKEY(elem).refcount, new_index, key_hash);
}
@@ -411,8 +368,8 @@ static void emit_lithdr_v(grpc_chttp2_hpack_compressor* /*c*/, grpc_mdelem elem,
static void emit_advertise_table_size_change(grpc_chttp2_hpack_compressor* c,
framer_state* st) {
- uint32_t len = GRPC_CHTTP2_VARINT_LENGTH(c->max_table_size, 3);
- GRPC_CHTTP2_WRITE_VARINT(c->max_table_size, 3, 0x20,
+ uint32_t len = GRPC_CHTTP2_VARINT_LENGTH(c->table->max_size(), 3);
+ GRPC_CHTTP2_WRITE_VARINT(c->table->max_size(), 3, 0x20,
add_tiny_header_data(st, len), len);
c->advertise_table_size_change = 0;
}
@@ -435,11 +392,6 @@ static void GPR_ATTRIBUTE_NOINLINE hpack_enc_log(grpc_mdelem elem) {
gpr_free(v);
}
-static uint32_t dynidx(grpc_chttp2_hpack_compressor* c, uint32_t elem_index) {
- return 1 + grpc_core::HPackTable::kLastStaticEntry + c->tail_remote_index +
- c->table_elems - elem_index;
-}
-
struct EmitIndexedStatus {
EmitIndexedStatus() = default;
EmitIndexedStatus(uint32_t elem_hash, bool emitted, bool can_add)
@@ -461,12 +413,13 @@ static EmitIndexedStatus maybe_emit_indexed(grpc_chttp2_hpack_compressor* c,
->hash();
// Update filter to see if we can perhaps add this elem.
bool can_add_to_hashtable =
- c->filter_elems.AddElement(HASH_FRAGMENT_1(elem_hash));
+ c->filter_elems->AddElement(HASH_FRAGMENT_1(elem_hash));
/* is this elem currently in the decoders table? */
- auto indices_key = c->elem_table->Lookup(
+ auto indices_key = c->elem_index->Lookup(
grpc_chttp2_hpack_compressor::KeyElem(elem, elem_hash));
- if (indices_key.has_value() && *indices_key > c->tail_remote_index) {
- emit_indexed(c, dynidx(c, *indices_key), st);
+ if (indices_key.has_value() &&
+ c->table->ConvertableToDynamicIndex(*indices_key)) {
+ emit_indexed(c, c->table->DynamicIndex(*indices_key), st);
return EmitIndexedStatus(elem_hash, true, false);
}
/* Didn't hit either cuckoo index, so no emit. */
@@ -478,10 +431,12 @@ static void emit_maybe_add(grpc_chttp2_hpack_compressor* c, grpc_mdelem elem,
bool should_add_elem, size_t decoder_space_usage,
uint32_t elem_hash, uint32_t key_hash) {
if (should_add_elem) {
- emit_lithdr(c, dynidx(c, indices_key), elem, st);
+ emit_lithdr(c, c->table->DynamicIndex(indices_key),
+ elem, st);
add_elem(c, elem, decoder_space_usage, elem_hash, key_hash);
} else {
- emit_lithdr(c, dynidx(c, indices_key), elem, st);
+ emit_lithdr(c, c->table->DynamicIndex(indices_key),
+ elem, st);
}
}
@@ -522,7 +477,7 @@ static void hpack_enc(grpc_chttp2_hpack_compressor* c, grpc_mdelem elem,
}
/* should this elem be in the table? */
const size_t decoder_space_usage =
- grpc_chttp2_get_size_in_hpack_table(elem, st->use_true_binary_metadata);
+ grpc_core::MetadataSizeInHPackTable(elem, st->use_true_binary_metadata);
const bool decoder_space_available =
decoder_space_usage < kMaxDecoderSpaceUsage;
const bool should_add_elem =
@@ -530,9 +485,10 @@ static void hpack_enc(grpc_chttp2_hpack_compressor* c, grpc_mdelem elem,
const uint32_t elem_hash = ret.elem_hash;
/* no hits for the elem... maybe there's a key? */
const uint32_t key_hash = elem_key.refcount->Hash(elem_key);
- auto indices_key = c->key_table->Lookup(
+ auto indices_key = c->key_index->Lookup(
grpc_chttp2_hpack_compressor::KeySliceRef(elem_key.refcount, key_hash));
- if (indices_key.has_value() && indices_key > c->tail_remote_index) {
+ if (indices_key.has_value() &&
+ c->table->ConvertableToDynamicIndex(*indices_key)) {
emit_maybe_add(c, elem, st, *indices_key, should_add_elem,
decoder_space_usage, elem_hash, key_hash);
return;
@@ -566,76 +522,38 @@ static void deadline_enc(grpc_chttp2_hpack_compressor* c, grpc_millis deadline,
GRPC_MDELEM_UNREF(mdelem);
}
-static uint32_t elems_for_bytes(uint32_t bytes) { return (bytes + 31) / 32; }
-
void grpc_chttp2_hpack_compressor_init(grpc_chttp2_hpack_compressor* c) {
- memset(c, 0, sizeof(*c));
- c->max_table_size = GRPC_CHTTP2_HPACKC_INITIAL_TABLE_SIZE;
- c->cap_table_elems = elems_for_bytes(c->max_table_size);
- c->max_table_elems = c->cap_table_elems;
- c->max_usable_size = GRPC_CHTTP2_HPACKC_INITIAL_TABLE_SIZE;
- const size_t alloc_size = sizeof(*c->table_elem_size) * c->cap_table_elems;
- c->table_elem_size = static_cast(gpr_malloc(alloc_size));
- c->elem_table.Init();
- c->key_table.Init();
- memset(c->table_elem_size, 0, alloc_size);
+ c->advertise_table_size_change = 0;
+ c->max_usable_size = grpc_core::hpack_constants::kInitialTableSize;
+ c->table.Init();
+ c->filter_elems.Init();
+ c->elem_index.Init();
+ c->key_index.Init();
}
void grpc_chttp2_hpack_compressor_destroy(grpc_chttp2_hpack_compressor* c) {
- c->elem_table.Destroy();
- c->key_table.Destroy();
- gpr_free(c->table_elem_size);
+ c->elem_index.Destroy();
+ c->filter_elems.Destroy();
+ c->key_index.Destroy();
+ c->table.Destroy();
}
void grpc_chttp2_hpack_compressor_set_max_usable_size(
grpc_chttp2_hpack_compressor* c, uint32_t max_table_size) {
c->max_usable_size = max_table_size;
grpc_chttp2_hpack_compressor_set_max_table_size(
- c, GPR_MIN(c->max_table_size, max_table_size));
-}
-
-static void rebuild_elems(grpc_chttp2_hpack_compressor* c, uint32_t new_cap) {
- uint16_t* table_elem_size =
- static_cast(gpr_malloc(sizeof(*table_elem_size) * new_cap));
- uint32_t i;
-
- memset(table_elem_size, 0, sizeof(*table_elem_size) * new_cap);
- GPR_ASSERT(c->table_elems <= new_cap);
-
- for (i = 0; i < c->table_elems; i++) {
- uint32_t ofs = c->tail_remote_index + i + 1;
- table_elem_size[ofs % new_cap] =
- c->table_elem_size[ofs % c->cap_table_elems];
- }
-
- c->cap_table_elems = new_cap;
- gpr_free(c->table_elem_size);
- c->table_elem_size = table_elem_size;
+ c, std::min(c->table->max_size(), max_table_size));
}
void grpc_chttp2_hpack_compressor_set_max_table_size(
grpc_chttp2_hpack_compressor* c, uint32_t max_table_size) {
- max_table_size = GPR_MIN(max_table_size, c->max_usable_size);
- if (max_table_size == c->max_table_size) {
- return;
- }
- while (c->table_size > 0 && c->table_size > max_table_size) {
- evict_entry(c);
- }
- c->max_table_size = max_table_size;
- c->max_table_elems = elems_for_bytes(max_table_size);
- if (c->max_table_elems > c->cap_table_elems) {
- rebuild_elems(c, GPR_MAX(c->max_table_elems, 2 * c->cap_table_elems));
- } else if (c->max_table_elems < c->cap_table_elems / 3) {
- uint32_t new_cap = GPR_MAX(c->max_table_elems, 16);
- if (new_cap != c->cap_table_elems) {
- rebuild_elems(c, new_cap);
+ if (c->table->SetMaxSize(std::min(c->max_usable_size, max_table_size))) {
+ c->advertise_table_size_change = 1;
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) {
+ gpr_log(GPR_INFO, "set max table size from encoder to %d",
+ max_table_size);
}
}
- c->advertise_table_size_change = 1;
- if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) {
- gpr_log(GPR_INFO, "set max table size from encoder to %d", max_table_size);
- }
}
void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor* c,
@@ -678,7 +596,8 @@ void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor* c,
if (is_static &&
(static_index =
reinterpret_cast(GRPC_MDELEM_DATA(md))
- ->StaticIndex()) < grpc_core::HPackTable::kLastStaticEntry) {
+ ->StaticIndex()) <
+ grpc_core::hpack_constants::kLastStaticEntry) {
emit_indexed(c, static_cast(static_index + 1), &st);
} else {
hpack_enc(c, md, &st);
@@ -693,7 +612,7 @@ void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor* c,
(static_index = reinterpret_cast(
GRPC_MDELEM_DATA(l->md))
->StaticIndex()) <
- grpc_core::HPackTable::kLastStaticEntry) {
+ grpc_core::hpack_constants::kLastStaticEntry) {
emit_indexed(c, static_cast(static_index + 1), &st);
} else {
hpack_enc(c, l->md, &st);
diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.h b/src/core/ext/transport/chttp2/transport/hpack_encoder.h
index 3d09d1dc7c433..09a133f8012ae 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_encoder.h
+++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.h
@@ -25,6 +25,7 @@
#include
#include "src/core/ext/transport/chttp2/transport/frame.h"
#include "src/core/ext/transport/chttp2/transport/hpack_encoder_index.h"
+#include "src/core/ext/transport/chttp2/transport/hpack_encoder_table.h"
#include "src/core/ext/transport/chttp2/transport/popularity_count.h"
#include "src/core/lib/transport/metadata.h"
#include "src/core/lib/transport/metadata_batch.h"
@@ -41,17 +42,10 @@
extern grpc_core::TraceFlag grpc_http_trace;
struct grpc_chttp2_hpack_compressor {
- uint32_t max_table_size;
- uint32_t max_table_elems;
- uint32_t cap_table_elems;
- /** maximum number of bytes we'll use for the decode table (to guard against
- peers ooming us by setting decode table size high) */
+ // maximum number of bytes we'll use for the decode table (to guard against
+ // peers ooming us by setting decode table size high)
uint32_t max_usable_size;
- /* one before the lowest usable table index */
- uint32_t tail_remote_index;
- uint32_t table_size;
- uint32_t table_elems;
- uint16_t* table_elem_size;
+ grpc_core::ManualConstructor table;
/** if non-zero, advertise to the decoder that we'll start using a table
of this size */
uint8_t advertise_table_size_change;
@@ -61,7 +55,9 @@ struct grpc_chttp2_hpack_compressor {
a new literal should be added to the compression table or not.
They track a single integer that counts how often a particular value has
been seen. When that count reaches max (255), all values are halved. */
- grpc_core::PopularityCount filter_elems;
+ grpc_core::ManualConstructor<
+ grpc_core::PopularityCount>
+ filter_elems;
class KeyElem {
public:
@@ -140,10 +136,10 @@ struct grpc_chttp2_hpack_compressor {
seen and *may* be in the decompressor table */
grpc_core::ManualConstructor<
grpc_core::HPackEncoderIndex>
- elem_table;
+ elem_index;
grpc_core::ManualConstructor<
grpc_core::HPackEncoderIndex>
- key_table;
+ key_index;
};
void grpc_chttp2_hpack_compressor_init(grpc_chttp2_hpack_compressor* c);
diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder_table.cc b/src/core/ext/transport/chttp2/transport/hpack_encoder_table.cc
new file mode 100644
index 0000000000000..eb08574233f11
--- /dev/null
+++ b/src/core/ext/transport/chttp2/transport/hpack_encoder_table.cc
@@ -0,0 +1,86 @@
+// Copyright 2021 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include
+
+#include
+
+#include "src/core/ext/transport/chttp2/transport/hpack_encoder_table.h"
+
+namespace grpc_core {
+
+uint32_t HPackEncoderTable::AllocateIndex(size_t element_size) {
+ uint32_t new_index = tail_remote_index_ + table_elems_ + 1;
+ GPR_DEBUG_ASSERT(element_size < 65536);
+
+ if (element_size > max_table_size_) {
+ while (table_size_ > 0) {
+ EvictOne();
+ }
+ return 0;
+ }
+
+ // Reserve space for this element in the remote table: if this overflows
+ // the current table, drop elements until it fits, matching the decompressor
+ // algorithm.
+ while (table_size_ + element_size > max_table_size_) {
+ EvictOne();
+ }
+ GPR_ASSERT(table_elems_ < elem_size_.size());
+ elem_size_[new_index % elem_size_.size()] =
+ static_cast(element_size);
+ table_size_ += element_size;
+ table_elems_++;
+
+ return new_index;
+}
+
+bool HPackEncoderTable::SetMaxSize(uint32_t max_table_size) {
+ if (max_table_size == max_table_size_) {
+ return false;
+ }
+ while (table_size_ > 0 && table_size_ > max_table_size) {
+ EvictOne();
+ }
+ max_table_size_ = max_table_size;
+ const size_t max_table_elems =
+ hpack_constants::EntriesForBytes(max_table_size);
+ // TODO(ctiller): integrate with ResourceQuota to rebuild smaller when we can.
+ if (max_table_elems > elem_size_.size()) {
+ Rebuild(std::max(max_table_elems, 2 * elem_size_.size()));
+ }
+ return true;
+}
+
+void HPackEncoderTable::EvictOne() {
+ tail_remote_index_++;
+ GPR_ASSERT(tail_remote_index_ > 0);
+ GPR_ASSERT(table_elems_ > 0);
+ auto removing_size = elem_size_[tail_remote_index_ % elem_size_.size()];
+ GPR_ASSERT(table_size_ >= removing_size);
+ table_size_ -= removing_size;
+ table_elems_--;
+}
+
+void HPackEncoderTable::Rebuild(uint32_t capacity) {
+ decltype(elem_size_) new_elem_size(capacity);
+ GPR_ASSERT(table_elems_ <= capacity);
+ for (uint32_t i = 0; i < table_elems_; i++) {
+ uint32_t ofs = tail_remote_index_ + i + 1;
+ new_elem_size[ofs % capacity] = elem_size_[ofs % elem_size_.size()];
+ }
+ elem_size_.swap(new_elem_size);
+}
+
+} // namespace grpc_core
diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder_table.h b/src/core/ext/transport/chttp2/transport/hpack_encoder_table.h
new file mode 100644
index 0000000000000..6d43ce06479aa
--- /dev/null
+++ b/src/core/ext/transport/chttp2/transport/hpack_encoder_table.h
@@ -0,0 +1,68 @@
+// Copyright 2021 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_ENCODER_TABLE_H
+#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_ENCODER_TABLE_H
+
+#include
+
+#include "absl/container/inlined_vector.h"
+#include "src/core/ext/transport/chttp2/transport/hpack_constants.h"
+
+namespace grpc_core {
+
+// Tracks the values available in the remote HPACK header table, and their
+// sizes.
+class HPackEncoderTable {
+ public:
+ HPackEncoderTable() : elem_size_(hpack_constants::kInitialTableEntries) {}
+
+ // Reserve space in table for the new element, evict entries if needed.
+ // Return the new index of the element. Return 0 to indicate not adding to
+ // table.
+ uint32_t AllocateIndex(size_t element_size);
+ // Set the maximum table size. Return true if it changed.
+ bool SetMaxSize(uint32_t max_table_size);
+ // Get the current max table size
+ uint32_t max_size() const { return max_table_size_; }
+ // Get the current table size
+ uint32_t test_only_table_size() const { return table_size_; }
+
+ // Convert an element index into a dynamic index
+ uint32_t DynamicIndex(uint32_t index) const {
+ return 1 + hpack_constants::kLastStaticEntry + tail_remote_index_ +
+ table_elems_ - index;
+ }
+ // Check if an element index is convertable to a dynamic index
+ bool ConvertableToDynamicIndex(uint32_t index) const {
+ return index > tail_remote_index_;
+ }
+
+ private:
+ void EvictOne();
+ void Rebuild(uint32_t capacity);
+
+ // one before the lowest usable table index
+ uint32_t tail_remote_index_ = 0;
+ uint32_t max_table_size_ = hpack_constants::kInitialTableSize;
+ uint32_t table_elems_ = 0;
+ uint32_t table_size_ = 0;
+ // The size of each element in the HPACK table.
+ absl::InlinedVector
+ elem_size_;
+};
+
+} // namespace grpc_core
+
+#endif // GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_ENCODER_TABLE_H
diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.h b/src/core/ext/transport/chttp2/transport/hpack_parser.h
index d6b6a49e03bfc..0ae7413df523e 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_parser.h
+++ b/src/core/ext/transport/chttp2/transport/hpack_parser.h
@@ -24,7 +24,7 @@
#include
#include "src/core/ext/transport/chttp2/transport/frame.h"
-#include "src/core/ext/transport/chttp2/transport/hpack_table.h"
+#include "src/core/ext/transport/chttp2/transport/hpack_parser_table.h"
#include "src/core/lib/transport/metadata.h"
namespace grpc_core {
diff --git a/src/core/ext/transport/chttp2/transport/hpack_table.cc b/src/core/ext/transport/chttp2/transport/hpack_parser_table.cc
similarity index 78%
rename from src/core/ext/transport/chttp2/transport/hpack_table.cc
rename to src/core/ext/transport/chttp2/transport/hpack_parser_table.cc
index 4e437fc982e8c..8bf7bac632f6f 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_table.cc
+++ b/src/core/ext/transport/chttp2/transport/hpack_parser_table.cc
@@ -18,7 +18,7 @@
#include
-#include "src/core/ext/transport/chttp2/transport/hpack_table.h"
+#include "src/core/ext/transport/chttp2/transport/hpack_parser_table.h"
#include
#include
@@ -38,10 +38,7 @@ extern grpc_core::TraceFlag grpc_http_trace;
namespace grpc_core {
-using hpack_table_detail::EntriesForBytes;
-using hpack_table_detail::kInlineEntries;
-
-HPackTable::HPackTable() : entries_(kInlineEntries) {}
+HPackTable::HPackTable() = default;
HPackTable::~HPackTable() {
for (size_t i = 0; i < num_entries_; i++) {
@@ -54,7 +51,7 @@ void HPackTable::EvictOne() {
grpc_mdelem first_entry = entries_[first_entry_];
size_t elem_bytes = GRPC_SLICE_LENGTH(GRPC_MDKEY(first_entry)) +
GRPC_SLICE_LENGTH(GRPC_MDVALUE(first_entry)) +
- kEntryOverhead;
+ hpack_constants::kEntryOverhead;
GPR_ASSERT(elem_bytes <= mem_used_);
mem_used_ -= static_cast(elem_bytes);
first_entry_ = ((first_entry_ + 1) % entries_.size());
@@ -103,13 +100,14 @@ grpc_error_handle HPackTable::SetCurrentTableSize(uint32_t bytes) {
EvictOne();
}
current_table_bytes_ = bytes;
- max_entries_ = EntriesForBytes(bytes);
+ max_entries_ = hpack_constants::EntriesForBytes(bytes);
if (max_entries_ > entries_.size()) {
Rebuild(max_entries_);
} else if (max_entries_ < entries_.size() / 3) {
// TODO(ctiller): move to resource quota system, only shrink under memory
// pressure
- uint32_t new_cap = std::max(max_entries_, kInlineEntries);
+ uint32_t new_cap =
+ std::max(max_entries_, static_cast(kInlineEntries));
if (new_cap != entries_.size()) {
Rebuild(new_cap);
}
@@ -120,7 +118,8 @@ grpc_error_handle HPackTable::SetCurrentTableSize(uint32_t bytes) {
grpc_error_handle HPackTable::Add(grpc_mdelem md) {
/* determine how many bytes of buffer this entry represents */
size_t elem_bytes = GRPC_SLICE_LENGTH(GRPC_MDKEY(md)) +
- GRPC_SLICE_LENGTH(GRPC_MDVALUE(md)) + kEntryOverhead;
+ GRPC_SLICE_LENGTH(GRPC_MDVALUE(md)) +
+ hpack_constants::kEntryOverhead;
if (current_table_bytes_ > max_bytes_) {
return GRPC_ERROR_CREATE_FROM_COPIED_STRING(
@@ -162,23 +161,3 @@ grpc_error_handle HPackTable::Add(grpc_mdelem md) {
}
} // namespace grpc_core
-
-static size_t get_base64_encoded_size(size_t raw_length) {
- static const uint8_t tail_xtra[3] = {0, 2, 3};
- return raw_length / 3 * 4 + tail_xtra[raw_length % 3];
-}
-
-size_t grpc_chttp2_get_size_in_hpack_table(grpc_mdelem elem,
- bool use_true_binary_metadata) {
- const uint8_t* key_buf = GRPC_SLICE_START_PTR(GRPC_MDKEY(elem));
- size_t key_len = GRPC_SLICE_LENGTH(GRPC_MDKEY(elem));
- size_t overhead_and_key = 32 + key_len;
- size_t value_len = GRPC_SLICE_LENGTH(GRPC_MDVALUE(elem));
- if (grpc_key_is_binary_header(key_buf, key_len)) {
- return overhead_and_key + (use_true_binary_metadata
- ? value_len + 1
- : get_base64_encoded_size(value_len));
- } else {
- return overhead_and_key + value_len;
- }
-}
diff --git a/src/core/ext/transport/chttp2/transport/hpack_table.h b/src/core/ext/transport/chttp2/transport/hpack_parser_table.h
similarity index 70%
rename from src/core/ext/transport/chttp2/transport/hpack_table.h
rename to src/core/ext/transport/chttp2/transport/hpack_parser_table.h
index 25129a9b11bec..0cf09dc930aa7 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_table.h
+++ b/src/core/ext/transport/chttp2/transport/hpack_parser_table.h
@@ -16,12 +16,13 @@
*
*/
-#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_TABLE_H
-#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_TABLE_H
+#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_PARSER_TABLE_H
+#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_PARSER_TABLE_H
#include
#include
+#include "src/core/ext/transport/chttp2/transport/hpack_constants.h"
#include "src/core/lib/gprpp/memory.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/transport/metadata.h"
@@ -29,30 +30,9 @@
namespace grpc_core {
-namespace hpack_table_detail {
-// Per entry overhead bytes as per the spec
-static constexpr uint32_t kEntryOverhead = 32;
-// Initial table size as per the spec
-static constexpr uint32_t kInitialTableSize = 4096;
-
-static constexpr uint32_t EntriesForBytes(uint32_t bytes) noexcept {
- return (bytes + kEntryOverhead - 1) / kEntryOverhead;
-}
-
-static constexpr uint32_t kInlineEntries = EntriesForBytes(kInitialTableSize);
-} // namespace hpack_table_detail
-
// HPACK header table
class HPackTable {
public:
- // last index in the static table
- static constexpr uint32_t kLastStaticEntry = 61;
- // Initial table size as per the spec
- static constexpr uint32_t kInitialTableSize =
- hpack_table_detail::kInitialTableSize;
- // Per entry overhead bytes as per the spec
- static constexpr uint32_t kEntryOverhead = hpack_table_detail::kEntryOverhead;
-
HPackTable();
~HPackTable();
@@ -74,8 +54,8 @@ class HPackTable {
uint32_t num_entries() const { return num_entries_; }
private:
- using EntriesVec =
- absl::InlinedVector;
+ enum { kInlineEntries = hpack_constants::kInitialTableEntries };
+ using EntriesVec = absl::InlinedVector;
/* lookup a table entry based on its hpack index */
template
@@ -86,7 +66,7 @@ class HPackTable {
// must follow the hpack standard. If that changes, we *must* not rely on
// reading the core static metadata table here; at that point we'd need our
// own singleton static metadata in the correct order.
- if (index <= kLastStaticEntry) {
+ if (index <= hpack_constants::kLastStaticEntry) {
return grpc_static_mdelem_manifested()[index - 1];
} else {
return LookupDynamic(index);
@@ -96,7 +76,7 @@ class HPackTable {
template
grpc_mdelem LookupDynamic(uint32_t index) const {
// Not static - find the value in the list of valid entries
- const uint32_t tbl_index = index - (kLastStaticEntry + 1);
+ const uint32_t tbl_index = index - (hpack_constants::kLastStaticEntry + 1);
if (tbl_index < num_entries_) {
uint32_t offset =
(num_entries_ - 1u - tbl_index + first_entry_) % entries_.size();
@@ -121,21 +101,18 @@ class HPackTable {
uint32_t mem_used_ = 0;
// The max memory allowed to be used by the table, according to the hpack
// algorithm.
- uint32_t max_bytes_ = kInitialTableSize;
+ uint32_t max_bytes_ = hpack_constants::kInitialTableSize;
// The currently agreed size of the table, according to the hpack algorithm.
- uint32_t current_table_bytes_ = kInitialTableSize;
+ uint32_t current_table_bytes_ = hpack_constants::kInitialTableSize;
// Maximum number of entries we could possibly fit in the table, given defined
// overheads.
- uint32_t max_entries_ = hpack_table_detail::kInlineEntries;
+ uint32_t max_entries_ = hpack_constants::kInitialTableEntries;
// HPack table entries
- EntriesVec entries_;
+ EntriesVec entries_{hpack_constants::kInitialTableEntries};
};
} // namespace grpc_core
-size_t grpc_chttp2_get_size_in_hpack_table(grpc_mdelem elem,
- bool use_true_binary_metadata);
-
/* Returns the static hpack table index that corresponds to /a elem. Returns 0
if /a elem is not statically stored or if it is not in the static hpack
table */
@@ -143,10 +120,10 @@ inline uintptr_t grpc_chttp2_get_static_hpack_table_index(grpc_mdelem md) {
uintptr_t index =
reinterpret_cast(GRPC_MDELEM_DATA(md)) -
grpc_static_mdelem_table();
- if (index < grpc_core::HPackTable::kLastStaticEntry) {
+ if (index < grpc_core::hpack_constants::kLastStaticEntry) {
return index + 1; // Hpack static metadata element indices start at 1
}
return 0;
}
-#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_TABLE_H */
+#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_PARSER_TABLE_H */
diff --git a/src/core/ext/transport/chttp2/transport/hpack_utils.cc b/src/core/ext/transport/chttp2/transport/hpack_utils.cc
new file mode 100644
index 0000000000000..c4511cedc290b
--- /dev/null
+++ b/src/core/ext/transport/chttp2/transport/hpack_utils.cc
@@ -0,0 +1,45 @@
+// Copyright 2021 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include
+
+#include "src/core/ext/transport/chttp2/transport/hpack_utils.h"
+#include "src/core/lib/surface/validate_metadata.h"
+
+namespace grpc_core {
+
+namespace {
+size_t Base64EncodedSize(size_t raw_length) {
+ static constexpr uint8_t tail_xtra[3] = {0, 2, 3};
+ return raw_length / 3 * 4 + tail_xtra[raw_length % 3];
+}
+} // namespace
+
+// Return the size occupied by some metadata in the HPACK table.
+size_t MetadataSizeInHPackTable(grpc_mdelem elem,
+ bool use_true_binary_metadata) {
+ const uint8_t* key_buf = GRPC_SLICE_START_PTR(GRPC_MDKEY(elem));
+ size_t key_len = GRPC_SLICE_LENGTH(GRPC_MDKEY(elem));
+ size_t overhead_and_key = 32 + key_len;
+ size_t value_len = GRPC_SLICE_LENGTH(GRPC_MDVALUE(elem));
+ if (grpc_key_is_binary_header(key_buf, key_len)) {
+ return overhead_and_key + (use_true_binary_metadata
+ ? value_len + 1
+ : Base64EncodedSize(value_len));
+ } else {
+ return overhead_and_key + value_len;
+ }
+}
+
+} // namespace grpc_core
diff --git a/src/core/ext/transport/chttp2/transport/hpack_utils.h b/src/core/ext/transport/chttp2/transport/hpack_utils.h
new file mode 100644
index 0000000000000..a1c9baa47698a
--- /dev/null
+++ b/src/core/ext/transport/chttp2/transport/hpack_utils.h
@@ -0,0 +1,30 @@
+// Copyright 2021 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_UTILS_H
+#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_UTILS_H
+
+#include
+
+#include "src/core/lib/transport/metadata.h"
+
+namespace grpc_core {
+
+// Return the size occupied by some metadata in the HPACK table.
+size_t MetadataSizeInHPackTable(grpc_mdelem elem,
+ bool use_true_binary_metadata);
+
+} // namespace grpc_core
+
+#endif // GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_UTILS_H
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index 80319c2ba0dc8..5c6dcc1cca212 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -114,8 +114,10 @@
'src/core/ext/transport/chttp2/transport/frame_settings.cc',
'src/core/ext/transport/chttp2/transport/frame_window_update.cc',
'src/core/ext/transport/chttp2/transport/hpack_encoder.cc',
+ 'src/core/ext/transport/chttp2/transport/hpack_encoder_table.cc',
'src/core/ext/transport/chttp2/transport/hpack_parser.cc',
- 'src/core/ext/transport/chttp2/transport/hpack_table.cc',
+ 'src/core/ext/transport/chttp2/transport/hpack_parser_table.cc',
+ 'src/core/ext/transport/chttp2/transport/hpack_utils.cc',
'src/core/ext/transport/chttp2/transport/http2_settings.cc',
'src/core/ext/transport/chttp2/transport/huffsyms.cc',
'src/core/ext/transport/chttp2/transport/incoming_metadata.cc',
diff --git a/test/core/transport/chttp2/BUILD b/test/core/transport/chttp2/BUILD
index 8ebb019f4556c..ad6709a7462b8 100644
--- a/test/core/transport/chttp2/BUILD
+++ b/test/core/transport/chttp2/BUILD
@@ -123,8 +123,8 @@ grpc_cc_test(
)
grpc_cc_test(
- name = "hpack_table_test",
- srcs = ["hpack_table_test.cc"],
+ name = "hpack_parser_table_test",
+ srcs = ["hpack_parser_table_test.cc"],
language = "C++",
uses_polling = False,
deps = [
diff --git a/test/core/transport/chttp2/hpack_encoder_index_test.cc b/test/core/transport/chttp2/hpack_encoder_index_test.cc
index c6402977b8fb6..2222b81b60b53 100644
--- a/test/core/transport/chttp2/hpack_encoder_index_test.cc
+++ b/test/core/transport/chttp2/hpack_encoder_index_test.cc
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2020 gRPC authors.
+ * Copyright 2021 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/test/core/transport/chttp2/hpack_encoder_test.cc b/test/core/transport/chttp2/hpack_encoder_test.cc
index 2ed16fe21f5d1..45182a0e0ab80 100644
--- a/test/core/transport/chttp2/hpack_encoder_test.cc
+++ b/test/core/transport/chttp2/hpack_encoder_test.cc
@@ -30,6 +30,7 @@
#include
#include "src/core/ext/transport/chttp2/transport/hpack_parser.h"
+#include "src/core/ext/transport/chttp2/transport/hpack_utils.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_string_helpers.h"
@@ -345,8 +346,8 @@ static void verify_table_size_change_match_elem_size(const char* key,
grpc_mdelem elem = grpc_mdelem_from_slices(
grpc_slice_intern(grpc_slice_from_static_string(key)),
grpc_slice_intern(grpc_slice_from_static_string(value)));
- size_t elem_size = grpc_chttp2_get_size_in_hpack_table(elem, use_true_binary);
- size_t initial_table_size = g_compressor.table_size;
+ size_t elem_size = grpc_core::MetadataSizeInHPackTable(elem, use_true_binary);
+ size_t initial_table_size = g_compressor.table->test_only_table_size();
grpc_linked_mdelem* e =
static_cast(gpr_malloc(sizeof(*e)));
grpc_metadata_batch b;
@@ -372,7 +373,8 @@ static void verify_table_size_change_match_elem_size(const char* key,
grpc_slice_buffer_destroy_internal(&output);
grpc_metadata_batch_destroy(&b);
- GPR_ASSERT(g_compressor.table_size == elem_size + initial_table_size);
+ GPR_ASSERT(g_compressor.table->test_only_table_size() ==
+ elem_size + initial_table_size);
gpr_free(e);
}
diff --git a/test/core/transport/chttp2/hpack_table_test.cc b/test/core/transport/chttp2/hpack_parser_table_test.cc
similarity index 94%
rename from test/core/transport/chttp2/hpack_table_test.cc
rename to test/core/transport/chttp2/hpack_parser_table_test.cc
index 04b69a9b633fe..6c47e5289fead 100644
--- a/test/core/transport/chttp2/hpack_table_test.cc
+++ b/test/core/transport/chttp2/hpack_parser_table_test.cc
@@ -16,7 +16,7 @@
*
*/
-#include "src/core/ext/transport/chttp2/transport/hpack_table.h"
+#include "src/core/ext/transport/chttp2/transport/hpack_parser_table.h"
#include
#include
@@ -134,13 +134,13 @@ static void test_many_additions(void) {
grpc_slice_from_cpp_string(value));
GPR_ASSERT(tbl.Add(elem) == GRPC_ERROR_NONE);
GRPC_MDELEM_UNREF(elem);
- assert_index(&tbl, 1 + HPackTable::kLastStaticEntry, key.c_str(),
- value.c_str());
+ assert_index(&tbl, 1 + grpc_core::hpack_constants::kLastStaticEntry,
+ key.c_str(), value.c_str());
if (i) {
std::string key = absl::StrCat("K:", i - 1);
std::string value = absl::StrCat("VALUE:", i - 1);
- assert_index(&tbl, 2 + HPackTable::kLastStaticEntry, key.c_str(),
- value.c_str());
+ assert_index(&tbl, 2 + grpc_core::hpack_constants::kLastStaticEntry,
+ key.c_str(), value.c_str());
}
}
}
diff --git a/test/core/transport/chttp2/hpack_utils_test.cc b/test/core/transport/chttp2/hpack_utils_test.cc
new file mode 100644
index 0000000000000..635ec7ee31eef
--- /dev/null
+++ b/test/core/transport/chttp2/hpack_utils_test.cc
@@ -0,0 +1,120 @@
+// Copyright 2021 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include
+
+#include
+#include
+#include
+#include "src/core/ext/transport/chttp2/transport/hpack_encoder_index.h"
+
+namespace grpc_core {
+namespace testing {
+
+static void VerifyAsciiHeaderSize(const char* key, const char* value,
+ bool intern_key, bool intern_value) {
+ grpc_mdelem elem = grpc_mdelem_from_slices(
+ maybe_intern(grpc_slice_from_static_string(key), intern_key),
+ maybe_intern(grpc_slice_from_static_string(value), intern_value));
+ size_t elem_size = grpc_core::MetadataSizeInHPackTable(elem, false);
+ size_t expected_size = 32 + strlen(key) + strlen(value);
+ GPR_ASSERT(expected_size == elem_size);
+ GRPC_MDELEM_UNREF(elem);
+}
+
+static void VerifyBinaryHeaderSize(const char* key, const uint8_t* value,
+ size_t value_len, bool intern_key,
+ bool intern_value) {
+ grpc_mdelem elem = grpc_mdelem_from_slices(
+ maybe_intern(grpc_slice_from_static_string(key), intern_key),
+ maybe_intern(grpc_slice_from_static_buffer(value, value_len),
+ intern_value));
+ GPR_ASSERT(grpc_is_binary_header(GRPC_MDKEY(elem)));
+ size_t elem_size = grpc_core::MetadataSizeInHPackTable(elem, false);
+ grpc_slice value_slice = grpc_slice_from_copied_buffer(
+ reinterpret_cast(value), value_len);
+ grpc_slice base64_encoded = grpc_chttp2_base64_encode(value_slice);
+ size_t expected_size = 32 + strlen(key) + GRPC_SLICE_LENGTH(base64_encoded);
+ GPR_ASSERT(expected_size == elem_size);
+ grpc_slice_unref_internal(value_slice);
+ grpc_slice_unref_internal(base64_encoded);
+ GRPC_MDELEM_UNREF(elem);
+}
+
+struct Param {
+ bool intern_key;
+ bool intern_value;
+}
+
+class MetadataTest : public ::testing::TestWithParam {
+};
+
+#define BUFFER_SIZE 64
+TEST_P(MetadataTest, MetadataSize) {
+ const bool intern_key = GetParam().intern_key;
+ const bool intern_value = GetParam().intern_value;
+ gpr_log(GPR_INFO, "test_mdelem_size: intern_key=%d intern_value=%d",
+ intern_key, intern_value);
+ grpc_init();
+ grpc_core::ExecCtx exec_ctx;
+
+ uint8_t binary_value[BUFFER_SIZE] = {0};
+ for (uint8_t i = 0; i < BUFFER_SIZE; i++) {
+ binary_value[i] = i;
+ }
+
+ verify_ascii_header_size("hello", "world", intern_key, intern_value);
+ verify_ascii_header_size("hello", "worldxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
+ intern_key, intern_value);
+ verify_ascii_header_size(":scheme", "http", intern_key, intern_value);
+
+ for (uint8_t i = 0; i < BUFFER_SIZE; i++) {
+ verify_binary_header_size("hello-bin", binary_value, i, intern_key,
+ intern_value);
+ }
+
+ grpc_shutdown();
+}
+
+INSTANTIATE_TEST_SUITE_P(MetadataTestSuite, MetadataTest,
+ ::testing::Values(Param{false, false},
+ Param{false, true},
+ Param{true, false},
+ Param{true, true}));
+
+TEST(HPackEncoderIndexTest, SetAndGet) {
+ HPackEncoderIndex index;
+ std::default_random_engine rng;
+ std::unordered_map last_index;
+ for (uint32_t i = 0; i < 10000; i++) {
+ uint32_t key = rng();
+ index.Insert({key}, i);
+ EXPECT_EQ(index.Lookup({key}), i);
+ last_index[key] = i;
+ }
+ for (auto p : last_index) {
+ auto r = index.Lookup({p.first});
+ if (r.has_value()) {
+ EXPECT_EQ(*r, p.second);
+ }
+ }
+}
+
+} // namespace testing
+} // namespace grpc_core
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/test/core/transport/metadata_test.cc b/test/core/transport/metadata_test.cc
index 42ada415af912..53ec92e3bed54 100644
--- a/test/core/transport/metadata_test.cc
+++ b/test/core/transport/metadata_test.cc
@@ -31,7 +31,7 @@
#include
#include "src/core/ext/transport/chttp2/transport/bin_encoder.h"
-#include "src/core/ext/transport/chttp2/transport/hpack_table.h"
+#include "src/core/ext/transport/chttp2/transport/hpack_utils.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/slice/slice_internal.h"
@@ -314,61 +314,6 @@ static void test_user_data_works_for_allocated_md(void) {
grpc_shutdown();
}
-static void verify_ascii_header_size(const char* key, const char* value,
- bool intern_key, bool intern_value) {
- grpc_mdelem elem = grpc_mdelem_from_slices(
- maybe_intern(grpc_slice_from_static_string(key), intern_key),
- maybe_intern(grpc_slice_from_static_string(value), intern_value));
- size_t elem_size = grpc_chttp2_get_size_in_hpack_table(elem, false);
- size_t expected_size = 32 + strlen(key) + strlen(value);
- GPR_ASSERT(expected_size == elem_size);
- GRPC_MDELEM_UNREF(elem);
-}
-
-static void verify_binary_header_size(const char* key, const uint8_t* value,
- size_t value_len, bool intern_key,
- bool intern_value) {
- grpc_mdelem elem = grpc_mdelem_from_slices(
- maybe_intern(grpc_slice_from_static_string(key), intern_key),
- maybe_intern(grpc_slice_from_static_buffer(value, value_len),
- intern_value));
- GPR_ASSERT(grpc_is_binary_header(GRPC_MDKEY(elem)));
- size_t elem_size = grpc_chttp2_get_size_in_hpack_table(elem, false);
- grpc_slice value_slice = grpc_slice_from_copied_buffer(
- reinterpret_cast(value), value_len);
- grpc_slice base64_encoded = grpc_chttp2_base64_encode(value_slice);
- size_t expected_size = 32 + strlen(key) + GRPC_SLICE_LENGTH(base64_encoded);
- GPR_ASSERT(expected_size == elem_size);
- grpc_slice_unref_internal(value_slice);
- grpc_slice_unref_internal(base64_encoded);
- GRPC_MDELEM_UNREF(elem);
-}
-
-#define BUFFER_SIZE 64
-static void test_mdelem_sizes_in_hpack(bool intern_key, bool intern_value) {
- gpr_log(GPR_INFO, "test_mdelem_size: intern_key=%d intern_value=%d",
- intern_key, intern_value);
- grpc_init();
- grpc_core::ExecCtx exec_ctx;
-
- uint8_t binary_value[BUFFER_SIZE] = {0};
- for (uint8_t i = 0; i < BUFFER_SIZE; i++) {
- binary_value[i] = i;
- }
-
- verify_ascii_header_size("hello", "world", intern_key, intern_value);
- verify_ascii_header_size("hello", "worldxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
- intern_key, intern_value);
- verify_ascii_header_size(":scheme", "http", intern_key, intern_value);
-
- for (uint8_t i = 0; i < BUFFER_SIZE; i++) {
- verify_binary_header_size("hello-bin", binary_value, i, intern_key,
- intern_value);
- }
-
- grpc_shutdown();
-}
-
static void test_copied_static_metadata(bool dup_key, bool dup_value) {
gpr_log(GPR_INFO, "test_static_metadata: dup_key=%d dup_value=%d", dup_key,
dup_value);
@@ -465,7 +410,6 @@ int main(int argc, char** argv) {
test_create_many_ephemeral_metadata(k, v);
test_identity_laws(k, v);
test_spin_creating_the_same_thing(k, v);
- test_mdelem_sizes_in_hpack(k, v);
test_copied_static_metadata(k, v);
}
}
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index f991bb9b83c3c..d5643221bdc18 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -1221,13 +1221,18 @@ src/core/ext/transport/chttp2/transport/frame_settings.cc \
src/core/ext/transport/chttp2/transport/frame_settings.h \
src/core/ext/transport/chttp2/transport/frame_window_update.cc \
src/core/ext/transport/chttp2/transport/frame_window_update.h \
+src/core/ext/transport/chttp2/transport/hpack_constants.h \
src/core/ext/transport/chttp2/transport/hpack_encoder.cc \
src/core/ext/transport/chttp2/transport/hpack_encoder.h \
src/core/ext/transport/chttp2/transport/hpack_encoder_index.h \
+src/core/ext/transport/chttp2/transport/hpack_encoder_table.cc \
+src/core/ext/transport/chttp2/transport/hpack_encoder_table.h \
src/core/ext/transport/chttp2/transport/hpack_parser.cc \
src/core/ext/transport/chttp2/transport/hpack_parser.h \
-src/core/ext/transport/chttp2/transport/hpack_table.cc \
-src/core/ext/transport/chttp2/transport/hpack_table.h \
+src/core/ext/transport/chttp2/transport/hpack_parser_table.cc \
+src/core/ext/transport/chttp2/transport/hpack_parser_table.h \
+src/core/ext/transport/chttp2/transport/hpack_utils.cc \
+src/core/ext/transport/chttp2/transport/hpack_utils.h \
src/core/ext/transport/chttp2/transport/http2_settings.cc \
src/core/ext/transport/chttp2/transport/http2_settings.h \
src/core/ext/transport/chttp2/transport/huffsyms.cc \
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 2c0366d6940cb..df339b38ee3fb 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -1056,13 +1056,18 @@ src/core/ext/transport/chttp2/transport/frame_settings.cc \
src/core/ext/transport/chttp2/transport/frame_settings.h \
src/core/ext/transport/chttp2/transport/frame_window_update.cc \
src/core/ext/transport/chttp2/transport/frame_window_update.h \
+src/core/ext/transport/chttp2/transport/hpack_constants.h \
src/core/ext/transport/chttp2/transport/hpack_encoder.cc \
src/core/ext/transport/chttp2/transport/hpack_encoder.h \
src/core/ext/transport/chttp2/transport/hpack_encoder_index.h \
+src/core/ext/transport/chttp2/transport/hpack_encoder_table.cc \
+src/core/ext/transport/chttp2/transport/hpack_encoder_table.h \
src/core/ext/transport/chttp2/transport/hpack_parser.cc \
src/core/ext/transport/chttp2/transport/hpack_parser.h \
-src/core/ext/transport/chttp2/transport/hpack_table.cc \
-src/core/ext/transport/chttp2/transport/hpack_table.h \
+src/core/ext/transport/chttp2/transport/hpack_parser_table.cc \
+src/core/ext/transport/chttp2/transport/hpack_parser_table.h \
+src/core/ext/transport/chttp2/transport/hpack_utils.cc \
+src/core/ext/transport/chttp2/transport/hpack_utils.h \
src/core/ext/transport/chttp2/transport/http2_settings.cc \
src/core/ext/transport/chttp2/transport/http2_settings.h \
src/core/ext/transport/chttp2/transport/huffsyms.cc \
diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json
index e0cdeff7d7f69..5ddd0698df21f 100644
--- a/tools/run_tests/generated/tests.json
+++ b/tools/run_tests/generated/tests.json
@@ -1532,7 +1532,7 @@
"flaky": false,
"gtest": false,
"language": "c",
- "name": "hpack_parser_test",
+ "name": "hpack_parser_table_test",
"platforms": [
"linux",
"mac",
@@ -1556,7 +1556,7 @@
"flaky": false,
"gtest": false,
"language": "c",
- "name": "hpack_table_test",
+ "name": "hpack_parser_test",
"platforms": [
"linux",
"mac",