diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/compression/compression_algorithm.c | 46 | ||||
-rw-r--r-- | src/core/surface/call.c | 6 | ||||
-rw-r--r-- | src/core/surface/call.h | 9 | ||||
-rw-r--r-- | src/cpp/server/server_context.cc | 3 |
4 files changed, 57 insertions, 7 deletions
diff --git a/src/core/compression/compression_algorithm.c b/src/core/compression/compression_algorithm.c index 6f3a8eb28e..a76abc372f 100644 --- a/src/core/compression/compression_algorithm.c +++ b/src/core/compression/compression_algorithm.c @@ -128,20 +128,56 @@ 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[num_supported]; + 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..7dd74d86b4 100644 --- a/src/core/surface/call.c +++ b/src/core/surface/call.c @@ -1481,3 +1481,9 @@ 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) { + return grpc_compression_algorithm_for_level(level, + call->encodings_accepted_by_peer); +} 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 diff --git a/src/cpp/server/server_context.cc b/src/cpp/server/server_context.cc index eb49b21037..5d12ce2ecf 100644 --- a/src/cpp/server/server_context.cc +++ b/src/cpp/server/server_context.cc @@ -43,6 +43,7 @@ #include <grpc/support/log.h> #include "src/core/channel/compress_filter.h" +#include "src/core/surface/call.h" #include "src/cpp/common/create_auth_context.h" namespace grpc { @@ -197,7 +198,7 @@ bool ServerContext::IsCancelled() const { void ServerContext::set_compression_level(grpc_compression_level level) { const grpc_compression_algorithm algorithm_for_level = - grpc_compression_algorithm_for_level(level); + grpc_call_compression_for_level(call_, level); set_compression_algorithm(algorithm_for_level); } |