diff options
author | Jan Tattermusch <jtattermusch@users.noreply.github.com> | 2016-03-18 16:46:21 -0700 |
---|---|---|
committer | Jan Tattermusch <jtattermusch@users.noreply.github.com> | 2016-03-18 16:46:21 -0700 |
commit | 8bce393aeb1fd806d71701b67f19066d9272d5f1 (patch) | |
tree | 9825955e08a11c7b79fb352e8e86f7f79fa9b570 /src/core | |
parent | dc6d5a6244232555c2d3392d51c65d11b3f447e8 (diff) | |
parent | 7d2c7333398fd05e9901ccea088b0280b6901893 (diff) |
Merge pull request #5819 from dgquintas/compression_levels
Implemented compression level algorithms properly
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/compression/compression_algorithm.c | 47 | ||||
-rw-r--r-- | src/core/surface/call.c | 8 | ||||
-rw-r--r-- | src/core/surface/call.h | 9 |
3 files changed, 58 insertions, 6 deletions
diff --git a/src/core/compression/compression_algorithm.c b/src/core/compression/compression_algorithm.c index 6f3a8eb28e..2810a38b68 100644 --- a/src/core/compression/compression_algorithm.c +++ b/src/core/compression/compression_algorithm.c @@ -128,20 +128,57 @@ grpc_mdelem *grpc_compression_encoding_mdelem( /* TODO(dgq): Add the ability to specify parameters to the individual * compression algorithms */ grpc_compression_algorithm grpc_compression_algorithm_for_level( - grpc_compression_level level) { + grpc_compression_level level, uint32_t accepted_encodings) { GRPC_API_TRACE("grpc_compression_algorithm_for_level(level=%d)", 1, ((int)level)); + if (level > GRPC_COMPRESS_LEVEL_HIGH) { + gpr_log(GPR_ERROR, "Unknown compression level %d.", (int)level); + abort(); + } + + const size_t num_supported = + GPR_BITCOUNT(accepted_encodings) - 1; /* discard NONE */ + if (level == GRPC_COMPRESS_LEVEL_NONE || num_supported == 0) { + return GRPC_COMPRESS_NONE; + } + + GPR_ASSERT(level > 0); + + /* Establish a "ranking" or compression algorithms in increasing order of + * compression. + * This is simplistic and we will probably want to introduce other dimensions + * in the future (cpu/memory cost, etc). */ + const grpc_compression_algorithm algos_ranking[] = {GRPC_COMPRESS_GZIP, + GRPC_COMPRESS_DEFLATE}; + + /* intersect algos_ranking with the supported ones keeping the ranked order */ + grpc_compression_algorithm + sorted_supported_algos[GRPC_COMPRESS_ALGORITHMS_COUNT]; + size_t algos_supported_idx = 0; + for (size_t i = 0; i < GPR_ARRAY_SIZE(algos_ranking); i++) { + const grpc_compression_algorithm alg = algos_ranking[i]; + for (size_t j = 0; j < num_supported; j++) { + if (GPR_BITGET(accepted_encodings, alg) == 1) { + /* if \a alg in supported */ + sorted_supported_algos[algos_supported_idx++] = alg; + break; + } + } + if (algos_supported_idx == num_supported) break; + } + switch (level) { case GRPC_COMPRESS_LEVEL_NONE: - return GRPC_COMPRESS_NONE; + abort(); /* should have been handled already */ case GRPC_COMPRESS_LEVEL_LOW: + return sorted_supported_algos[0]; case GRPC_COMPRESS_LEVEL_MED: + return sorted_supported_algos[num_supported / 2]; case GRPC_COMPRESS_LEVEL_HIGH: - return GRPC_COMPRESS_DEFLATE; + return sorted_supported_algos[num_supported - 1]; default: - gpr_log(GPR_ERROR, "Unknown compression level %d.", (int)level); abort(); - } + }; } void grpc_compression_options_init(grpc_compression_options *opts) { diff --git a/src/core/surface/call.c b/src/core/surface/call.c index 1b117aa6b8..6f1cd1df10 100644 --- a/src/core/surface/call.c +++ b/src/core/surface/call.c @@ -1481,3 +1481,11 @@ void *grpc_call_context_get(grpc_call *call, grpc_context_index elem) { } uint8_t grpc_call_is_client(grpc_call *call) { return call->is_client; } + +grpc_compression_algorithm grpc_call_compression_for_level( + grpc_call *call, grpc_compression_level level) { + gpr_mu_lock(&call->mu); + const uint32_t accepted_encodings = call->encodings_accepted_by_peer; + gpr_mu_unlock(&call->mu); + return grpc_compression_algorithm_for_level(level, accepted_encodings); +} diff --git a/src/core/surface/call.h b/src/core/surface/call.h index 0bbffb98ae..0b3f543fe4 100644 --- a/src/core/surface/call.h +++ b/src/core/surface/call.h @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -38,7 +38,9 @@ #include "src/core/channel/context.h" #include "src/core/surface/api_trace.h" #include "src/core/surface/surface_trace.h" + #include <grpc/grpc.h> +#include <grpc/impl/codegen/compression_types.h> #ifdef __cplusplus extern "C" { @@ -102,6 +104,11 @@ void *grpc_call_context_get(grpc_call *call, grpc_context_index elem); uint8_t grpc_call_is_client(grpc_call *call); +/* Return an appropriate compression algorithm for the requested compression \a + * level in the context of \a call. */ +grpc_compression_algorithm grpc_call_compression_for_level( + grpc_call *call, grpc_compression_level level); + #ifdef __cplusplus } #endif |