grpc 1.1.2 → 1.2.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of grpc might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Makefile +1257 -404
- data/etc/roots.pem +189 -102
- data/include/grpc/census.h +7 -7
- data/include/grpc/compression.h +4 -4
- data/include/grpc/grpc.h +13 -7
- data/include/grpc/impl/codegen/atm_gcc_atomic.h +26 -9
- data/include/grpc/impl/codegen/grpc_types.h +39 -30
- data/include/grpc/impl/codegen/slice.h +24 -6
- data/include/grpc/impl/codegen/sync.h +8 -0
- data/include/grpc/load_reporting.h +63 -0
- data/include/grpc/slice.h +37 -1
- data/include/grpc/slice_buffer.h +7 -0
- data/include/grpc/support/alloc.h +3 -0
- data/include/grpc/support/useful.h +3 -0
- data/src/core/ext/census/gen/census.pb.h +1 -1
- data/src/core/ext/census/gen/trace_context.pb.c +9 -36
- data/src/core/ext/census/gen/trace_context.pb.h +20 -26
- data/src/core/ext/census/grpc_filter.c +3 -5
- data/src/core/ext/census/trace_context.c +1 -1
- data/src/core/ext/census/trace_context.h +3 -0
- data/src/core/ext/census/trace_label.h +61 -0
- data/src/core/ext/census/trace_propagation.h +63 -0
- data/src/core/ext/census/trace_status.h +45 -0
- data/src/core/ext/census/trace_string.h +50 -0
- data/src/core/ext/census/tracing.c +31 -11
- data/src/core/ext/census/tracing.h +124 -0
- data/src/core/ext/client_channel/client_channel.c +456 -368
- data/src/core/ext/client_channel/client_channel.h +4 -0
- data/src/core/ext/client_channel/client_channel_plugin.c +6 -1
- data/src/core/ext/client_channel/connector.c +3 -3
- data/src/core/ext/client_channel/connector.h +4 -3
- data/src/core/ext/client_channel/http_connect_handshaker.c +62 -72
- data/src/core/ext/client_channel/http_connect_handshaker.h +7 -10
- data/src/core/ext/client_channel/http_proxy.c +125 -0
- data/src/core/ext/client_channel/http_proxy.h +39 -0
- data/src/core/ext/client_channel/lb_policy.c +56 -35
- data/src/core/ext/client_channel/lb_policy.h +46 -39
- data/src/core/ext/client_channel/lb_policy_factory.h +1 -0
- data/src/core/ext/client_channel/parse_address.c +32 -6
- data/src/core/ext/client_channel/proxy_mapper.c +63 -0
- data/src/core/ext/client_channel/proxy_mapper.h +89 -0
- data/src/core/ext/client_channel/proxy_mapper_registry.c +133 -0
- data/src/core/ext/client_channel/proxy_mapper_registry.h +59 -0
- data/src/core/ext/client_channel/resolver.c +16 -9
- data/src/core/ext/client_channel/resolver.h +23 -12
- data/src/core/ext/client_channel/resolver_factory.h +1 -0
- data/src/core/ext/client_channel/resolver_registry.c +15 -11
- data/src/core/ext/client_channel/resolver_registry.h +5 -3
- data/src/core/ext/client_channel/subchannel.c +44 -27
- data/src/core/ext/client_channel/subchannel.h +6 -2
- data/src/core/ext/client_channel/uri_parser.c +26 -14
- data/src/core/ext/client_channel/uri_parser.h +3 -1
- data/src/core/ext/lb_policy/grpclb/grpclb.c +220 -209
- data/src/core/ext/lb_policy/grpclb/grpclb_channel.h +56 -0
- data/src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c +107 -0
- data/src/core/ext/lb_policy/grpclb/load_balancer_api.c +3 -6
- data/src/core/ext/lb_policy/pick_first/pick_first.c +71 -116
- data/src/core/ext/lb_policy/round_robin/round_robin.c +52 -67
- data/src/core/ext/load_reporting/load_reporting.c +20 -0
- data/src/core/ext/load_reporting/load_reporting.h +1 -16
- data/src/core/ext/load_reporting/load_reporting_filter.c +28 -54
- data/src/core/ext/resolver/dns/native/dns_resolver.c +31 -45
- data/src/core/ext/resolver/sockaddr/sockaddr_resolver.c +20 -29
- data/src/core/ext/transport/chttp2/client/chttp2_connector.c +11 -8
- data/src/core/ext/transport/chttp2/client/insecure/channel_create.c +11 -2
- data/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c +143 -46
- data/src/core/ext/transport/chttp2/server/chttp2_server.c +12 -50
- data/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c +1 -1
- data/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c +1 -1
- data/src/core/ext/transport/chttp2/transport/bin_decoder.c +7 -7
- data/src/core/ext/transport/chttp2/transport/bin_encoder.c +1 -2
- data/src/core/ext/transport/chttp2/transport/bin_encoder.h +1 -2
- data/src/core/ext/transport/chttp2/transport/chttp2_plugin.c +0 -3
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.c +606 -374
- data/src/core/ext/transport/chttp2/transport/frame_ping.c +17 -5
- data/src/core/ext/transport/chttp2/transport/frame_ping.h +2 -2
- data/src/core/ext/transport/chttp2/transport/frame_rst_stream.c +9 -13
- data/src/core/ext/transport/chttp2/transport/frame_settings.c +12 -11
- data/src/core/ext/transport/chttp2/transport/frame_settings.h +1 -1
- data/src/core/ext/transport/chttp2/transport/frame_window_update.c +5 -6
- data/src/core/ext/transport/chttp2/transport/hpack_encoder.c +100 -53
- data/src/core/ext/transport/chttp2/transport/hpack_encoder.h +2 -2
- data/src/core/ext/transport/chttp2/transport/hpack_parser.c +126 -70
- data/src/core/ext/transport/chttp2/transport/hpack_parser.h +13 -7
- data/src/core/ext/transport/chttp2/transport/hpack_table.c +22 -19
- data/src/core/ext/transport/chttp2/transport/hpack_table.h +6 -6
- data/src/core/ext/transport/chttp2/transport/incoming_metadata.c +23 -11
- data/src/core/ext/transport/chttp2/transport/incoming_metadata.h +6 -2
- data/src/core/ext/transport/chttp2/transport/internal.h +169 -42
- data/src/core/ext/transport/chttp2/transport/parsing.c +98 -41
- data/src/core/ext/transport/chttp2/transport/stream_lists.c +29 -14
- data/src/core/ext/transport/chttp2/transport/writing.c +137 -15
- data/src/core/lib/channel/channel_stack.c +14 -44
- data/src/core/lib/channel/channel_stack.h +10 -17
- data/src/core/lib/channel/channel_stack_builder.c +2 -3
- data/src/core/lib/channel/compress_filter.c +54 -46
- data/src/core/lib/channel/connected_channel.c +4 -4
- data/src/core/lib/channel/connected_channel.h +5 -0
- data/src/core/lib/channel/context.h +3 -0
- data/src/core/lib/channel/deadline_filter.c +61 -61
- data/src/core/lib/channel/deadline_filter.h +8 -5
- data/src/core/lib/channel/handshaker.c +47 -7
- data/src/core/lib/channel/handshaker.h +21 -3
- data/src/core/lib/channel/http_client_filter.c +149 -99
- data/src/core/lib/channel/http_server_filter.c +163 -147
- data/src/core/lib/channel/message_size_filter.c +15 -10
- data/src/core/lib/compression/algorithm_metadata.h +4 -4
- data/src/core/lib/compression/compression.c +17 -23
- data/src/core/lib/http/httpcli.c +3 -2
- data/src/core/lib/http/httpcli.h +2 -1
- data/src/core/lib/http/httpcli_security_connector.c +2 -3
- data/src/core/lib/http/parser.c +2 -2
- data/src/core/lib/iomgr/closure.c +6 -3
- data/src/core/lib/iomgr/closure.h +4 -2
- data/src/core/lib/iomgr/combiner.c +35 -5
- data/src/core/lib/iomgr/combiner.h +21 -2
- data/src/core/lib/iomgr/endpoint.c +3 -2
- data/src/core/lib/iomgr/endpoint.h +3 -2
- data/src/core/lib/iomgr/error.c +60 -94
- data/src/core/lib/iomgr/error.h +7 -10
- data/src/core/lib/iomgr/error_internal.h +54 -0
- data/src/core/lib/iomgr/ev_epoll_linux.c +253 -109
- data/src/core/lib/iomgr/ev_poll_posix.c +61 -29
- data/src/core/lib/iomgr/ev_posix.c +7 -8
- data/src/core/lib/iomgr/ev_posix.h +4 -4
- data/src/core/lib/iomgr/exec_ctx.c +11 -6
- data/src/core/lib/iomgr/exec_ctx.h +11 -14
- data/src/core/lib/iomgr/executor.c +2 -2
- data/src/core/lib/iomgr/load_file.c +1 -1
- data/src/core/lib/iomgr/network_status_tracker.c +5 -81
- data/src/core/lib/iomgr/pollset.h +1 -3
- data/src/core/lib/iomgr/pollset_set.h +2 -1
- data/src/core/lib/iomgr/pollset_set_uv.c +2 -1
- data/src/core/lib/iomgr/pollset_set_windows.c +2 -1
- data/src/core/lib/iomgr/pollset_uv.c +25 -11
- data/src/core/lib/iomgr/pollset_windows.c +0 -11
- data/src/core/lib/iomgr/resolve_address_uv.c +50 -2
- data/src/core/lib/iomgr/resource_quota.c +41 -11
- data/src/core/lib/iomgr/resource_quota.h +6 -0
- data/src/core/lib/iomgr/sockaddr_utils.c +33 -17
- data/src/core/lib/iomgr/sockaddr_utils.h +4 -0
- data/src/core/lib/iomgr/tcp_client_posix.c +2 -3
- data/src/core/lib/iomgr/tcp_client_uv.c +1 -3
- data/src/core/lib/iomgr/tcp_client_windows.c +21 -6
- data/src/core/lib/iomgr/tcp_posix.c +4 -5
- data/src/core/lib/iomgr/tcp_server_posix.c +269 -94
- data/src/core/lib/iomgr/tcp_server_windows.c +1 -1
- data/src/core/lib/iomgr/tcp_uv.c +11 -5
- data/src/core/lib/iomgr/tcp_windows.c +20 -7
- data/src/core/lib/iomgr/timer_generic.c +15 -22
- data/src/core/lib/iomgr/timer_generic.h +1 -1
- data/src/core/lib/iomgr/timer_uv.c +10 -6
- data/src/core/lib/iomgr/timer_uv.h +1 -1
- data/src/core/lib/iomgr/udp_server.c +45 -6
- data/src/core/lib/iomgr/udp_server.h +7 -1
- data/src/core/lib/iomgr/unix_sockets_posix.c +11 -1
- data/src/core/lib/json/json.c +1 -2
- data/src/core/lib/profiling/basic_timers.c +17 -3
- data/src/core/lib/security/context/security_context.c +3 -10
- data/src/core/lib/security/credentials/composite/composite_credentials.c +4 -8
- data/src/core/lib/security/credentials/credentials.c +48 -2
- data/src/core/lib/security/credentials/credentials.h +13 -0
- data/src/core/lib/security/credentials/credentials_metadata.c +1 -2
- data/src/core/lib/security/credentials/fake/fake_credentials.c +6 -8
- data/src/core/lib/security/credentials/fake/fake_credentials.h +15 -0
- data/src/core/lib/security/credentials/google_default/google_default_credentials.c +3 -3
- data/src/core/lib/security/credentials/iam/iam_credentials.c +1 -2
- data/src/core/lib/security/credentials/jwt/jwt_credentials.c +1 -2
- data/src/core/lib/security/credentials/jwt/jwt_verifier.c +5 -8
- data/src/core/lib/security/credentials/jwt/jwt_verifier.h +2 -1
- data/src/core/lib/security/credentials/oauth2/oauth2_credentials.c +3 -5
- data/src/core/lib/security/credentials/plugin/plugin_credentials.c +15 -13
- data/src/core/lib/security/credentials/ssl/ssl_credentials.c +2 -4
- data/src/core/lib/security/transport/client_auth_filter.c +72 -47
- data/src/core/lib/security/transport/lb_targets_info.c +70 -0
- data/src/core/lib/security/transport/lb_targets_info.h +47 -0
- data/src/core/lib/security/transport/secure_endpoint.c +3 -3
- data/src/core/lib/security/transport/security_connector.c +125 -28
- data/src/core/lib/security/transport/security_connector.h +4 -3
- data/src/core/lib/security/transport/security_handshaker.c +13 -9
- data/src/core/lib/security/transport/server_auth_filter.c +31 -40
- data/src/core/lib/security/util/b64.c +1 -1
- data/src/core/lib/slice/slice.c +110 -20
- data/src/core/lib/slice/slice_buffer.c +92 -39
- data/src/core/lib/{transport/mdstr_hash_table.c → slice/slice_hash_table.c} +40 -33
- data/src/core/lib/{transport/mdstr_hash_table.h → slice/slice_hash_table.h} +21 -21
- data/src/core/lib/slice/slice_intern.c +346 -0
- data/src/core/lib/slice/slice_internal.h +15 -0
- data/src/core/lib/slice/slice_string_helpers.c +5 -0
- data/src/core/lib/slice/slice_string_helpers.h +5 -0
- data/src/core/lib/support/alloc.c +26 -1
- data/src/core/lib/support/cmdline.c +2 -4
- data/src/core/lib/support/cpu_posix.c +2 -7
- data/src/core/lib/support/histogram.c +1 -2
- data/src/core/lib/support/log_posix.c +8 -4
- data/src/core/lib/support/spinlock.h +52 -0
- data/src/core/lib/support/subprocess_posix.c +1 -2
- data/src/core/lib/support/sync.c +7 -1
- data/src/core/lib/support/sync_posix.c +9 -0
- data/src/core/lib/support/time_windows.c +7 -1
- data/src/core/lib/surface/call.c +647 -629
- data/src/core/lib/surface/call.h +4 -1
- data/src/core/lib/surface/call_details.c +8 -2
- data/src/core/lib/surface/call_log_batch.c +17 -6
- data/src/core/lib/surface/channel.c +49 -59
- data/src/core/lib/surface/channel.h +5 -6
- data/src/core/lib/surface/completion_queue.c +16 -45
- data/src/core/lib/surface/completion_queue.h +0 -3
- data/src/core/lib/surface/init.c +6 -2
- data/src/core/lib/surface/init_secure.c +1 -1
- data/src/core/lib/surface/lame_client.c +14 -4
- data/src/core/lib/surface/server.c +79 -82
- data/src/core/lib/surface/validate_metadata.c +46 -15
- data/src/core/lib/surface/validate_metadata.h +43 -0
- data/src/core/lib/surface/version.c +2 -2
- data/src/core/lib/transport/bdp_estimator.c +104 -0
- data/src/core/lib/transport/bdp_estimator.h +76 -0
- data/src/core/lib/transport/connectivity_state.c +33 -13
- data/src/core/lib/transport/connectivity_state.h +15 -5
- data/src/core/lib/transport/error_utils.c +124 -0
- data/src/core/lib/transport/error_utils.h +56 -0
- data/src/core/{ext/transport/chttp2 → lib}/transport/http2_errors.h +18 -18
- data/src/core/lib/transport/metadata.c +259 -503
- data/src/core/lib/transport/metadata.h +69 -68
- data/src/core/lib/transport/metadata_batch.c +183 -63
- data/src/core/lib/transport/metadata_batch.h +50 -26
- data/src/core/lib/transport/pid_controller.c +28 -8
- data/src/core/lib/transport/pid_controller.h +15 -2
- data/src/core/lib/transport/service_config.c +21 -18
- data/src/core/lib/transport/service_config.h +5 -5
- data/src/core/lib/transport/static_metadata.c +753 -112
- data/src/core/lib/transport/static_metadata.h +403 -264
- data/src/core/{ext/transport/chttp2 → lib}/transport/status_conversion.c +18 -20
- data/src/core/{ext/transport/chttp2 → lib}/transport/status_conversion.h +9 -10
- data/src/core/lib/transport/timeout_encoding.c +11 -9
- data/src/core/lib/transport/timeout_encoding.h +3 -1
- data/src/core/lib/transport/transport.c +47 -87
- data/src/core/lib/transport/transport.h +20 -25
- data/src/core/lib/transport/transport_op_string.c +7 -19
- data/src/core/lib/tsi/fake_transport_security.c +2 -4
- data/src/core/lib/tsi/ssl_transport_security.c +7 -16
- data/src/core/lib/tsi/transport_security.c +2 -4
- data/src/ruby/ext/grpc/extconf.rb +4 -1
- data/src/ruby/ext/grpc/rb_byte_buffer.c +7 -0
- data/src/ruby/ext/grpc/rb_byte_buffer.h +3 -0
- data/src/ruby/ext/grpc/rb_call.c +47 -46
- data/src/ruby/ext/grpc/rb_channel.c +21 -6
- data/src/ruby/ext/grpc/rb_compression_options.c +9 -6
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +36 -2
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +59 -8
- data/src/ruby/ext/grpc/rb_server.c +6 -4
- data/src/ruby/lib/grpc/generic/client_stub.rb +1 -1
- data/src/ruby/lib/grpc/version.rb +1 -1
- metadata +33 -9
@@ -29,7 +29,7 @@
|
|
29
29
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
30
30
|
//
|
31
31
|
|
32
|
-
#include "src/core/lib/
|
32
|
+
#include "src/core/lib/slice/slice_hash_table.h"
|
33
33
|
|
34
34
|
#include <stdbool.h>
|
35
35
|
#include <string.h>
|
@@ -37,70 +37,77 @@
|
|
37
37
|
#include <grpc/support/alloc.h>
|
38
38
|
#include <grpc/support/log.h>
|
39
39
|
|
40
|
+
#include "src/core/lib/slice/slice_internal.h"
|
40
41
|
#include "src/core/lib/transport/metadata.h"
|
41
42
|
|
42
|
-
struct
|
43
|
+
struct grpc_slice_hash_table {
|
43
44
|
gpr_refcount refs;
|
44
45
|
size_t size;
|
45
|
-
|
46
|
+
grpc_slice_hash_table_entry* entries;
|
46
47
|
};
|
47
48
|
|
49
|
+
static bool is_empty(grpc_slice_hash_table_entry* entry) {
|
50
|
+
return entry->vtable == NULL;
|
51
|
+
}
|
52
|
+
|
48
53
|
// Helper function for insert and get operations that performs quadratic
|
49
54
|
// probing (https://en.wikipedia.org/wiki/Quadratic_probing).
|
50
|
-
static size_t
|
51
|
-
const
|
52
|
-
|
55
|
+
static size_t grpc_slice_hash_table_find_index(
|
56
|
+
const grpc_slice_hash_table* table, const grpc_slice key, bool find_empty) {
|
57
|
+
size_t hash = grpc_slice_hash(key);
|
53
58
|
for (size_t i = 0; i < table->size; ++i) {
|
54
|
-
const size_t idx = (
|
55
|
-
if (table->entries[idx]
|
56
|
-
|
59
|
+
const size_t idx = (hash + i * i) % table->size;
|
60
|
+
if (is_empty(&table->entries[idx])) {
|
61
|
+
return find_empty ? idx : table->size;
|
62
|
+
}
|
63
|
+
if (grpc_slice_eq(table->entries[idx].key, key)) {
|
64
|
+
return idx;
|
65
|
+
}
|
57
66
|
}
|
58
67
|
return table->size; // Not found.
|
59
68
|
}
|
60
69
|
|
61
|
-
static void
|
62
|
-
|
63
|
-
const
|
70
|
+
static void grpc_slice_hash_table_add(
|
71
|
+
grpc_slice_hash_table* table, grpc_slice key, void* value,
|
72
|
+
const grpc_slice_hash_table_vtable* vtable) {
|
64
73
|
GPR_ASSERT(value != NULL);
|
65
74
|
const size_t idx =
|
66
|
-
|
75
|
+
grpc_slice_hash_table_find_index(table, key, true /* find_empty */);
|
67
76
|
GPR_ASSERT(idx != table->size); // Table should never be full.
|
68
|
-
|
69
|
-
entry->key =
|
77
|
+
grpc_slice_hash_table_entry* entry = &table->entries[idx];
|
78
|
+
entry->key = grpc_slice_ref_internal(key);
|
70
79
|
entry->value = vtable->copy_value(value);
|
71
80
|
entry->vtable = vtable;
|
72
81
|
}
|
73
82
|
|
74
|
-
|
75
|
-
size_t num_entries,
|
76
|
-
|
77
|
-
memset(table, 0, sizeof(*table));
|
83
|
+
grpc_slice_hash_table* grpc_slice_hash_table_create(
|
84
|
+
size_t num_entries, grpc_slice_hash_table_entry* entries) {
|
85
|
+
grpc_slice_hash_table* table = gpr_zalloc(sizeof(*table));
|
78
86
|
gpr_ref_init(&table->refs, 1);
|
79
87
|
// Quadratic probing gets best performance when the table is no more
|
80
88
|
// than half full.
|
81
89
|
table->size = num_entries * 2;
|
82
|
-
const size_t entry_size = sizeof(
|
83
|
-
table->entries =
|
84
|
-
memset(table->entries, 0, entry_size);
|
90
|
+
const size_t entry_size = sizeof(grpc_slice_hash_table_entry) * table->size;
|
91
|
+
table->entries = gpr_zalloc(entry_size);
|
85
92
|
for (size_t i = 0; i < num_entries; ++i) {
|
86
|
-
|
87
|
-
|
93
|
+
grpc_slice_hash_table_entry* entry = &entries[i];
|
94
|
+
grpc_slice_hash_table_add(table, entry->key, entry->value, entry->vtable);
|
88
95
|
}
|
89
96
|
return table;
|
90
97
|
}
|
91
98
|
|
92
|
-
|
99
|
+
grpc_slice_hash_table* grpc_slice_hash_table_ref(grpc_slice_hash_table* table) {
|
93
100
|
if (table != NULL) gpr_ref(&table->refs);
|
94
101
|
return table;
|
95
102
|
}
|
96
103
|
|
97
|
-
void
|
98
|
-
|
104
|
+
void grpc_slice_hash_table_unref(grpc_exec_ctx* exec_ctx,
|
105
|
+
grpc_slice_hash_table* table) {
|
99
106
|
if (table != NULL && gpr_unref(&table->refs)) {
|
100
107
|
for (size_t i = 0; i < table->size; ++i) {
|
101
|
-
|
102
|
-
if (entry
|
103
|
-
|
108
|
+
grpc_slice_hash_table_entry* entry = &table->entries[i];
|
109
|
+
if (!is_empty(entry)) {
|
110
|
+
grpc_slice_unref_internal(exec_ctx, entry->key);
|
104
111
|
entry->vtable->destroy_value(exec_ctx, entry->value);
|
105
112
|
}
|
106
113
|
}
|
@@ -109,10 +116,10 @@ void grpc_mdstr_hash_table_unref(grpc_exec_ctx* exec_ctx,
|
|
109
116
|
}
|
110
117
|
}
|
111
118
|
|
112
|
-
void*
|
113
|
-
const
|
119
|
+
void* grpc_slice_hash_table_get(const grpc_slice_hash_table* table,
|
120
|
+
const grpc_slice key) {
|
114
121
|
const size_t idx =
|
115
|
-
|
122
|
+
grpc_slice_hash_table_find_index(table, key, false /* find_empty */);
|
116
123
|
if (idx == table->size) return NULL; // Not found.
|
117
124
|
return table->entries[idx].value;
|
118
125
|
}
|
@@ -29,8 +29,8 @@
|
|
29
29
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
30
30
|
*/
|
31
31
|
|
32
|
-
#ifndef
|
33
|
-
#define
|
32
|
+
#ifndef GRPC_CORE_LIB_SLICE_SLICE_HASH_TABLE_H
|
33
|
+
#define GRPC_CORE_LIB_SLICE_SLICE_HASH_TABLE_H
|
34
34
|
|
35
35
|
#include "src/core/lib/transport/metadata.h"
|
36
36
|
|
@@ -40,38 +40,38 @@
|
|
40
40
|
* (https://en.wikipedia.org/wiki/Open_addressing) with quadratic
|
41
41
|
* probing (https://en.wikipedia.org/wiki/Quadratic_probing).
|
42
42
|
*
|
43
|
-
* The keys are \a
|
43
|
+
* The keys are \a grpc_slice objects. The values are arbitrary pointers
|
44
44
|
* with a common vtable.
|
45
45
|
*
|
46
46
|
* Hash tables are intentionally immutable, to avoid the need for locking.
|
47
47
|
*/
|
48
48
|
|
49
|
-
typedef struct
|
49
|
+
typedef struct grpc_slice_hash_table grpc_slice_hash_table;
|
50
50
|
|
51
|
-
typedef struct
|
52
|
-
void (*destroy_value)(grpc_exec_ctx*
|
53
|
-
void*
|
54
|
-
}
|
51
|
+
typedef struct grpc_slice_hash_table_vtable {
|
52
|
+
void (*destroy_value)(grpc_exec_ctx *exec_ctx, void *value);
|
53
|
+
void *(*copy_value)(void *value);
|
54
|
+
} grpc_slice_hash_table_vtable;
|
55
55
|
|
56
|
-
typedef struct
|
57
|
-
|
58
|
-
void*
|
59
|
-
const
|
60
|
-
}
|
56
|
+
typedef struct grpc_slice_hash_table_entry {
|
57
|
+
grpc_slice key;
|
58
|
+
void *value; /* Must not be NULL. */
|
59
|
+
const grpc_slice_hash_table_vtable *vtable;
|
60
|
+
} grpc_slice_hash_table_entry;
|
61
61
|
|
62
62
|
/** Creates a new hash table of containing \a entries, which is an array
|
63
63
|
of length \a num_entries.
|
64
64
|
Creates its own copy of all keys and values from \a entries. */
|
65
|
-
|
66
|
-
size_t num_entries,
|
65
|
+
grpc_slice_hash_table *grpc_slice_hash_table_create(
|
66
|
+
size_t num_entries, grpc_slice_hash_table_entry *entries);
|
67
67
|
|
68
|
-
|
69
|
-
void
|
70
|
-
|
68
|
+
grpc_slice_hash_table *grpc_slice_hash_table_ref(grpc_slice_hash_table *table);
|
69
|
+
void grpc_slice_hash_table_unref(grpc_exec_ctx *exec_ctx,
|
70
|
+
grpc_slice_hash_table *table);
|
71
71
|
|
72
72
|
/** Returns the value from \a table associated with \a key.
|
73
73
|
Returns NULL if \a key is not found. */
|
74
|
-
void*
|
75
|
-
const
|
74
|
+
void *grpc_slice_hash_table_get(const grpc_slice_hash_table *table,
|
75
|
+
const grpc_slice key);
|
76
76
|
|
77
|
-
#endif /*
|
77
|
+
#endif /* GRPC_CORE_LIB_SLICE_SLICE_HASH_TABLE_H */
|
@@ -0,0 +1,346 @@
|
|
1
|
+
/*
|
2
|
+
*
|
3
|
+
* Copyright 2016, Google Inc.
|
4
|
+
* All rights reserved.
|
5
|
+
*
|
6
|
+
* Redistribution and use in source and binary forms, with or without
|
7
|
+
* modification, are permitted provided that the following conditions are
|
8
|
+
* met:
|
9
|
+
*
|
10
|
+
* * Redistributions of source code must retain the above copyright
|
11
|
+
* notice, this list of conditions and the following disclaimer.
|
12
|
+
* * Redistributions in binary form must reproduce the above
|
13
|
+
* copyright notice, this list of conditions and the following disclaimer
|
14
|
+
* in the documentation and/or other materials provided with the
|
15
|
+
* distribution.
|
16
|
+
* * Neither the name of Google Inc. nor the names of its
|
17
|
+
* contributors may be used to endorse or promote products derived from
|
18
|
+
* this software without specific prior written permission.
|
19
|
+
*
|
20
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
21
|
+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
22
|
+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
23
|
+
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
24
|
+
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
25
|
+
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
26
|
+
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
27
|
+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
28
|
+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
29
|
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
30
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
31
|
+
*
|
32
|
+
*/
|
33
|
+
|
34
|
+
#include "src/core/lib/slice/slice_internal.h"
|
35
|
+
|
36
|
+
#include <string.h>
|
37
|
+
|
38
|
+
#include <grpc/support/alloc.h>
|
39
|
+
#include <grpc/support/log.h>
|
40
|
+
|
41
|
+
#include "src/core/lib/iomgr/iomgr_internal.h" /* for iomgr_abort_on_leaks() */
|
42
|
+
#include "src/core/lib/profiling/timers.h"
|
43
|
+
#include "src/core/lib/slice/slice_string_helpers.h"
|
44
|
+
#include "src/core/lib/support/murmur_hash.h"
|
45
|
+
#include "src/core/lib/transport/static_metadata.h"
|
46
|
+
|
47
|
+
#define LOG2_SHARD_COUNT 5
|
48
|
+
#define SHARD_COUNT (1 << LOG2_SHARD_COUNT)
|
49
|
+
#define INITIAL_SHARD_CAPACITY 8
|
50
|
+
|
51
|
+
#define TABLE_IDX(hash, capacity) (((hash) >> LOG2_SHARD_COUNT) % (capacity))
|
52
|
+
#define SHARD_IDX(hash) ((hash) & ((1 << LOG2_SHARD_COUNT) - 1))
|
53
|
+
|
54
|
+
typedef struct interned_slice_refcount {
|
55
|
+
grpc_slice_refcount base;
|
56
|
+
grpc_slice_refcount sub;
|
57
|
+
size_t length;
|
58
|
+
gpr_atm refcnt;
|
59
|
+
uint32_t hash;
|
60
|
+
struct interned_slice_refcount *bucket_next;
|
61
|
+
} interned_slice_refcount;
|
62
|
+
|
63
|
+
typedef struct slice_shard {
|
64
|
+
gpr_mu mu;
|
65
|
+
interned_slice_refcount **strs;
|
66
|
+
size_t count;
|
67
|
+
size_t capacity;
|
68
|
+
} slice_shard;
|
69
|
+
|
70
|
+
/* hash seed: decided at initialization time */
|
71
|
+
static uint32_t g_hash_seed;
|
72
|
+
static int g_forced_hash_seed = 0;
|
73
|
+
|
74
|
+
static slice_shard g_shards[SHARD_COUNT];
|
75
|
+
|
76
|
+
typedef struct {
|
77
|
+
uint32_t hash;
|
78
|
+
uint32_t idx;
|
79
|
+
} static_metadata_hash_ent;
|
80
|
+
|
81
|
+
static static_metadata_hash_ent
|
82
|
+
static_metadata_hash[4 * GRPC_STATIC_MDSTR_COUNT];
|
83
|
+
static uint32_t max_static_metadata_hash_probe;
|
84
|
+
static uint32_t static_metadata_hash_values[GRPC_STATIC_MDSTR_COUNT];
|
85
|
+
|
86
|
+
static void interned_slice_ref(void *p) {
|
87
|
+
interned_slice_refcount *s = p;
|
88
|
+
GPR_ASSERT(gpr_atm_no_barrier_fetch_add(&s->refcnt, 1) > 0);
|
89
|
+
}
|
90
|
+
|
91
|
+
static void interned_slice_destroy(interned_slice_refcount *s) {
|
92
|
+
slice_shard *shard = &g_shards[SHARD_IDX(s->hash)];
|
93
|
+
gpr_mu_lock(&shard->mu);
|
94
|
+
GPR_ASSERT(0 == gpr_atm_no_barrier_load(&s->refcnt));
|
95
|
+
interned_slice_refcount **prev_next;
|
96
|
+
interned_slice_refcount *cur;
|
97
|
+
for (prev_next = &shard->strs[TABLE_IDX(s->hash, shard->capacity)],
|
98
|
+
cur = *prev_next;
|
99
|
+
cur != s; prev_next = &cur->bucket_next, cur = cur->bucket_next)
|
100
|
+
;
|
101
|
+
*prev_next = cur->bucket_next;
|
102
|
+
shard->count--;
|
103
|
+
gpr_free(s);
|
104
|
+
gpr_mu_unlock(&shard->mu);
|
105
|
+
}
|
106
|
+
|
107
|
+
static void interned_slice_unref(grpc_exec_ctx *exec_ctx, void *p) {
|
108
|
+
interned_slice_refcount *s = p;
|
109
|
+
if (1 == gpr_atm_full_fetch_add(&s->refcnt, -1)) {
|
110
|
+
interned_slice_destroy(s);
|
111
|
+
}
|
112
|
+
}
|
113
|
+
|
114
|
+
static void interned_slice_sub_ref(void *p) {
|
115
|
+
interned_slice_ref(((char *)p) - offsetof(interned_slice_refcount, sub));
|
116
|
+
}
|
117
|
+
|
118
|
+
static void interned_slice_sub_unref(grpc_exec_ctx *exec_ctx, void *p) {
|
119
|
+
interned_slice_unref(exec_ctx,
|
120
|
+
((char *)p) - offsetof(interned_slice_refcount, sub));
|
121
|
+
}
|
122
|
+
|
123
|
+
static uint32_t interned_slice_hash(grpc_slice slice) {
|
124
|
+
interned_slice_refcount *s = (interned_slice_refcount *)slice.refcount;
|
125
|
+
return s->hash;
|
126
|
+
}
|
127
|
+
|
128
|
+
static int interned_slice_eq(grpc_slice a, grpc_slice b) {
|
129
|
+
return a.refcount == b.refcount;
|
130
|
+
}
|
131
|
+
|
132
|
+
static const grpc_slice_refcount_vtable interned_slice_vtable = {
|
133
|
+
interned_slice_ref, interned_slice_unref, interned_slice_eq,
|
134
|
+
interned_slice_hash};
|
135
|
+
static const grpc_slice_refcount_vtable interned_slice_sub_vtable = {
|
136
|
+
interned_slice_sub_ref, interned_slice_sub_unref,
|
137
|
+
grpc_slice_default_eq_impl, grpc_slice_default_hash_impl};
|
138
|
+
|
139
|
+
static void grow_shard(slice_shard *shard) {
|
140
|
+
size_t capacity = shard->capacity * 2;
|
141
|
+
size_t i;
|
142
|
+
interned_slice_refcount **strtab;
|
143
|
+
interned_slice_refcount *s, *next;
|
144
|
+
|
145
|
+
GPR_TIMER_BEGIN("grow_strtab", 0);
|
146
|
+
|
147
|
+
strtab = gpr_zalloc(sizeof(interned_slice_refcount *) * capacity);
|
148
|
+
|
149
|
+
for (i = 0; i < shard->capacity; i++) {
|
150
|
+
for (s = shard->strs[i]; s; s = next) {
|
151
|
+
size_t idx = TABLE_IDX(s->hash, capacity);
|
152
|
+
next = s->bucket_next;
|
153
|
+
s->bucket_next = strtab[idx];
|
154
|
+
strtab[idx] = s;
|
155
|
+
}
|
156
|
+
}
|
157
|
+
|
158
|
+
gpr_free(shard->strs);
|
159
|
+
shard->strs = strtab;
|
160
|
+
shard->capacity = capacity;
|
161
|
+
|
162
|
+
GPR_TIMER_END("grow_strtab", 0);
|
163
|
+
}
|
164
|
+
|
165
|
+
static grpc_slice materialize(interned_slice_refcount *s) {
|
166
|
+
grpc_slice slice;
|
167
|
+
slice.refcount = &s->base;
|
168
|
+
slice.data.refcounted.bytes = (uint8_t *)(s + 1);
|
169
|
+
slice.data.refcounted.length = s->length;
|
170
|
+
return slice;
|
171
|
+
}
|
172
|
+
|
173
|
+
uint32_t grpc_slice_default_hash_impl(grpc_slice s) {
|
174
|
+
return gpr_murmur_hash3(GRPC_SLICE_START_PTR(s), GRPC_SLICE_LENGTH(s),
|
175
|
+
g_hash_seed);
|
176
|
+
}
|
177
|
+
|
178
|
+
uint32_t grpc_static_slice_hash(grpc_slice s) {
|
179
|
+
return static_metadata_hash_values[GRPC_STATIC_METADATA_INDEX(s)];
|
180
|
+
}
|
181
|
+
|
182
|
+
int grpc_static_slice_eq(grpc_slice a, grpc_slice b) {
|
183
|
+
return GRPC_STATIC_METADATA_INDEX(a) == GRPC_STATIC_METADATA_INDEX(b);
|
184
|
+
}
|
185
|
+
|
186
|
+
uint32_t grpc_slice_hash(grpc_slice s) {
|
187
|
+
return s.refcount == NULL ? grpc_slice_default_hash_impl(s)
|
188
|
+
: s.refcount->vtable->hash(s);
|
189
|
+
}
|
190
|
+
|
191
|
+
grpc_slice grpc_slice_maybe_static_intern(grpc_slice slice,
|
192
|
+
bool *returned_slice_is_different) {
|
193
|
+
if (GRPC_IS_STATIC_METADATA_STRING(slice)) {
|
194
|
+
return slice;
|
195
|
+
}
|
196
|
+
|
197
|
+
uint32_t hash = grpc_slice_hash(slice);
|
198
|
+
for (uint32_t i = 0; i <= max_static_metadata_hash_probe; i++) {
|
199
|
+
static_metadata_hash_ent ent =
|
200
|
+
static_metadata_hash[(hash + i) % GPR_ARRAY_SIZE(static_metadata_hash)];
|
201
|
+
if (ent.hash == hash && ent.idx < GRPC_STATIC_MDSTR_COUNT &&
|
202
|
+
grpc_slice_eq(grpc_static_slice_table[ent.idx], slice)) {
|
203
|
+
*returned_slice_is_different = true;
|
204
|
+
return grpc_static_slice_table[ent.idx];
|
205
|
+
}
|
206
|
+
}
|
207
|
+
|
208
|
+
return slice;
|
209
|
+
}
|
210
|
+
|
211
|
+
bool grpc_slice_is_interned(grpc_slice slice) {
|
212
|
+
return (slice.refcount && slice.refcount->vtable == &interned_slice_vtable) ||
|
213
|
+
GRPC_IS_STATIC_METADATA_STRING(slice);
|
214
|
+
}
|
215
|
+
|
216
|
+
grpc_slice grpc_slice_intern(grpc_slice slice) {
|
217
|
+
GPR_TIMER_BEGIN("grpc_slice_intern", 0);
|
218
|
+
if (GRPC_IS_STATIC_METADATA_STRING(slice)) {
|
219
|
+
GPR_TIMER_END("grpc_slice_intern", 0);
|
220
|
+
return slice;
|
221
|
+
}
|
222
|
+
|
223
|
+
uint32_t hash = grpc_slice_hash(slice);
|
224
|
+
for (uint32_t i = 0; i <= max_static_metadata_hash_probe; i++) {
|
225
|
+
static_metadata_hash_ent ent =
|
226
|
+
static_metadata_hash[(hash + i) % GPR_ARRAY_SIZE(static_metadata_hash)];
|
227
|
+
if (ent.hash == hash && ent.idx < GRPC_STATIC_MDSTR_COUNT &&
|
228
|
+
grpc_slice_eq(grpc_static_slice_table[ent.idx], slice)) {
|
229
|
+
GPR_TIMER_END("grpc_slice_intern", 0);
|
230
|
+
return grpc_static_slice_table[ent.idx];
|
231
|
+
}
|
232
|
+
}
|
233
|
+
|
234
|
+
interned_slice_refcount *s;
|
235
|
+
slice_shard *shard = &g_shards[SHARD_IDX(hash)];
|
236
|
+
|
237
|
+
gpr_mu_lock(&shard->mu);
|
238
|
+
|
239
|
+
/* search for an existing string */
|
240
|
+
size_t idx = TABLE_IDX(hash, shard->capacity);
|
241
|
+
for (s = shard->strs[idx]; s; s = s->bucket_next) {
|
242
|
+
if (s->hash == hash && grpc_slice_eq(slice, materialize(s))) {
|
243
|
+
if (gpr_atm_no_barrier_fetch_add(&s->refcnt, 1) == 0) {
|
244
|
+
/* If we get here, we've added a ref to something that was about to
|
245
|
+
* die - drop it immediately.
|
246
|
+
* The *only* possible path here (given the shard mutex) should be to
|
247
|
+
* drop from one ref back to zero - assert that with a CAS */
|
248
|
+
GPR_ASSERT(gpr_atm_rel_cas(&s->refcnt, 1, 0));
|
249
|
+
/* and treat this as if we were never here... sshhh */
|
250
|
+
} else {
|
251
|
+
gpr_mu_unlock(&shard->mu);
|
252
|
+
GPR_TIMER_END("grpc_slice_intern", 0);
|
253
|
+
return materialize(s);
|
254
|
+
}
|
255
|
+
}
|
256
|
+
}
|
257
|
+
|
258
|
+
/* not found: create a new string */
|
259
|
+
/* string data goes after the internal_string header */
|
260
|
+
s = gpr_malloc(sizeof(*s) + GRPC_SLICE_LENGTH(slice));
|
261
|
+
gpr_atm_rel_store(&s->refcnt, 1);
|
262
|
+
s->length = GRPC_SLICE_LENGTH(slice);
|
263
|
+
s->hash = hash;
|
264
|
+
s->base.vtable = &interned_slice_vtable;
|
265
|
+
s->base.sub_refcount = &s->sub;
|
266
|
+
s->sub.vtable = &interned_slice_sub_vtable;
|
267
|
+
s->sub.sub_refcount = &s->sub;
|
268
|
+
s->bucket_next = shard->strs[idx];
|
269
|
+
shard->strs[idx] = s;
|
270
|
+
memcpy(s + 1, GRPC_SLICE_START_PTR(slice), GRPC_SLICE_LENGTH(slice));
|
271
|
+
|
272
|
+
shard->count++;
|
273
|
+
|
274
|
+
if (shard->count > shard->capacity * 2) {
|
275
|
+
grow_shard(shard);
|
276
|
+
}
|
277
|
+
|
278
|
+
gpr_mu_unlock(&shard->mu);
|
279
|
+
|
280
|
+
GPR_TIMER_END("grpc_slice_intern", 0);
|
281
|
+
return materialize(s);
|
282
|
+
}
|
283
|
+
|
284
|
+
void grpc_test_only_set_slice_hash_seed(uint32_t seed) {
|
285
|
+
g_hash_seed = seed;
|
286
|
+
g_forced_hash_seed = 1;
|
287
|
+
}
|
288
|
+
|
289
|
+
void grpc_slice_intern_init(void) {
|
290
|
+
if (!g_forced_hash_seed) {
|
291
|
+
g_hash_seed = (uint32_t)gpr_now(GPR_CLOCK_REALTIME).tv_nsec;
|
292
|
+
}
|
293
|
+
for (size_t i = 0; i < SHARD_COUNT; i++) {
|
294
|
+
slice_shard *shard = &g_shards[i];
|
295
|
+
gpr_mu_init(&shard->mu);
|
296
|
+
shard->count = 0;
|
297
|
+
shard->capacity = INITIAL_SHARD_CAPACITY;
|
298
|
+
shard->strs = gpr_zalloc(sizeof(*shard->strs) * shard->capacity);
|
299
|
+
}
|
300
|
+
for (size_t i = 0; i < GPR_ARRAY_SIZE(static_metadata_hash); i++) {
|
301
|
+
static_metadata_hash[i].hash = 0;
|
302
|
+
static_metadata_hash[i].idx = GRPC_STATIC_MDSTR_COUNT;
|
303
|
+
}
|
304
|
+
max_static_metadata_hash_probe = 0;
|
305
|
+
for (size_t i = 0; i < GRPC_STATIC_MDSTR_COUNT; i++) {
|
306
|
+
static_metadata_hash_values[i] =
|
307
|
+
grpc_slice_default_hash_impl(grpc_static_slice_table[i]);
|
308
|
+
for (size_t j = 0; j < GPR_ARRAY_SIZE(static_metadata_hash); j++) {
|
309
|
+
size_t slot = (static_metadata_hash_values[i] + j) %
|
310
|
+
GPR_ARRAY_SIZE(static_metadata_hash);
|
311
|
+
if (static_metadata_hash[slot].idx == GRPC_STATIC_MDSTR_COUNT) {
|
312
|
+
static_metadata_hash[slot].hash = static_metadata_hash_values[i];
|
313
|
+
static_metadata_hash[slot].idx = (uint32_t)i;
|
314
|
+
if (j > max_static_metadata_hash_probe) {
|
315
|
+
max_static_metadata_hash_probe = (uint32_t)j;
|
316
|
+
}
|
317
|
+
break;
|
318
|
+
}
|
319
|
+
}
|
320
|
+
}
|
321
|
+
}
|
322
|
+
|
323
|
+
void grpc_slice_intern_shutdown(void) {
|
324
|
+
for (size_t i = 0; i < SHARD_COUNT; i++) {
|
325
|
+
slice_shard *shard = &g_shards[i];
|
326
|
+
gpr_mu_destroy(&shard->mu);
|
327
|
+
/* TODO(ctiller): GPR_ASSERT(shard->count == 0); */
|
328
|
+
if (shard->count != 0) {
|
329
|
+
gpr_log(GPR_DEBUG, "WARNING: %" PRIuPTR " metadata strings were leaked",
|
330
|
+
shard->count);
|
331
|
+
for (size_t j = 0; j < shard->capacity; j++) {
|
332
|
+
for (interned_slice_refcount *s = shard->strs[j]; s;
|
333
|
+
s = s->bucket_next) {
|
334
|
+
char *text =
|
335
|
+
grpc_dump_slice(materialize(s), GPR_DUMP_HEX | GPR_DUMP_ASCII);
|
336
|
+
gpr_log(GPR_DEBUG, "LEAKED: %s", text);
|
337
|
+
gpr_free(text);
|
338
|
+
}
|
339
|
+
}
|
340
|
+
if (grpc_iomgr_abort_on_leaks()) {
|
341
|
+
abort();
|
342
|
+
}
|
343
|
+
}
|
344
|
+
gpr_free(shard->strs);
|
345
|
+
}
|
346
|
+
}
|