wearefair-grpc 1.3.1.pre.c → 1.4.0.fair

Sign up to get free protection for your applications and to get access to all the features.
Files changed (219) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +418 -126
  3. data/include/grpc/grpc.h +15 -69
  4. data/include/grpc/grpc_security.h +1 -1
  5. data/include/grpc/impl/codegen/compression_types.h +3 -4
  6. data/include/grpc/impl/codegen/gpr_types.h +0 -1
  7. data/include/grpc/impl/codegen/grpc_types.h +69 -3
  8. data/include/grpc/impl/codegen/port_platform.h +6 -0
  9. data/include/grpc/impl/codegen/slice.h +2 -1
  10. data/include/grpc/load_reporting.h +6 -6
  11. data/include/grpc/slice.h +25 -3
  12. data/include/grpc/slice_buffer.h +4 -0
  13. data/src/core/ext/census/context.c +1 -1
  14. data/src/core/ext/census/resource.c +3 -1
  15. data/src/core/ext/filters/client_channel/channel_connectivity.c +1 -1
  16. data/src/core/ext/filters/client_channel/client_channel.c +158 -100
  17. data/src/core/ext/filters/client_channel/client_channel_plugin.c +3 -2
  18. data/src/core/ext/filters/client_channel/lb_policy.c +2 -1
  19. data/src/core/ext/filters/client_channel/lb_policy.h +5 -6
  20. data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c +153 -0
  21. data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h +42 -0
  22. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c +344 -88
  23. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c +133 -0
  24. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h +65 -0
  25. data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c +47 -5
  26. data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h +6 -0
  27. data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c +19 -8
  28. data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h +63 -34
  29. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.c +2 -1
  30. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.c +13 -12
  31. data/src/core/ext/filters/client_channel/lb_policy_factory.c +28 -5
  32. data/src/core/ext/filters/client_channel/lb_policy_factory.h +18 -4
  33. data/src/core/ext/filters/client_channel/parse_address.c +37 -7
  34. data/src/core/ext/filters/client_channel/parse_address.h +11 -8
  35. data/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.c +3 -3
  36. data/src/core/ext/filters/client_channel/subchannel.c +19 -16
  37. data/src/core/ext/filters/client_channel/subchannel.h +1 -0
  38. data/src/core/ext/filters/client_channel/uri_parser.c +36 -22
  39. data/src/core/ext/filters/client_channel/uri_parser.h +1 -1
  40. data/src/core/{lib/channel → ext/filters/deadline}/deadline_filter.c +42 -17
  41. data/src/core/{lib/channel → ext/filters/deadline}/deadline_filter.h +8 -9
  42. data/src/core/{lib/channel → ext/filters/http/client}/http_client_filter.c +19 -11
  43. data/src/core/{lib/channel → ext/filters/http/client}/http_client_filter.h +3 -6
  44. data/src/core/ext/filters/http/http_filters_plugin.c +104 -0
  45. data/src/core/{lib/channel/compress_filter.c → ext/filters/http/message_compress/message_compress_filter.c} +124 -23
  46. data/src/core/{lib/channel/compress_filter.h → ext/filters/http/message_compress/message_compress_filter.h} +5 -6
  47. data/src/core/{lib/channel → ext/filters/http/server}/http_server_filter.c +4 -6
  48. data/src/core/{lib/channel → ext/filters/http/server}/http_server_filter.h +3 -3
  49. data/src/core/ext/filters/load_reporting/load_reporting.c +2 -25
  50. data/src/core/ext/filters/load_reporting/load_reporting_filter.c +26 -1
  51. data/src/core/ext/filters/max_age/max_age_filter.c +14 -14
  52. data/src/core/{lib/channel → ext/filters/message_size}/message_size_filter.c +91 -47
  53. data/src/core/{lib/channel → ext/filters/message_size}/message_size_filter.h +3 -3
  54. data/src/core/ext/transport/chttp2/client/insecure/channel_create.c +1 -1
  55. data/src/core/ext/transport/chttp2/server/chttp2_server.c +2 -2
  56. data/src/core/ext/transport/chttp2/transport/bin_decoder.c +2 -2
  57. data/src/core/ext/transport/chttp2/transport/bin_encoder.c +3 -3
  58. data/src/core/ext/transport/chttp2/transport/chttp2_transport.c +296 -172
  59. data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +3 -2
  60. data/src/core/ext/transport/chttp2/transport/frame_data.c +203 -164
  61. data/src/core/ext/transport/chttp2/transport/frame_data.h +8 -14
  62. data/src/core/ext/transport/chttp2/transport/frame_goaway.c +1 -1
  63. data/src/core/ext/transport/chttp2/transport/frame_ping.c +1 -1
  64. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.c +1 -1
  65. data/src/core/ext/transport/chttp2/transport/frame_settings.c +5 -5
  66. data/src/core/ext/transport/chttp2/transport/frame_window_update.c +1 -1
  67. data/src/core/ext/transport/chttp2/transport/hpack_encoder.c +4 -4
  68. data/src/core/ext/transport/chttp2/transport/hpack_parser.c +2 -4
  69. data/src/core/ext/transport/chttp2/transport/hpack_table.c +4 -3
  70. data/src/core/ext/transport/chttp2/transport/internal.h +50 -33
  71. data/src/core/ext/transport/chttp2/transport/parsing.c +10 -11
  72. data/src/core/ext/transport/chttp2/transport/writing.c +32 -13
  73. data/src/core/lib/channel/channel_args.c +28 -9
  74. data/src/core/lib/channel/channel_args.h +5 -1
  75. data/src/core/lib/channel/channel_stack.c +1 -1
  76. data/src/core/lib/channel/channel_stack.h +2 -2
  77. data/src/core/lib/channel/channel_stack_builder.c +13 -1
  78. data/src/core/lib/channel/channel_stack_builder.h +5 -1
  79. data/src/core/lib/channel/connected_channel.c +3 -1
  80. data/src/core/lib/channel/context.h +2 -2
  81. data/src/core/lib/compression/message_compress.c +2 -2
  82. data/src/core/lib/debug/trace.c +13 -6
  83. data/src/core/lib/debug/trace.h +27 -1
  84. data/src/core/lib/http/httpcli.c +1 -1
  85. data/src/core/lib/http/httpcli_security_connector.c +6 -10
  86. data/src/core/lib/http/parser.c +2 -2
  87. data/src/core/lib/http/parser.h +2 -1
  88. data/src/core/lib/iomgr/combiner.c +6 -6
  89. data/src/core/lib/iomgr/combiner.h +2 -1
  90. data/src/core/lib/iomgr/error.c +12 -5
  91. data/src/core/lib/iomgr/error.h +13 -13
  92. data/src/core/lib/iomgr/ev_epoll1_linux.c +984 -0
  93. data/src/core/lib/iomgr/ev_epoll1_linux.h +44 -0
  94. data/src/core/lib/iomgr/ev_epoll_limited_pollers_linux.c +2146 -0
  95. data/src/core/lib/iomgr/ev_epoll_limited_pollers_linux.h +43 -0
  96. data/src/core/lib/iomgr/ev_epoll_thread_pool_linux.c +1337 -0
  97. data/src/core/lib/iomgr/ev_epoll_thread_pool_linux.h +43 -0
  98. data/src/core/lib/iomgr/ev_epollex_linux.c +1511 -0
  99. data/src/core/lib/iomgr/ev_epollex_linux.h +43 -0
  100. data/src/core/lib/iomgr/{ev_epoll_linux.c → ev_epollsig_linux.c} +24 -31
  101. data/src/core/lib/iomgr/{ev_epoll_linux.h → ev_epollsig_linux.h} +4 -4
  102. data/src/core/lib/iomgr/ev_poll_posix.c +12 -27
  103. data/src/core/lib/iomgr/ev_poll_posix.h +2 -2
  104. data/src/core/lib/iomgr/ev_posix.c +22 -8
  105. data/src/core/lib/iomgr/ev_posix.h +4 -3
  106. data/src/core/lib/iomgr/exec_ctx.c +5 -0
  107. data/src/core/lib/iomgr/exec_ctx.h +2 -0
  108. data/src/core/lib/iomgr/iomgr.c +4 -0
  109. data/src/core/lib/iomgr/iomgr.h +3 -0
  110. data/src/core/lib/iomgr/is_epollexclusive_available.c +116 -0
  111. data/src/core/lib/iomgr/is_epollexclusive_available.h +41 -0
  112. data/src/core/lib/iomgr/lockfree_event.c +16 -0
  113. data/src/core/lib/iomgr/pollset.h +2 -5
  114. data/src/core/lib/iomgr/pollset_uv.c +1 -1
  115. data/src/core/lib/iomgr/pollset_windows.c +3 -3
  116. data/src/core/lib/iomgr/resource_quota.c +9 -8
  117. data/src/core/lib/iomgr/resource_quota.h +2 -1
  118. data/src/core/lib/iomgr/sockaddr_utils.h +1 -1
  119. data/src/core/lib/iomgr/socket_mutator.h +2 -0
  120. data/src/core/lib/iomgr/sys_epoll_wrapper.h +43 -0
  121. data/src/core/lib/iomgr/tcp_client_posix.c +6 -6
  122. data/src/core/lib/iomgr/tcp_client_uv.c +3 -3
  123. data/src/core/lib/iomgr/tcp_posix.c +7 -7
  124. data/src/core/lib/iomgr/tcp_posix.h +2 -1
  125. data/src/core/lib/iomgr/tcp_server_posix.c +1 -1
  126. data/src/core/lib/iomgr/tcp_uv.c +6 -6
  127. data/src/core/lib/iomgr/tcp_uv.h +2 -1
  128. data/src/core/lib/iomgr/tcp_windows.c +1 -1
  129. data/src/core/lib/iomgr/timer_generic.c +24 -25
  130. data/src/core/lib/iomgr/timer_manager.c +276 -0
  131. data/src/core/lib/iomgr/timer_manager.h +52 -0
  132. data/src/core/lib/iomgr/timer_uv.c +6 -0
  133. data/src/core/lib/iomgr/udp_server.c +42 -9
  134. data/src/core/lib/iomgr/udp_server.h +3 -1
  135. data/src/core/lib/security/credentials/credentials.c +0 -1
  136. data/src/core/lib/security/credentials/fake/fake_credentials.c +23 -0
  137. data/src/core/lib/security/credentials/fake/fake_credentials.h +12 -9
  138. data/src/core/lib/security/credentials/google_default/google_default_credentials.c +1 -1
  139. data/src/core/lib/security/credentials/jwt/jwt_credentials.c +1 -1
  140. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.c +1 -1
  141. data/src/core/lib/security/credentials/ssl/ssl_credentials.c +24 -53
  142. data/src/core/lib/security/transport/client_auth_filter.c +9 -3
  143. data/src/core/lib/security/transport/secure_endpoint.c +7 -7
  144. data/src/core/lib/security/transport/secure_endpoint.h +1 -1
  145. data/src/core/lib/security/transport/security_connector.c +32 -51
  146. data/src/core/lib/security/transport/security_connector.h +10 -14
  147. data/src/core/lib/slice/b64.c +1 -1
  148. data/src/core/lib/slice/percent_encoding.c +3 -3
  149. data/src/core/lib/slice/slice.c +66 -33
  150. data/src/core/lib/slice/slice_buffer.c +25 -6
  151. data/src/core/lib/slice/slice_hash_table.c +33 -35
  152. data/src/core/lib/slice/slice_hash_table.h +7 -12
  153. data/src/core/lib/support/atomic.h +45 -0
  154. data/src/core/lib/support/atomic_with_atm.h +70 -0
  155. data/src/core/lib/support/atomic_with_std.h +48 -0
  156. data/src/core/lib/support/avl.c +14 -14
  157. data/src/core/lib/support/memory.h +74 -0
  158. data/src/core/lib/support/mpscq.c +12 -1
  159. data/src/core/lib/support/mpscq.h +4 -0
  160. data/src/core/lib/support/stack_lockfree.c +3 -36
  161. data/src/core/lib/support/time_posix.c +8 -0
  162. data/src/core/lib/support/tmpfile_posix.c +10 -10
  163. data/src/core/lib/surface/alarm.c +3 -1
  164. data/src/core/lib/surface/api_trace.c +2 -1
  165. data/src/core/lib/surface/api_trace.h +2 -2
  166. data/src/core/lib/surface/byte_buffer_reader.c +1 -1
  167. data/src/core/lib/surface/call.c +65 -22
  168. data/src/core/lib/surface/call.h +4 -2
  169. data/src/core/lib/surface/channel_init.c +2 -19
  170. data/src/core/lib/surface/channel_stack_type.c +18 -0
  171. data/src/core/lib/surface/channel_stack_type.h +2 -0
  172. data/src/core/lib/surface/completion_queue.c +249 -83
  173. data/src/core/lib/surface/completion_queue.h +18 -13
  174. data/src/core/lib/surface/completion_queue_factory.c +24 -9
  175. data/src/core/lib/surface/init.c +1 -52
  176. data/src/core/lib/surface/{lame_client.c → lame_client.cc} +37 -26
  177. data/src/core/lib/surface/server.c +50 -27
  178. data/src/core/lib/surface/server.h +2 -1
  179. data/src/core/lib/surface/version.c +2 -2
  180. data/src/core/lib/transport/bdp_estimator.c +20 -9
  181. data/src/core/lib/transport/bdp_estimator.h +5 -1
  182. data/src/core/lib/transport/byte_stream.c +23 -9
  183. data/src/core/lib/transport/byte_stream.h +15 -6
  184. data/src/core/lib/transport/connectivity_state.c +6 -6
  185. data/src/core/lib/transport/connectivity_state.h +2 -1
  186. data/src/core/lib/transport/service_config.c +6 -13
  187. data/src/core/lib/transport/service_config.h +2 -2
  188. data/src/core/lib/transport/static_metadata.c +403 -389
  189. data/src/core/lib/transport/static_metadata.h +127 -114
  190. data/src/core/plugin_registry/grpc_plugin_registry.c +12 -0
  191. data/src/core/tsi/fake_transport_security.c +5 -4
  192. data/src/core/tsi/ssl_transport_security.c +71 -82
  193. data/src/core/tsi/ssl_transport_security.h +39 -61
  194. data/src/core/tsi/transport_security.c +83 -2
  195. data/src/core/tsi/transport_security.h +27 -2
  196. data/src/core/tsi/transport_security_adapter.c +236 -0
  197. data/src/core/tsi/transport_security_adapter.h +62 -0
  198. data/src/core/tsi/transport_security_interface.h +179 -66
  199. data/src/ruby/ext/grpc/extconf.rb +2 -1
  200. data/src/ruby/ext/grpc/rb_byte_buffer.c +8 -6
  201. data/src/ruby/ext/grpc/rb_call.c +56 -48
  202. data/src/ruby/ext/grpc/rb_call.h +3 -4
  203. data/src/ruby/ext/grpc/rb_call_credentials.c +23 -22
  204. data/src/ruby/ext/grpc/rb_channel.c +45 -29
  205. data/src/ruby/ext/grpc/rb_channel_args.c +11 -9
  206. data/src/ruby/ext/grpc/rb_channel_credentials.c +16 -12
  207. data/src/ruby/ext/grpc/rb_completion_queue.c +7 -9
  208. data/src/ruby/ext/grpc/rb_compression_options.c +7 -6
  209. data/src/ruby/ext/grpc/rb_event_thread.c +10 -12
  210. data/src/ruby/ext/grpc/rb_event_thread.h +1 -2
  211. data/src/ruby/ext/grpc/rb_grpc.c +11 -15
  212. data/src/ruby/ext/grpc/rb_grpc.h +2 -2
  213. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +14 -6
  214. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +22 -10
  215. data/src/ruby/ext/grpc/rb_server.c +26 -28
  216. data/src/ruby/lib/grpc/version.rb +1 -1
  217. metadata +40 -18
  218. data/src/ruby/lib/grpc/grpc_c.bundle +0 -0
  219. data/src/ruby/lib/grpc/grpc_c.so +0 -0
@@ -253,16 +253,18 @@ void grpc_slice_buffer_move_into(grpc_slice_buffer *src,
253
253
  src->length = 0;
254
254
  }
255
255
 
256
- void grpc_slice_buffer_move_first(grpc_slice_buffer *src, size_t n,
257
- grpc_slice_buffer *dst) {
258
- size_t output_len = dst->length + n;
259
- size_t new_input_len = src->length - n;
256
+ static void slice_buffer_move_first_maybe_ref(grpc_slice_buffer *src, size_t n,
257
+ grpc_slice_buffer *dst,
258
+ bool incref) {
260
259
  GPR_ASSERT(src->length >= n);
261
260
  if (src->length == n) {
262
261
  grpc_slice_buffer_move_into(src, dst);
263
262
  return;
264
263
  }
265
264
 
265
+ size_t output_len = dst->length + n;
266
+ size_t new_input_len = src->length - n;
267
+
266
268
  while (src->count > 0) {
267
269
  grpc_slice slice = grpc_slice_buffer_take_first(src);
268
270
  size_t slice_len = GRPC_SLICE_LENGTH(slice);
@@ -272,11 +274,18 @@ void grpc_slice_buffer_move_first(grpc_slice_buffer *src, size_t n,
272
274
  } else if (n == slice_len) {
273
275
  grpc_slice_buffer_add(dst, slice);
274
276
  break;
275
- } else { /* n < slice_len */
276
- grpc_slice_buffer_undo_take_first(src, grpc_slice_split_tail(&slice, n));
277
+ } else if (incref) { /* n < slice_len */
278
+ grpc_slice_buffer_undo_take_first(
279
+ src, grpc_slice_split_tail_maybe_ref(&slice, n, GRPC_SLICE_REF_BOTH));
277
280
  GPR_ASSERT(GRPC_SLICE_LENGTH(slice) == n);
278
281
  grpc_slice_buffer_add(dst, slice);
279
282
  break;
283
+ } else { /* n < slice_len */
284
+ grpc_slice_buffer_undo_take_first(
285
+ src, grpc_slice_split_tail_maybe_ref(&slice, n, GRPC_SLICE_REF_TAIL));
286
+ GPR_ASSERT(GRPC_SLICE_LENGTH(slice) == n);
287
+ grpc_slice_buffer_add_indexed(dst, slice);
288
+ break;
280
289
  }
281
290
  }
282
291
  GPR_ASSERT(dst->length == output_len);
@@ -284,6 +293,16 @@ void grpc_slice_buffer_move_first(grpc_slice_buffer *src, size_t n,
284
293
  GPR_ASSERT(src->count > 0);
285
294
  }
286
295
 
296
+ void grpc_slice_buffer_move_first(grpc_slice_buffer *src, size_t n,
297
+ grpc_slice_buffer *dst) {
298
+ slice_buffer_move_first_maybe_ref(src, n, dst, true);
299
+ }
300
+
301
+ void grpc_slice_buffer_move_first_no_ref(grpc_slice_buffer *src, size_t n,
302
+ grpc_slice_buffer *dst) {
303
+ slice_buffer_move_first_maybe_ref(src, n, dst, false);
304
+ }
305
+
287
306
  void grpc_slice_buffer_move_first_into_buffer(grpc_exec_ctx *exec_ctx,
288
307
  grpc_slice_buffer *src, size_t n,
289
308
  void *dst) {
@@ -42,56 +42,47 @@
42
42
 
43
43
  struct grpc_slice_hash_table {
44
44
  gpr_refcount refs;
45
+ void (*destroy_value)(grpc_exec_ctx* exec_ctx, void* value);
45
46
  size_t size;
47
+ size_t max_num_probes;
46
48
  grpc_slice_hash_table_entry* entries;
47
49
  };
48
50
 
49
51
  static bool is_empty(grpc_slice_hash_table_entry* entry) {
50
- return entry->vtable == NULL;
52
+ return entry->value == NULL;
51
53
  }
52
54
 
53
- // Helper function for insert and get operations that performs quadratic
54
- // probing (https://en.wikipedia.org/wiki/Quadratic_probing).
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);
58
- for (size_t i = 0; i < table->size; ++i) {
59
- const size_t idx = (hash + i * i) % table->size;
55
+ static void grpc_slice_hash_table_add(grpc_slice_hash_table* table,
56
+ grpc_slice key, void* value) {
57
+ GPR_ASSERT(value != NULL);
58
+ const size_t hash = grpc_slice_hash(key);
59
+ for (size_t offset = 0; offset < table->size; ++offset) {
60
+ const size_t idx = (hash + offset) % table->size;
60
61
  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;
62
+ table->entries[idx].key = key;
63
+ table->entries[idx].value = value;
64
+ // Keep track of the maximum number of probes needed, since this
65
+ // provides an upper bound for lookups.
66
+ if (offset > table->max_num_probes) table->max_num_probes = offset;
67
+ return;
65
68
  }
66
69
  }
67
- return table->size; // Not found.
68
- }
69
-
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) {
73
- GPR_ASSERT(value != NULL);
74
- const size_t idx =
75
- grpc_slice_hash_table_find_index(table, key, true /* find_empty */);
76
- GPR_ASSERT(idx != table->size); // Table should never be full.
77
- grpc_slice_hash_table_entry* entry = &table->entries[idx];
78
- entry->key = grpc_slice_ref_internal(key);
79
- entry->value = vtable->copy_value(value);
80
- entry->vtable = vtable;
70
+ GPR_ASSERT(false); // Table should never be full.
81
71
  }
82
72
 
83
73
  grpc_slice_hash_table* grpc_slice_hash_table_create(
84
- size_t num_entries, grpc_slice_hash_table_entry* entries) {
74
+ size_t num_entries, grpc_slice_hash_table_entry* entries,
75
+ void (*destroy_value)(grpc_exec_ctx* exec_ctx, void* value)) {
85
76
  grpc_slice_hash_table* table = gpr_zalloc(sizeof(*table));
86
77
  gpr_ref_init(&table->refs, 1);
87
- // Quadratic probing gets best performance when the table is no more
88
- // than half full.
78
+ table->destroy_value = destroy_value;
79
+ // Keep load factor low to improve performance of lookups.
89
80
  table->size = num_entries * 2;
90
81
  const size_t entry_size = sizeof(grpc_slice_hash_table_entry) * table->size;
91
82
  table->entries = gpr_zalloc(entry_size);
92
83
  for (size_t i = 0; i < num_entries; ++i) {
93
84
  grpc_slice_hash_table_entry* entry = &entries[i];
94
- grpc_slice_hash_table_add(table, entry->key, entry->value, entry->vtable);
85
+ grpc_slice_hash_table_add(table, entry->key, entry->value);
95
86
  }
96
87
  return table;
97
88
  }
@@ -108,7 +99,7 @@ void grpc_slice_hash_table_unref(grpc_exec_ctx* exec_ctx,
108
99
  grpc_slice_hash_table_entry* entry = &table->entries[i];
109
100
  if (!is_empty(entry)) {
110
101
  grpc_slice_unref_internal(exec_ctx, entry->key);
111
- entry->vtable->destroy_value(exec_ctx, entry->value);
102
+ table->destroy_value(exec_ctx, entry->value);
112
103
  }
113
104
  }
114
105
  gpr_free(table->entries);
@@ -118,8 +109,15 @@ void grpc_slice_hash_table_unref(grpc_exec_ctx* exec_ctx,
118
109
 
119
110
  void* grpc_slice_hash_table_get(const grpc_slice_hash_table* table,
120
111
  const grpc_slice key) {
121
- const size_t idx =
122
- grpc_slice_hash_table_find_index(table, key, false /* find_empty */);
123
- if (idx == table->size) return NULL; // Not found.
124
- return table->entries[idx].value;
112
+ const size_t hash = grpc_slice_hash(key);
113
+ // We cap the number of probes at the max number recorded when
114
+ // populating the table.
115
+ for (size_t offset = 0; offset <= table->max_num_probes; ++offset) {
116
+ const size_t idx = (hash + offset) % table->size;
117
+ if (is_empty(&table->entries[idx])) break;
118
+ if (grpc_slice_eq(table->entries[idx].key, key)) {
119
+ return table->entries[idx].value;
120
+ }
121
+ }
122
+ return NULL; // Not found.
125
123
  }
@@ -37,33 +37,28 @@
37
37
  /** Hash table implementation.
38
38
  *
39
39
  * This implementation uses open addressing
40
- * (https://en.wikipedia.org/wiki/Open_addressing) with quadratic
41
- * probing (https://en.wikipedia.org/wiki/Quadratic_probing).
40
+ * (https://en.wikipedia.org/wiki/Open_addressing) with linear
41
+ * probing (https://en.wikipedia.org/wiki/Linear_probing).
42
42
  *
43
43
  * The keys are \a grpc_slice objects. The values are arbitrary pointers
44
- * with a common vtable.
44
+ * with a common destroy function.
45
45
  *
46
46
  * Hash tables are intentionally immutable, to avoid the need for locking.
47
47
  */
48
48
 
49
49
  typedef struct grpc_slice_hash_table grpc_slice_hash_table;
50
50
 
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
-
56
51
  typedef struct grpc_slice_hash_table_entry {
57
52
  grpc_slice key;
58
53
  void *value; /* Must not be NULL. */
59
- const grpc_slice_hash_table_vtable *vtable;
60
54
  } grpc_slice_hash_table_entry;
61
55
 
62
56
  /** Creates a new hash table of containing \a entries, which is an array
63
- of length \a num_entries.
64
- Creates its own copy of all keys and values from \a entries. */
57
+ of length \a num_entries. Takes ownership of all keys and values in
58
+ \a entries. Values will be cleaned up via \a destroy_value(). */
65
59
  grpc_slice_hash_table *grpc_slice_hash_table_create(
66
- size_t num_entries, grpc_slice_hash_table_entry *entries);
60
+ size_t num_entries, grpc_slice_hash_table_entry *entries,
61
+ void (*destroy_value)(grpc_exec_ctx *exec_ctx, void *value));
67
62
 
68
63
  grpc_slice_hash_table *grpc_slice_hash_table_ref(grpc_slice_hash_table *table);
69
64
  void grpc_slice_hash_table_unref(grpc_exec_ctx *exec_ctx,
@@ -0,0 +1,45 @@
1
+ /*
2
+ *
3
+ * Copyright 2017, 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
+ #ifndef GRPC_CORE_LIB_SUPPORT_ATOMIC_H
35
+ #define GRPC_CORE_LIB_SUPPORT_ATOMIC_H
36
+
37
+ #include <grpc/support/port_platform.h>
38
+
39
+ #ifdef GPR_HAS_CXX11_ATOMIC
40
+ #include "src/core/lib/support/atomic_with_std.h"
41
+ #else
42
+ #include "src/core/lib/support/atomic_with_atm.h"
43
+ #endif
44
+
45
+ #endif /* GRPC_CORE_LIB_SUPPORT_ATOMIC_H */
@@ -0,0 +1,70 @@
1
+ /*
2
+ *
3
+ * Copyright 2017, 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
+ #ifndef GRPC_CORE_LIB_SUPPORT_ATOMIC_WITH_ATM_H
35
+ #define GRPC_CORE_LIB_SUPPORT_ATOMIC_WITH_ATM_H
36
+
37
+ #include <grpc/support/atm.h>
38
+
39
+ namespace grpc_core {
40
+
41
+ enum MemoryOrderRelaxed { memory_order_relaxed };
42
+
43
+ template <class T>
44
+ class atomic;
45
+
46
+ template <>
47
+ class atomic<bool> {
48
+ public:
49
+ atomic() { gpr_atm_no_barrier_store(&x_, static_cast<gpr_atm>(false)); }
50
+ explicit atomic(bool x) {
51
+ gpr_atm_no_barrier_store(&x_, static_cast<gpr_atm>(x));
52
+ }
53
+
54
+ bool compare_exchange_strong(bool& expected, bool update, MemoryOrderRelaxed,
55
+ MemoryOrderRelaxed) {
56
+ if (!gpr_atm_no_barrier_cas(&x_, static_cast<gpr_atm>(expected),
57
+ static_cast<gpr_atm>(update))) {
58
+ expected = gpr_atm_no_barrier_load(&x_) != 0;
59
+ return false;
60
+ }
61
+ return true;
62
+ }
63
+
64
+ private:
65
+ gpr_atm x_;
66
+ };
67
+
68
+ } // namespace grpc_core
69
+
70
+ #endif /* GRPC_CORE_LIB_SUPPORT_ATOMIC_WITH_ATM_H */
@@ -0,0 +1,48 @@
1
+ /*
2
+ *
3
+ * Copyright 2017, 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
+ #ifndef GRPC_CORE_LIB_SUPPORT_ATOMIC_WITH_STD_H
35
+ #define GRPC_CORE_LIB_SUPPORT_ATOMIC_WITH_STD_H
36
+
37
+ #include <atomic>
38
+
39
+ namespace grpc_core {
40
+
41
+ template <class T>
42
+ using atomic = std::atomic<T>;
43
+
44
+ typedef std::memory_order memory_order;
45
+
46
+ } // namespace grpc_core
47
+
48
+ #endif /* GRPC_CORE_LIB_SUPPORT_ATOMIC_WITH_STD_H */
@@ -205,8 +205,8 @@ static gpr_avl_node *rebalance(const gpr_avl_vtable *vtable, void *key,
205
205
  }
206
206
  }
207
207
 
208
- static gpr_avl_node *add(const gpr_avl_vtable *vtable, gpr_avl_node *node,
209
- void *key, void *value) {
208
+ static gpr_avl_node *add_key(const gpr_avl_vtable *vtable, gpr_avl_node *node,
209
+ void *key, void *value) {
210
210
  long cmp;
211
211
  if (node == NULL) {
212
212
  return new_node(key, value, NULL, NULL);
@@ -217,17 +217,17 @@ static gpr_avl_node *add(const gpr_avl_vtable *vtable, gpr_avl_node *node,
217
217
  } else if (cmp > 0) {
218
218
  return rebalance(
219
219
  vtable, vtable->copy_key(node->key), vtable->copy_value(node->value),
220
- add(vtable, node->left, key, value), ref_node(node->right));
220
+ add_key(vtable, node->left, key, value), ref_node(node->right));
221
221
  } else {
222
222
  return rebalance(vtable, vtable->copy_key(node->key),
223
223
  vtable->copy_value(node->value), ref_node(node->left),
224
- add(vtable, node->right, key, value));
224
+ add_key(vtable, node->right, key, value));
225
225
  }
226
226
  }
227
227
 
228
228
  gpr_avl gpr_avl_add(gpr_avl avl, void *key, void *value) {
229
229
  gpr_avl_node *old_root = avl.root;
230
- avl.root = add(avl.vtable, avl.root, key, value);
230
+ avl.root = add_key(avl.vtable, avl.root, key, value);
231
231
  assert_invariants(avl.root);
232
232
  unref_node(avl.vtable, old_root);
233
233
  return avl;
@@ -247,8 +247,8 @@ static gpr_avl_node *in_order_tail(gpr_avl_node *node) {
247
247
  return node;
248
248
  }
249
249
 
250
- static gpr_avl_node *remove(const gpr_avl_vtable *vtable, gpr_avl_node *node,
251
- void *key) {
250
+ static gpr_avl_node *remove_key(const gpr_avl_vtable *vtable,
251
+ gpr_avl_node *node, void *key) {
252
252
  long cmp;
253
253
  if (node == NULL) {
254
254
  return NULL;
@@ -263,27 +263,27 @@ static gpr_avl_node *remove(const gpr_avl_vtable *vtable, gpr_avl_node *node,
263
263
  gpr_avl_node *h = in_order_head(node->right);
264
264
  return rebalance(vtable, vtable->copy_key(h->key),
265
265
  vtable->copy_value(h->value), ref_node(node->left),
266
- remove(vtable, node->right, h->key));
266
+ remove_key(vtable, node->right, h->key));
267
267
  } else {
268
268
  gpr_avl_node *h = in_order_tail(node->left);
269
269
  return rebalance(
270
270
  vtable, vtable->copy_key(h->key), vtable->copy_value(h->value),
271
- remove(vtable, node->left, h->key), ref_node(node->right));
271
+ remove_key(vtable, node->left, h->key), ref_node(node->right));
272
272
  }
273
273
  } else if (cmp > 0) {
274
- return rebalance(vtable, vtable->copy_key(node->key),
275
- vtable->copy_value(node->value),
276
- remove(vtable, node->left, key), ref_node(node->right));
274
+ return rebalance(
275
+ vtable, vtable->copy_key(node->key), vtable->copy_value(node->value),
276
+ remove_key(vtable, node->left, key), ref_node(node->right));
277
277
  } else {
278
278
  return rebalance(vtable, vtable->copy_key(node->key),
279
279
  vtable->copy_value(node->value), ref_node(node->left),
280
- remove(vtable, node->right, key));
280
+ remove_key(vtable, node->right, key));
281
281
  }
282
282
  }
283
283
 
284
284
  gpr_avl gpr_avl_remove(gpr_avl avl, void *key) {
285
285
  gpr_avl_node *old_root = avl.root;
286
- avl.root = remove(avl.vtable, avl.root, key);
286
+ avl.root = remove_key(avl.vtable, avl.root, key);
287
287
  assert_invariants(avl.root);
288
288
  unref_node(avl.vtable, old_root);
289
289
  return avl;