aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/lib/transport
diff options
context:
space:
mode:
authorGravatar Craig Tiller <ctiller@google.com>2016-04-26 13:00:44 -0700
committerGravatar Craig Tiller <ctiller@google.com>2016-04-26 13:00:44 -0700
commit89c5cb596df9f3bbbf1d024fb59df2b799c85fba (patch)
treebb9ae905ada472eb788c485b09dd8db214fb227d /src/core/lib/transport
parent6c8ae9aad5f1aaaf9c043817e184ec26bee75c86 (diff)
parentc3d869ef5853c4cfad57b7d3694d5260eeb7ce75 (diff)
Merge github.com:grpc/grpc into split-me-baby-one-more-time
Diffstat (limited to 'src/core/lib/transport')
-rw-r--r--src/core/lib/transport/metadata.c41
-rw-r--r--src/core/lib/transport/metadata.h7
2 files changed, 47 insertions, 1 deletions
diff --git a/src/core/lib/transport/metadata.c b/src/core/lib/transport/metadata.c
index d037c61d72..779efbb97d 100644
--- a/src/core/lib/transport/metadata.c
+++ b/src/core/lib/transport/metadata.c
@@ -38,19 +38,21 @@
#include <string.h>
#include <grpc/compression.h>
+#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/atm.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/time.h>
-#include "src/core/ext/transport/chttp2/transport/bin_encoder.h"
#include "src/core/lib/iomgr/iomgr_internal.h"
#include "src/core/lib/profiling/timers.h"
#include "src/core/lib/support/murmur_hash.h"
#include "src/core/lib/support/string.h"
#include "src/core/lib/transport/static_metadata.h"
+gpr_slice (*grpc_chttp2_base64_encode_and_huffman_compress)(gpr_slice input);
+
/* There are two kinds of mdelem and mdstr instances.
* Static instances are declared in static_metadata.{h,c} and
* are initialized by grpc_mdctx_global_init().
@@ -79,6 +81,7 @@
typedef void (*destroy_user_data_func)(void *user_data);
+#define SIZE_IN_DECODER_TABLE_NOT_SET -1
/* Shadow structure for grpc_mdstr for non-static values */
typedef struct internal_string {
/* must be byte compatible with grpc_mdstr */
@@ -93,6 +96,8 @@ typedef struct internal_string {
gpr_slice base64_and_huffman;
+ gpr_atm size_in_decoder_table;
+
struct internal_string *bucket_next;
} internal_string;
@@ -413,6 +418,7 @@ grpc_mdstr *grpc_mdstr_from_buffer(const uint8_t *buf, size_t length) {
}
s->has_base64_and_huffman_encoded = 0;
s->hash = hash;
+ s->size_in_decoder_table = SIZE_IN_DECODER_TABLE_NOT_SET;
s->bucket_next = shard->strs[idx];
shard->strs[idx] = s;
@@ -582,6 +588,39 @@ grpc_mdelem *grpc_mdelem_from_string_and_buffer(const char *key,
grpc_mdstr_from_string(key), grpc_mdstr_from_buffer(value, value_length));
}
+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_mdelem_get_size_in_hpack_table(grpc_mdelem *elem) {
+ size_t overhead_and_key = 32 + GPR_SLICE_LENGTH(elem->key->slice);
+ size_t value_len = GPR_SLICE_LENGTH(elem->value->slice);
+ if (is_mdstr_static(elem->value)) {
+ if (grpc_is_binary_header(
+ (const char *)GPR_SLICE_START_PTR(elem->key->slice),
+ GPR_SLICE_LENGTH(elem->key->slice))) {
+ return overhead_and_key + get_base64_encoded_size(value_len);
+ } else {
+ return overhead_and_key + value_len;
+ }
+ } else {
+ internal_string *is = (internal_string *)elem->value;
+ gpr_atm current_size = gpr_atm_acq_load(&is->size_in_decoder_table);
+ if (current_size == SIZE_IN_DECODER_TABLE_NOT_SET) {
+ if (grpc_is_binary_header(
+ (const char *)GPR_SLICE_START_PTR(elem->key->slice),
+ GPR_SLICE_LENGTH(elem->key->slice))) {
+ current_size = (gpr_atm)get_base64_encoded_size(value_len);
+ } else {
+ current_size = (gpr_atm)value_len;
+ }
+ gpr_atm_rel_store(&is->size_in_decoder_table, current_size);
+ }
+ return overhead_and_key + (size_t)current_size;
+ }
+}
+
grpc_mdelem *grpc_mdelem_ref(grpc_mdelem *gmd DEBUG_ARGS) {
internal_metadata *md = (internal_metadata *)gmd;
if (is_mdelem_static(gmd)) return gmd;
diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h
index 6a02437fdf..713d9e6782 100644
--- a/src/core/lib/transport/metadata.h
+++ b/src/core/lib/transport/metadata.h
@@ -110,6 +110,8 @@ grpc_mdelem *grpc_mdelem_from_string_and_buffer(const char *key,
const uint8_t *value,
size_t value_length);
+size_t grpc_mdelem_get_size_in_hpack_table(grpc_mdelem *elem);
+
/* Mutator and accessor for grpc_mdelem user data. The destructor function
is used as a type tag and is checked during user_data fetch. */
void *grpc_mdelem_get_user_data(grpc_mdelem *md,
@@ -118,6 +120,7 @@ void grpc_mdelem_set_user_data(grpc_mdelem *md, void (*destroy_func)(void *),
void *user_data);
/* Reference counting */
+//#define GRPC_METADATA_REFCOUNT_DEBUG
#ifdef GRPC_METADATA_REFCOUNT_DEBUG
#define GRPC_MDSTR_REF(s) grpc_mdstr_ref((s), __FILE__, __LINE__)
#define GRPC_MDSTR_UNREF(s) grpc_mdstr_unref((s), __FILE__, __LINE__)
@@ -153,4 +156,8 @@ int grpc_mdstr_is_bin_suffixed(grpc_mdstr *s);
void grpc_mdctx_global_init(void);
void grpc_mdctx_global_shutdown(void);
+/* Implementation provided by chttp2_transport */
+extern gpr_slice (*grpc_chttp2_base64_encode_and_huffman_compress)(
+ gpr_slice input);
+
#endif /* GRPC_CORE_LIB_TRANSPORT_METADATA_H */