grpc 1.43.1 → 1.44.0.pre2

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.

Files changed (382) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +84 -64
  3. data/include/grpc/grpc_security.h +10 -0
  4. data/include/grpc/impl/codegen/compression_types.h +0 -2
  5. data/include/grpc/impl/codegen/grpc_types.h +6 -0
  6. data/src/core/ext/filters/client_channel/backend_metric.h +1 -1
  7. data/src/core/ext/filters/client_channel/client_channel.cc +62 -68
  8. data/src/core/ext/filters/client_channel/client_channel.h +8 -8
  9. data/src/core/ext/filters/client_channel/client_channel_plugin.cc +1 -1
  10. data/src/core/ext/filters/client_channel/config_selector.h +4 -4
  11. data/src/core/ext/filters/client_channel/dynamic_filters.h +1 -1
  12. data/src/core/ext/filters/client_channel/health/health_check_client.cc +16 -14
  13. data/src/core/ext/filters/client_channel/health/health_check_client.h +3 -3
  14. data/src/core/ext/filters/client_channel/http_connect_handshaker.cc +1 -1
  15. data/src/core/ext/filters/client_channel/lb_policy/address_filtering.cc +4 -3
  16. data/src/core/ext/filters/client_channel/lb_policy/address_filtering.h +6 -5
  17. data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc +3 -7
  18. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +31 -32
  19. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h +0 -7
  20. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h +1 -1
  21. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h +1 -1
  22. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc +1 -1
  23. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +43 -29
  24. data/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc +6 -2
  25. data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.cc +120 -68
  26. data/src/core/ext/filters/client_channel/lb_policy/rls/rls.cc +60 -48
  27. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +62 -61
  28. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +16 -11
  29. data/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc +11 -5
  30. data/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc +19 -15
  31. data/src/core/ext/filters/client_channel/lb_policy/xds/xds.h +1 -1
  32. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc +14 -12
  33. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc +3 -2
  34. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc +50 -105
  35. data/src/core/ext/filters/client_channel/lb_policy.cc +15 -14
  36. data/src/core/ext/filters/client_channel/lb_policy.h +19 -3
  37. data/src/core/ext/filters/client_channel/resolver/binder/binder_resolver.cc +3 -3
  38. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +207 -81
  39. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h +22 -12
  40. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc +19 -15
  41. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +23 -38
  42. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +118 -207
  43. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +25 -32
  44. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +1 -1
  45. data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +82 -73
  46. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +10 -10
  47. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h +2 -1
  48. data/src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc +2 -5
  49. data/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +5 -5
  50. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +157 -67
  51. data/src/core/ext/filters/client_channel/resolver_result_parsing.cc +1 -1
  52. data/src/core/ext/filters/client_channel/resolver_result_parsing.h +2 -2
  53. data/src/core/ext/filters/client_channel/retry_filter.cc +37 -64
  54. data/src/core/ext/filters/client_channel/retry_service_config.cc +1 -1
  55. data/src/core/ext/filters/client_channel/retry_service_config.h +1 -1
  56. data/src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc +1 -1
  57. data/src/core/ext/filters/client_channel/subchannel.cc +12 -16
  58. data/src/core/ext/filters/client_channel/subchannel.h +2 -3
  59. data/src/core/ext/filters/fault_injection/fault_injection_filter.cc +37 -48
  60. data/src/core/ext/filters/fault_injection/service_config_parser.cc +6 -8
  61. data/src/core/ext/filters/fault_injection/service_config_parser.h +1 -1
  62. data/src/core/ext/filters/http/client/http_client_filter.cc +51 -122
  63. data/src/core/ext/filters/http/client_authority_filter.cc +8 -24
  64. data/src/core/ext/filters/http/message_compress/message_compress_filter.cc +42 -140
  65. data/src/core/ext/filters/http/message_compress/message_decompress_filter.cc +5 -25
  66. data/src/core/ext/filters/http/server/http_server_filter.cc +50 -135
  67. data/src/core/ext/filters/message_size/message_size_filter.cc +1 -1
  68. data/src/core/ext/filters/message_size/message_size_filter.h +1 -1
  69. data/src/core/ext/filters/rbac/rbac_filter.cc +157 -0
  70. data/src/core/ext/filters/rbac/rbac_filter.h +74 -0
  71. data/src/core/ext/filters/rbac/rbac_service_config_parser.cc +605 -0
  72. data/src/core/ext/filters/rbac/rbac_service_config_parser.h +70 -0
  73. data/src/core/ext/filters/server_config_selector/server_config_selector.h +3 -2
  74. data/src/core/ext/filters/server_config_selector/server_config_selector_filter.cc +11 -6
  75. data/src/core/ext/transport/chttp2/client/insecure/channel_create.cc +1 -1
  76. data/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc +1 -1
  77. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +89 -29
  78. data/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc +0 -1
  79. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +45 -186
  80. data/src/core/ext/transport/chttp2/transport/frame_data.cc +0 -1
  81. data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +341 -279
  82. data/src/core/ext/transport/chttp2/transport/hpack_encoder.h +69 -159
  83. data/src/core/ext/transport/chttp2/transport/hpack_encoder_table.cc +1 -1
  84. data/src/core/ext/transport/chttp2/transport/hpack_encoder_table.h +2 -0
  85. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +19 -32
  86. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +0 -1
  87. data/src/core/ext/transport/chttp2/transport/hpack_parser_table.cc +94 -1
  88. data/src/core/ext/transport/chttp2/transport/hpack_parser_table.h +2 -24
  89. data/src/core/ext/transport/chttp2/transport/internal.h +0 -33
  90. data/src/core/ext/transport/chttp2/transport/parsing.cc +0 -6
  91. data/src/core/ext/transport/chttp2/transport/writing.cc +47 -116
  92. data/src/core/ext/transport/inproc/inproc_plugin.cc +0 -4
  93. data/src/core/ext/transport/inproc/inproc_transport.cc +11 -63
  94. data/src/core/ext/transport/inproc/inproc_transport.h +0 -3
  95. data/src/core/ext/upb-generated/envoy/extensions/filters/http/rbac/v3/rbac.upb.c +61 -0
  96. data/src/core/ext/upb-generated/envoy/extensions/filters/http/rbac/v3/rbac.upb.h +146 -0
  97. data/src/core/ext/upbdefs-generated/envoy/config/rbac/v3/rbac.upbdefs.c +188 -0
  98. data/src/core/ext/upbdefs-generated/envoy/config/rbac/v3/rbac.upbdefs.h +70 -0
  99. data/src/core/ext/upbdefs-generated/envoy/extensions/filters/http/rbac/v3/rbac.upbdefs.c +56 -0
  100. data/src/core/ext/upbdefs-generated/envoy/extensions/filters/http/rbac/v3/rbac.upbdefs.h +40 -0
  101. data/src/core/ext/upbdefs-generated/google/api/expr/v1alpha1/checked.upbdefs.c +154 -0
  102. data/src/core/ext/upbdefs-generated/google/api/expr/v1alpha1/checked.upbdefs.h +95 -0
  103. data/src/core/ext/upbdefs-generated/google/api/expr/v1alpha1/eval.upbdefs.c +58 -0
  104. data/src/core/ext/upbdefs-generated/google/api/expr/v1alpha1/eval.upbdefs.h +55 -0
  105. data/src/core/ext/upbdefs-generated/google/api/expr/v1alpha1/explain.upbdefs.c +44 -0
  106. data/src/core/ext/upbdefs-generated/google/api/expr/v1alpha1/explain.upbdefs.h +40 -0
  107. data/src/core/ext/upbdefs-generated/google/api/expr/v1alpha1/syntax.upbdefs.c +153 -0
  108. data/src/core/ext/upbdefs-generated/google/api/expr/v1alpha1/syntax.upbdefs.h +100 -0
  109. data/src/core/ext/upbdefs-generated/google/api/expr/v1alpha1/value.upbdefs.c +75 -0
  110. data/src/core/ext/upbdefs-generated/google/api/expr/v1alpha1/value.upbdefs.h +55 -0
  111. data/src/core/ext/xds/upb_utils.h +65 -0
  112. data/src/core/ext/xds/xds_api.cc +81 -3458
  113. data/src/core/ext/xds/xds_api.h +56 -611
  114. data/src/core/ext/xds/xds_bootstrap.cc +189 -125
  115. data/src/core/ext/xds/xds_bootstrap.h +20 -15
  116. data/src/core/ext/xds/xds_certificate_provider.h +1 -0
  117. data/src/core/ext/xds/xds_channel_creds.cc +108 -0
  118. data/src/core/ext/xds/xds_channel_creds.h +50 -0
  119. data/src/core/ext/xds/xds_client.cc +584 -994
  120. data/src/core/ext/xds/xds_client.h +78 -135
  121. data/src/core/ext/xds/xds_cluster.cc +451 -0
  122. data/src/core/ext/xds/xds_cluster.h +111 -0
  123. data/src/core/ext/xds/xds_common_types.cc +388 -0
  124. data/src/core/ext/xds/xds_common_types.h +110 -0
  125. data/src/core/ext/xds/xds_endpoint.cc +364 -0
  126. data/src/core/ext/xds/xds_endpoint.h +135 -0
  127. data/src/core/ext/xds/xds_http_filters.cc +5 -0
  128. data/src/core/ext/xds/xds_http_rbac_filter.cc +563 -0
  129. data/src/core/ext/xds/xds_http_rbac_filter.h +54 -0
  130. data/src/core/ext/xds/xds_listener.cc +1036 -0
  131. data/src/core/ext/xds/xds_listener.h +220 -0
  132. data/src/core/ext/{transport/chttp2/transport/hpack_utils.h → xds/xds_resource_type.cc} +12 -9
  133. data/src/core/ext/xds/xds_resource_type.h +98 -0
  134. data/src/core/ext/xds/xds_resource_type_impl.h +87 -0
  135. data/src/core/ext/xds/xds_route_config.cc +993 -0
  136. data/src/core/ext/xds/xds_route_config.h +215 -0
  137. data/src/core/ext/xds/xds_routing.cc +11 -8
  138. data/src/core/ext/xds/xds_routing.h +8 -5
  139. data/src/core/ext/xds/xds_server_config_fetcher.cc +159 -99
  140. data/src/core/lib/address_utils/parse_address.cc +20 -0
  141. data/src/core/lib/address_utils/parse_address.h +5 -0
  142. data/src/core/lib/address_utils/sockaddr_utils.cc +33 -36
  143. data/src/core/lib/address_utils/sockaddr_utils.h +1 -16
  144. data/src/core/lib/backoff/backoff.cc +4 -30
  145. data/src/core/lib/backoff/backoff.h +3 -3
  146. data/src/core/lib/channel/channel_args.cc +0 -1
  147. data/src/core/lib/channel/channel_stack.cc +8 -0
  148. data/src/core/lib/channel/channel_stack.h +1 -1
  149. data/src/core/lib/channel/channel_stack_builder.cc +5 -9
  150. data/src/core/lib/channel/channel_stack_builder.h +4 -7
  151. data/src/core/lib/channel/channelz.cc +1 -0
  152. data/src/core/lib/compression/compression.cc +19 -111
  153. data/src/core/lib/compression/compression_internal.cc +142 -202
  154. data/src/core/lib/compression/compression_internal.h +64 -69
  155. data/src/core/lib/compression/message_compress.cc +11 -11
  156. data/src/core/lib/compression/message_compress.h +2 -2
  157. data/src/core/lib/gpr/useful.h +4 -0
  158. data/src/core/lib/gprpp/bitset.h +7 -0
  159. data/src/core/lib/gprpp/chunked_vector.h +45 -3
  160. data/src/core/lib/gprpp/status_helper.cc +20 -28
  161. data/src/core/lib/gprpp/status_helper.h +6 -19
  162. data/src/core/lib/gprpp/table.h +11 -0
  163. data/src/core/lib/http/httpcli.cc +37 -46
  164. data/src/core/lib/http/httpcli.h +3 -15
  165. data/src/core/lib/iomgr/call_combiner.cc +15 -4
  166. data/src/core/lib/iomgr/closure.h +29 -9
  167. data/src/core/lib/iomgr/combiner.cc +25 -3
  168. data/src/core/lib/iomgr/error.cc +2 -0
  169. data/src/core/lib/iomgr/error.h +3 -0
  170. data/src/core/lib/iomgr/event_engine/iomgr.cc +3 -2
  171. data/src/core/lib/iomgr/event_engine/resolved_address_internal.cc +6 -0
  172. data/src/core/lib/iomgr/event_engine/resolved_address_internal.h +2 -0
  173. data/src/core/lib/iomgr/event_engine/resolver.cc +66 -48
  174. data/src/core/lib/iomgr/event_engine/resolver.h +56 -0
  175. data/src/core/lib/iomgr/exec_ctx.cc +22 -9
  176. data/src/core/lib/iomgr/executor.cc +10 -1
  177. data/src/core/lib/iomgr/fork_posix.cc +3 -2
  178. data/src/core/lib/iomgr/iomgr_custom.cc +4 -1
  179. data/src/core/lib/iomgr/iomgr_posix.cc +2 -2
  180. data/src/core/lib/iomgr/iomgr_posix_cfstream.cc +2 -2
  181. data/src/core/lib/iomgr/iomgr_windows.cc +2 -2
  182. data/src/core/lib/iomgr/port.h +2 -2
  183. data/src/core/lib/iomgr/resolve_address.cc +5 -24
  184. data/src/core/lib/iomgr/resolve_address.h +47 -44
  185. data/src/core/lib/iomgr/resolve_address_custom.cc +131 -109
  186. data/src/core/lib/iomgr/resolve_address_custom.h +101 -19
  187. data/src/core/lib/iomgr/resolve_address_impl.h +59 -0
  188. data/src/core/lib/iomgr/resolve_address_posix.cc +82 -66
  189. data/src/core/lib/iomgr/resolve_address_posix.h +47 -0
  190. data/src/core/lib/iomgr/resolve_address_windows.cc +93 -74
  191. data/src/core/lib/iomgr/resolve_address_windows.h +47 -0
  192. data/src/core/lib/iomgr/resolved_address.h +39 -0
  193. data/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +1 -0
  194. data/src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.cc +1 -0
  195. data/src/core/lib/iomgr/unix_sockets_posix.cc +22 -34
  196. data/src/core/lib/iomgr/unix_sockets_posix.h +4 -7
  197. data/src/core/lib/iomgr/unix_sockets_posix_noop.cc +6 -15
  198. data/src/core/lib/matchers/matchers.cc +1 -1
  199. data/src/core/lib/promise/activity.h +49 -20
  200. data/src/core/lib/promise/detail/status.h +5 -0
  201. data/src/core/{ext/filters/client_channel → lib/resolver}/resolver.cc +17 -25
  202. data/src/core/{ext/filters/client_channel → lib/resolver}/resolver.h +43 -44
  203. data/src/core/{ext/filters/client_channel → lib/resolver}/resolver_factory.h +10 -5
  204. data/src/core/{ext/filters/client_channel → lib/resolver}/resolver_registry.cc +3 -2
  205. data/src/core/{ext/filters/client_channel → lib/resolver}/resolver_registry.h +4 -5
  206. data/src/core/{ext/filters/client_channel → lib/resolver}/server_address.cc +1 -1
  207. data/src/core/{ext/filters/client_channel → lib/resolver}/server_address.h +4 -4
  208. data/src/core/lib/resource_quota/api.h +0 -1
  209. data/src/core/lib/{gprpp → resource_quota}/arena.cc +16 -13
  210. data/src/core/lib/{gprpp → resource_quota}/arena.h +24 -13
  211. data/src/core/lib/security/authorization/evaluate_args.cc +30 -15
  212. data/src/core/lib/security/authorization/evaluate_args.h +1 -0
  213. data/src/core/lib/security/authorization/grpc_authorization_engine.cc +60 -0
  214. data/src/core/lib/security/authorization/grpc_authorization_engine.h +62 -0
  215. data/src/core/lib/security/authorization/matchers.cc +227 -0
  216. data/src/core/lib/security/authorization/matchers.h +211 -0
  217. data/src/core/lib/security/authorization/rbac_policy.cc +442 -0
  218. data/src/core/lib/security/authorization/rbac_policy.h +170 -0
  219. data/src/core/lib/security/context/security_context.cc +4 -2
  220. data/src/core/lib/security/context/security_context.h +1 -1
  221. data/src/core/lib/security/credentials/composite/composite_credentials.cc +5 -5
  222. data/src/core/lib/security/credentials/composite/composite_credentials.h +4 -3
  223. data/src/core/lib/security/credentials/credentials.h +10 -20
  224. data/src/core/lib/security/credentials/external/aws_external_account_credentials.cc +6 -9
  225. data/src/core/lib/security/credentials/external/external_account_credentials.cc +7 -9
  226. data/src/core/lib/security/credentials/external/external_account_credentials.h +2 -7
  227. data/src/core/lib/security/credentials/external/url_external_account_credentials.cc +2 -3
  228. data/src/core/lib/security/credentials/fake/fake_credentials.cc +5 -4
  229. data/src/core/lib/security/credentials/fake/fake_credentials.h +8 -7
  230. data/src/core/lib/security/credentials/google_default/google_default_credentials.cc +2 -5
  231. data/src/core/lib/security/credentials/iam/iam_credentials.cc +16 -19
  232. data/src/core/lib/security/credentials/iam/iam_credentials.h +6 -5
  233. data/src/core/lib/security/credentials/jwt/json_token.cc +4 -6
  234. data/src/core/lib/security/credentials/jwt/jwt_credentials.cc +16 -28
  235. data/src/core/lib/security/credentials/jwt/jwt_credentials.h +8 -8
  236. data/src/core/lib/security/credentials/jwt/jwt_verifier.cc +6 -13
  237. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +44 -57
  238. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.h +13 -15
  239. data/src/core/lib/security/credentials/plugin/plugin_credentials.cc +6 -7
  240. data/src/core/lib/security/credentials/plugin/plugin_credentials.h +5 -4
  241. data/src/core/lib/security/credentials/ssl/ssl_credentials.cc +1 -10
  242. data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc +6 -0
  243. data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h +7 -0
  244. data/src/core/lib/security/credentials/xds/xds_credentials.h +1 -1
  245. data/src/core/lib/security/security_connector/security_connector.cc +0 -4
  246. data/src/core/lib/security/security_connector/security_connector.h +5 -1
  247. data/src/core/lib/security/security_connector/ssl_utils.cc +14 -24
  248. data/src/core/lib/security/security_connector/ssl_utils.h +5 -14
  249. data/src/core/lib/security/security_connector/tls/tls_security_connector.cc +2 -3
  250. data/src/core/lib/security/transport/auth_filters.h +7 -0
  251. data/src/core/lib/security/transport/client_auth_filter.cc +53 -33
  252. data/src/core/lib/security/transport/server_auth_filter.cc +40 -35
  253. data/src/core/{ext → lib}/service_config/service_config.cc +2 -2
  254. data/src/core/{ext → lib}/service_config/service_config.h +4 -4
  255. data/src/core/{ext → lib}/service_config/service_config_call_data.h +5 -5
  256. data/src/core/{ext → lib}/service_config/service_config_parser.cc +1 -1
  257. data/src/core/{ext → lib}/service_config/service_config_parser.h +3 -3
  258. data/src/core/lib/slice/slice.cc +3 -1
  259. data/src/core/lib/slice/slice.h +43 -13
  260. data/src/core/lib/slice/slice_intern.cc +3 -101
  261. data/src/core/lib/slice/slice_internal.h +1 -2
  262. data/src/core/lib/slice/slice_refcount.h +4 -13
  263. data/src/core/lib/slice/slice_refcount_base.h +0 -16
  264. data/src/core/lib/surface/call.cc +140 -382
  265. data/src/core/lib/surface/call.h +4 -4
  266. data/src/core/lib/surface/channel.cc +42 -44
  267. data/src/core/lib/surface/channel.h +4 -4
  268. data/src/core/lib/surface/init.cc +0 -2
  269. data/src/core/lib/surface/lame_client.cc +0 -1
  270. data/src/core/lib/surface/server.cc +12 -29
  271. data/src/core/lib/surface/server.h +2 -2
  272. data/src/core/lib/surface/version.cc +2 -2
  273. data/src/core/lib/transport/error_utils.h +14 -0
  274. data/src/core/lib/transport/metadata_batch.h +799 -717
  275. data/src/core/lib/transport/parsed_metadata.cc +2 -0
  276. data/src/core/lib/transport/parsed_metadata.h +95 -92
  277. data/src/core/lib/transport/timeout_encoding.cc +200 -66
  278. data/src/core/lib/transport/timeout_encoding.h +40 -10
  279. data/src/core/lib/transport/transport.h +1 -1
  280. data/src/core/lib/transport/transport_op_string.cc +6 -39
  281. data/src/core/lib/uri/uri_parser.cc +223 -53
  282. data/src/core/lib/uri/uri_parser.h +36 -23
  283. data/src/core/plugin_registry/grpc_plugin_registry.cc +4 -3
  284. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +1 -1
  285. data/src/core/tsi/ssl/session_cache/ssl_session.h +2 -4
  286. data/src/core/tsi/ssl/session_cache/ssl_session_cache.h +3 -5
  287. data/src/core/tsi/ssl_transport_security.cc +53 -13
  288. data/src/core/tsi/ssl_transport_security.h +18 -6
  289. data/src/ruby/ext/grpc/extconf.rb +10 -3
  290. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +2 -0
  291. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +3 -0
  292. data/src/ruby/lib/grpc/version.rb +1 -1
  293. data/src/ruby/pb/src/proto/grpc/testing/test_pb.rb +2 -1
  294. data/third_party/abseil-cpp/absl/base/internal/fast_type_id.h +48 -0
  295. data/third_party/abseil-cpp/absl/random/bernoulli_distribution.h +200 -0
  296. data/third_party/abseil-cpp/absl/random/beta_distribution.h +427 -0
  297. data/third_party/abseil-cpp/absl/random/discrete_distribution.cc +98 -0
  298. data/third_party/abseil-cpp/absl/random/discrete_distribution.h +247 -0
  299. data/third_party/abseil-cpp/absl/random/distributions.h +452 -0
  300. data/third_party/abseil-cpp/absl/random/exponential_distribution.h +165 -0
  301. data/third_party/abseil-cpp/absl/random/gaussian_distribution.cc +104 -0
  302. data/third_party/abseil-cpp/absl/random/gaussian_distribution.h +275 -0
  303. data/third_party/abseil-cpp/absl/random/internal/distribution_caller.h +92 -0
  304. data/third_party/abseil-cpp/absl/random/internal/fast_uniform_bits.h +268 -0
  305. data/third_party/abseil-cpp/absl/random/internal/fastmath.h +57 -0
  306. data/third_party/abseil-cpp/absl/random/internal/generate_real.h +144 -0
  307. data/third_party/abseil-cpp/absl/random/internal/iostream_state_saver.h +245 -0
  308. data/third_party/abseil-cpp/absl/random/internal/nonsecure_base.h +150 -0
  309. data/third_party/abseil-cpp/absl/random/internal/pcg_engine.h +308 -0
  310. data/third_party/abseil-cpp/absl/random/internal/platform.h +171 -0
  311. data/third_party/abseil-cpp/absl/random/internal/pool_urbg.cc +253 -0
  312. data/third_party/abseil-cpp/absl/random/internal/pool_urbg.h +131 -0
  313. data/third_party/abseil-cpp/absl/random/internal/randen.cc +91 -0
  314. data/third_party/abseil-cpp/absl/random/internal/randen.h +102 -0
  315. data/third_party/abseil-cpp/absl/random/internal/randen_detect.cc +221 -0
  316. data/third_party/abseil-cpp/absl/random/internal/randen_detect.h +33 -0
  317. data/third_party/abseil-cpp/absl/random/internal/randen_engine.h +239 -0
  318. data/third_party/abseil-cpp/absl/random/internal/randen_hwaes.cc +526 -0
  319. data/third_party/abseil-cpp/absl/random/internal/randen_hwaes.h +50 -0
  320. data/third_party/abseil-cpp/absl/random/internal/randen_round_keys.cc +462 -0
  321. data/third_party/abseil-cpp/absl/random/internal/randen_slow.cc +471 -0
  322. data/third_party/abseil-cpp/absl/random/internal/randen_slow.h +40 -0
  323. data/third_party/abseil-cpp/absl/random/internal/randen_traits.h +88 -0
  324. data/third_party/abseil-cpp/absl/random/internal/salted_seed_seq.h +167 -0
  325. data/third_party/abseil-cpp/absl/random/internal/seed_material.cc +267 -0
  326. data/third_party/abseil-cpp/absl/random/internal/seed_material.h +104 -0
  327. data/third_party/abseil-cpp/absl/random/internal/traits.h +101 -0
  328. data/third_party/abseil-cpp/absl/random/internal/uniform_helper.h +244 -0
  329. data/third_party/abseil-cpp/absl/random/internal/wide_multiply.h +111 -0
  330. data/third_party/abseil-cpp/absl/random/log_uniform_int_distribution.h +257 -0
  331. data/third_party/abseil-cpp/absl/random/poisson_distribution.h +258 -0
  332. data/third_party/abseil-cpp/absl/random/random.h +189 -0
  333. data/third_party/abseil-cpp/absl/random/seed_gen_exception.cc +46 -0
  334. data/third_party/abseil-cpp/absl/random/seed_gen_exception.h +55 -0
  335. data/third_party/abseil-cpp/absl/random/seed_sequences.cc +29 -0
  336. data/third_party/abseil-cpp/absl/random/seed_sequences.h +110 -0
  337. data/third_party/abseil-cpp/absl/random/uniform_int_distribution.h +275 -0
  338. data/third_party/abseil-cpp/absl/random/uniform_real_distribution.h +202 -0
  339. data/third_party/abseil-cpp/absl/random/zipf_distribution.h +271 -0
  340. data/third_party/boringssl-with-bazel/src/crypto/asn1/tasn_enc.c +1 -0
  341. data/third_party/boringssl-with-bazel/src/crypto/base64/base64.c +13 -0
  342. data/third_party/boringssl-with-bazel/src/crypto/dsa/dsa.c +21 -0
  343. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/cipher/cipher.c +12 -0
  344. data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/ecdsa/ecdsa.c +1 -2
  345. data/third_party/boringssl-with-bazel/src/crypto/hpke/hpke.c +2 -2
  346. data/third_party/boringssl-with-bazel/src/crypto/mem.c +1 -1
  347. data/third_party/boringssl-with-bazel/src/crypto/pkcs7/pkcs7.c +29 -0
  348. data/third_party/boringssl-with-bazel/src/crypto/pkcs8/internal.h +0 -1
  349. data/third_party/boringssl-with-bazel/src/crypto/pkcs8/pkcs8.c +1 -1
  350. data/third_party/boringssl-with-bazel/src/crypto/pkcs8/pkcs8_x509.c +1 -1
  351. data/third_party/boringssl-with-bazel/src/include/openssl/base64.h +8 -0
  352. data/third_party/boringssl-with-bazel/src/include/openssl/cipher.h +13 -1
  353. data/third_party/boringssl-with-bazel/src/include/openssl/dsa.h +10 -0
  354. data/third_party/boringssl-with-bazel/src/include/openssl/hpke.h +1 -1
  355. data/third_party/boringssl-with-bazel/src/include/openssl/pkcs7.h +9 -4
  356. data/third_party/boringssl-with-bazel/src/include/openssl/pkcs8.h +6 -1
  357. data/third_party/boringssl-with-bazel/src/include/openssl/ssl.h +23 -2
  358. data/third_party/boringssl-with-bazel/src/ssl/ssl_lib.cc +4 -0
  359. data/third_party/xxhash/xxhash.h +607 -352
  360. metadata +149 -77
  361. data/src/core/ext/transport/chttp2/transport/hpack_encoder_index.h +0 -107
  362. data/src/core/ext/transport/chttp2/transport/hpack_utils.cc +0 -46
  363. data/src/core/ext/transport/chttp2/transport/popularity_count.h +0 -60
  364. data/src/core/lib/compression/algorithm_metadata.h +0 -62
  365. data/src/core/lib/compression/compression_args.cc +0 -140
  366. data/src/core/lib/compression/compression_args.h +0 -58
  367. data/src/core/lib/compression/stream_compression.cc +0 -81
  368. data/src/core/lib/compression/stream_compression.h +0 -117
  369. data/src/core/lib/compression/stream_compression_gzip.cc +0 -231
  370. data/src/core/lib/compression/stream_compression_gzip.h +0 -28
  371. data/src/core/lib/compression/stream_compression_identity.cc +0 -91
  372. data/src/core/lib/compression/stream_compression_identity.h +0 -29
  373. data/src/core/lib/security/credentials/credentials_metadata.cc +0 -61
  374. data/src/core/lib/slice/static_slice.cc +0 -377
  375. data/src/core/lib/slice/static_slice.h +0 -300
  376. data/src/core/lib/transport/metadata.cc +0 -714
  377. data/src/core/lib/transport/metadata.h +0 -449
  378. data/src/core/lib/transport/metadata_batch.cc +0 -99
  379. data/src/core/lib/transport/static_metadata.cc +0 -1032
  380. data/src/core/lib/transport/static_metadata.h +0 -322
  381. data/src/core/lib/transport/status_metadata.cc +0 -63
  382. data/src/core/lib/transport/status_metadata.h +0 -48
@@ -121,29 +121,80 @@ extern "C" {
121
121
 
122
122
  /*
123
123
  * This part deals with the special case where a unit wants to inline xxHash,
124
- * but "xxhash.h" has previously been included without XXH_INLINE_ALL, such
125
- * as part of some previously included *.h header file.
124
+ * but "xxhash.h" has previously been included without XXH_INLINE_ALL,
125
+ * such as part of some previously included *.h header file.
126
126
  * Without further action, the new include would just be ignored,
127
127
  * and functions would effectively _not_ be inlined (silent failure).
128
128
  * The following macros solve this situation by prefixing all inlined names,
129
129
  * avoiding naming collision with previous inclusions.
130
130
  */
131
- # ifdef XXH_NAMESPACE
132
- # error "XXH_INLINE_ALL with XXH_NAMESPACE is not supported"
133
- /*
134
- * Note: Alternative: #undef all symbols (it's a pretty large list).
135
- * Without #error: it compiles, but functions are actually not inlined.
136
- */
137
- # endif
131
+ /* Before that, we unconditionally #undef all symbols,
132
+ * in case they were already defined with XXH_NAMESPACE.
133
+ * They will then be redefined for XXH_INLINE_ALL
134
+ */
135
+ # undef XXH_versionNumber
136
+ /* XXH32 */
137
+ # undef XXH32
138
+ # undef XXH32_createState
139
+ # undef XXH32_freeState
140
+ # undef XXH32_reset
141
+ # undef XXH32_update
142
+ # undef XXH32_digest
143
+ # undef XXH32_copyState
144
+ # undef XXH32_canonicalFromHash
145
+ # undef XXH32_hashFromCanonical
146
+ /* XXH64 */
147
+ # undef XXH64
148
+ # undef XXH64_createState
149
+ # undef XXH64_freeState
150
+ # undef XXH64_reset
151
+ # undef XXH64_update
152
+ # undef XXH64_digest
153
+ # undef XXH64_copyState
154
+ # undef XXH64_canonicalFromHash
155
+ # undef XXH64_hashFromCanonical
156
+ /* XXH3_64bits */
157
+ # undef XXH3_64bits
158
+ # undef XXH3_64bits_withSecret
159
+ # undef XXH3_64bits_withSeed
160
+ # undef XXH3_64bits_withSecretandSeed
161
+ # undef XXH3_createState
162
+ # undef XXH3_freeState
163
+ # undef XXH3_copyState
164
+ # undef XXH3_64bits_reset
165
+ # undef XXH3_64bits_reset_withSeed
166
+ # undef XXH3_64bits_reset_withSecret
167
+ # undef XXH3_64bits_update
168
+ # undef XXH3_64bits_digest
169
+ # undef XXH3_generateSecret
170
+ /* XXH3_128bits */
171
+ # undef XXH128
172
+ # undef XXH3_128bits
173
+ # undef XXH3_128bits_withSeed
174
+ # undef XXH3_128bits_withSecret
175
+ # undef XXH3_128bits_reset
176
+ # undef XXH3_128bits_reset_withSeed
177
+ # undef XXH3_128bits_reset_withSecret
178
+ # undef XXH3_128bits_reset_withSecretandSeed
179
+ # undef XXH3_128bits_update
180
+ # undef XXH3_128bits_digest
181
+ # undef XXH128_isEqual
182
+ # undef XXH128_cmp
183
+ # undef XXH128_canonicalFromHash
184
+ # undef XXH128_hashFromCanonical
185
+ /* Finally, free the namespace itself */
186
+ # undef XXH_NAMESPACE
187
+
188
+ /* employ the namespace for XXH_INLINE_ALL */
138
189
  # define XXH_NAMESPACE XXH_INLINE_
139
190
  /*
140
- * Some identifiers (enums, type names) are not symbols, but they must
141
- * still be renamed to avoid redeclaration.
191
+ * Some identifiers (enums, type names) are not symbols,
192
+ * but they must nonetheless be renamed to avoid redeclaration.
142
193
  * Alternative solution: do not redeclare them.
143
- * However, this requires some #ifdefs, and is a more dispersed action.
144
- * Meanwhile, renaming can be achieved in a single block
194
+ * However, this requires some #ifdefs, and has a more dispersed impact.
195
+ * Meanwhile, renaming can be achieved in a single place.
145
196
  */
146
- # define XXH_IPREF(Id) XXH_INLINE_ ## Id
197
+ # define XXH_IPREF(Id) XXH_NAMESPACE ## Id
147
198
  # define XXH_OK XXH_IPREF(XXH_OK)
148
199
  # define XXH_ERROR XXH_IPREF(XXH_ERROR)
149
200
  # define XXH_errorcode XXH_IPREF(XXH_errorcode)
@@ -235,23 +286,28 @@ extern "C" {
235
286
  # define XXH3_64bits XXH_NAME2(XXH_NAMESPACE, XXH3_64bits)
236
287
  # define XXH3_64bits_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_withSecret)
237
288
  # define XXH3_64bits_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_withSeed)
289
+ # define XXH3_64bits_withSecretandSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_withSecretandSeed)
238
290
  # define XXH3_createState XXH_NAME2(XXH_NAMESPACE, XXH3_createState)
239
291
  # define XXH3_freeState XXH_NAME2(XXH_NAMESPACE, XXH3_freeState)
240
292
  # define XXH3_copyState XXH_NAME2(XXH_NAMESPACE, XXH3_copyState)
241
293
  # define XXH3_64bits_reset XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset)
242
294
  # define XXH3_64bits_reset_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset_withSeed)
243
295
  # define XXH3_64bits_reset_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset_withSecret)
296
+ # define XXH3_64bits_reset_withSecretandSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset_withSecretandSeed)
244
297
  # define XXH3_64bits_update XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_update)
245
298
  # define XXH3_64bits_digest XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_digest)
246
299
  # define XXH3_generateSecret XXH_NAME2(XXH_NAMESPACE, XXH3_generateSecret)
300
+ # define XXH3_generateSecret_fromSeed XXH_NAME2(XXH_NAMESPACE, XXH3_generateSecret_fromSeed)
247
301
  /* XXH3_128bits */
248
302
  # define XXH128 XXH_NAME2(XXH_NAMESPACE, XXH128)
249
303
  # define XXH3_128bits XXH_NAME2(XXH_NAMESPACE, XXH3_128bits)
250
304
  # define XXH3_128bits_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_withSeed)
251
305
  # define XXH3_128bits_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_withSecret)
306
+ # define XXH3_128bits_withSecretandSeed XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_withSecretandSeed)
252
307
  # define XXH3_128bits_reset XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset)
253
308
  # define XXH3_128bits_reset_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset_withSeed)
254
309
  # define XXH3_128bits_reset_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset_withSecret)
310
+ # define XXH3_128bits_reset_withSecretandSeed XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset_withSecretandSeed)
255
311
  # define XXH3_128bits_update XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_update)
256
312
  # define XXH3_128bits_digest XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_digest)
257
313
  # define XXH128_isEqual XXH_NAME2(XXH_NAMESPACE, XXH128_isEqual)
@@ -272,16 +328,16 @@ extern "C" {
272
328
  /*!
273
329
  * @brief Obtains the xxHash version.
274
330
  *
275
- * This is only useful when xxHash is compiled as a shared library, as it is
276
- * independent of the version defined in the header.
331
+ * This is mostly useful when xxHash is compiled as a shared library,
332
+ * since the returned value comes from the library, as opposed to header file.
277
333
  *
278
- * @return `XXH_VERSION_NUMBER` as of when the libray was compiled.
334
+ * @return `XXH_VERSION_NUMBER` of the invoked library.
279
335
  */
280
336
  XXH_PUBLIC_API unsigned XXH_versionNumber (void);
281
337
 
282
338
 
283
339
  /* ****************************
284
- * Definitions
340
+ * Common basic types
285
341
  ******************************/
286
342
  #include <stddef.h> /* size_t */
287
343
  typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode;
@@ -297,11 +353,13 @@ typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode;
297
353
  * Not necessarily defined to `uint32_t` but functionally equivalent.
298
354
  */
299
355
  typedef uint32_t XXH32_hash_t;
356
+
300
357
  #elif !defined (__VMS) \
301
358
  && (defined (__cplusplus) \
302
359
  || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
303
360
  # include <stdint.h>
304
361
  typedef uint32_t XXH32_hash_t;
362
+
305
363
  #else
306
364
  # include <limits.h>
307
365
  # if UINT_MAX == 0xFFFFFFFFUL
@@ -323,10 +381,9 @@ typedef uint32_t XXH32_hash_t;
323
381
  * Contains functions used in the classic 32-bit xxHash algorithm.
324
382
  *
325
383
  * @note
326
- * XXH32 is considered rather weak by today's standards.
327
- * The @ref xxh3_family provides competitive speed for both 32-bit and 64-bit
328
- * systems, and offers true 64/128 bit hash results. It provides a superior
329
- * level of dispersion, and greatly reduces the risks of collisions.
384
+ * XXH32 is useful for older platforms, with no or poor 64-bit performance.
385
+ * Note that @ref xxh3_family provides competitive speed
386
+ * for both 32-bit and 64-bit systems, and offers true 64/128 bit hash results.
330
387
  *
331
388
  * @see @ref xxh64_family, @ref xxh3_family : Other xxHash families
332
389
  * @see @ref xxh32_impl for implementation details
@@ -543,6 +600,41 @@ XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t
543
600
  XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src);
544
601
 
545
602
 
603
+ #ifdef __has_attribute
604
+ # define XXH_HAS_ATTRIBUTE(x) __has_attribute(x)
605
+ #else
606
+ # define XXH_HAS_ATTRIBUTE(x) 0
607
+ #endif
608
+
609
+ /* C-language Attributes are added in C23. */
610
+ #if defined(__STDC_VERSION__) && (__STDC_VERSION__ > 201710L) && defined(__has_c_attribute)
611
+ # define XXH_HAS_C_ATTRIBUTE(x) __has_c_attribute(x)
612
+ #else
613
+ # define XXH_HAS_C_ATTRIBUTE(x) 0
614
+ #endif
615
+
616
+ #if defined(__cplusplus) && defined(__has_cpp_attribute)
617
+ # define XXH_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
618
+ #else
619
+ # define XXH_HAS_CPP_ATTRIBUTE(x) 0
620
+ #endif
621
+
622
+ /*
623
+ Define XXH_FALLTHROUGH macro for annotating switch case with the 'fallthrough' attribute
624
+ introduced in CPP17 and C23.
625
+ CPP17 : https://en.cppreference.com/w/cpp/language/attributes/fallthrough
626
+ C23 : https://en.cppreference.com/w/c/language/attributes/fallthrough
627
+ */
628
+ #if XXH_HAS_C_ATTRIBUTE(x)
629
+ # define XXH_FALLTHROUGH [[fallthrough]]
630
+ #elif XXH_HAS_CPP_ATTRIBUTE(x)
631
+ # define XXH_FALLTHROUGH [[fallthrough]]
632
+ #elif XXH_HAS_ATTRIBUTE(__fallthrough__)
633
+ # define XXH_FALLTHROUGH __attribute__ ((fallthrough))
634
+ #else
635
+ # define XXH_FALLTHROUGH
636
+ #endif
637
+
546
638
  /*!
547
639
  * @}
548
640
  * @ingroup public
@@ -586,8 +678,8 @@ typedef uint64_t XXH64_hash_t;
586
678
  *
587
679
  * @note
588
680
  * XXH3 provides competitive speed for both 32-bit and 64-bit systems,
589
- * and offers true 64/128 bit hash results. It provides a superior level of
590
- * dispersion, and greatly reduces the risks of collisions.
681
+ * and offers true 64/128 bit hash results.
682
+ * It provides better speed for systems with vector processing capabilities.
591
683
  */
592
684
 
593
685
 
@@ -713,13 +805,17 @@ XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSeed(const void* data, size_t len, X
713
805
  * It's possible to provide any blob of bytes as a "secret" to generate the hash.
714
806
  * This makes it more difficult for an external actor to prepare an intentional collision.
715
807
  * The main condition is that secretSize *must* be large enough (>= XXH3_SECRET_SIZE_MIN).
716
- * However, the quality of produced hash values depends on secret's entropy.
717
- * Technically, the secret must look like a bunch of random bytes.
808
+ * However, the quality of the secret impacts the dispersion of the hash algorithm.
809
+ * Therefore, the secret _must_ look like a bunch of random bytes.
718
810
  * Avoid "trivial" or structured data such as repeated sequences or a text document.
719
- * Whenever unsure about the "randomness" of the blob of bytes,
720
- * consider relabelling it as a "custom seed" instead,
721
- * and employ "XXH3_generateSecret()" (see below)
722
- * to generate a high entropy secret derived from the custom seed.
811
+ * Whenever in doubt about the "randomness" of the blob of bytes,
812
+ * consider employing "XXH3_generateSecret()" instead (see below).
813
+ * It will generate a proper high entropy secret derived from the blob of bytes.
814
+ * Another advantage of using XXH3_generateSecret() is that
815
+ * it guarantees that all bits within the initial blob of bytes
816
+ * will impact every bit of the output.
817
+ * This is not necessarily the case when using the blob of bytes directly
818
+ * because, when hashing _small_ inputs, only a portion of the secret is employed.
723
819
  */
724
820
  XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSecret(const void* data, size_t len, const void* secret, size_t secretSize);
725
821
 
@@ -879,10 +975,7 @@ XXH_PUBLIC_API XXH128_hash_t XXH128_hashFromCanonical(const XXH128_canonical_t*
879
975
  struct XXH32_state_s {
880
976
  XXH32_hash_t total_len_32; /*!< Total length hashed, modulo 2^32 */
881
977
  XXH32_hash_t large_len; /*!< Whether the hash is >= 16 (handles @ref total_len_32 overflow) */
882
- XXH32_hash_t v1; /*!< First accumulator lane */
883
- XXH32_hash_t v2; /*!< Second accumulator lane */
884
- XXH32_hash_t v3; /*!< Third accumulator lane */
885
- XXH32_hash_t v4; /*!< Fourth accumulator lane */
978
+ XXH32_hash_t v[4]; /*!< Accumulator lanes */
886
979
  XXH32_hash_t mem32[4]; /*!< Internal buffer for partial reads. Treated as unsigned char[16]. */
887
980
  XXH32_hash_t memsize; /*!< Amount of data in @ref mem32 */
888
981
  XXH32_hash_t reserved; /*!< Reserved field. Do not read or write to it, it may be removed. */
@@ -905,19 +998,19 @@ struct XXH32_state_s {
905
998
  */
906
999
  struct XXH64_state_s {
907
1000
  XXH64_hash_t total_len; /*!< Total length hashed. This is always 64-bit. */
908
- XXH64_hash_t v1; /*!< First accumulator lane */
909
- XXH64_hash_t v2; /*!< Second accumulator lane */
910
- XXH64_hash_t v3; /*!< Third accumulator lane */
911
- XXH64_hash_t v4; /*!< Fourth accumulator lane */
1001
+ XXH64_hash_t v[4]; /*!< Accumulator lanes */
912
1002
  XXH64_hash_t mem64[4]; /*!< Internal buffer for partial reads. Treated as unsigned char[32]. */
913
1003
  XXH32_hash_t memsize; /*!< Amount of data in @ref mem64 */
914
1004
  XXH32_hash_t reserved32; /*!< Reserved field, needed for padding anyways*/
915
1005
  XXH64_hash_t reserved64; /*!< Reserved field. Do not read or write to it, it may be removed. */
916
1006
  }; /* typedef'd to XXH64_state_t */
917
1007
 
918
- #if defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* C11+ */
1008
+ #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* >= C11 */
919
1009
  # include <stdalign.h>
920
1010
  # define XXH_ALIGN(n) alignas(n)
1011
+ #elif defined(__cplusplus) && (__cplusplus >= 201103L) /* >= C++11 */
1012
+ /* In C++ alignas() is a keyword */
1013
+ # define XXH_ALIGN(n) alignas(n)
921
1014
  #elif defined(__GNUC__)
922
1015
  # define XXH_ALIGN(n) __attribute__ ((aligned(n)))
923
1016
  #elif defined(_MSC_VER)
@@ -928,6 +1021,7 @@ struct XXH64_state_s {
928
1021
 
929
1022
  /* Old GCC versions only accept the attribute after the type in structures. */
930
1023
  #if !(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) /* C11+ */ \
1024
+ && ! (defined(__cplusplus) && (__cplusplus >= 201103L)) /* >= C++11 */ \
931
1025
  && defined(__GNUC__)
932
1026
  # define XXH_ALIGN_MEMBER(align, type) type XXH_ALIGN(align)
933
1027
  #else
@@ -957,16 +1051,18 @@ struct XXH64_state_s {
957
1051
  * @brief Structure for XXH3 streaming API.
958
1052
  *
959
1053
  * @note This is only defined when @ref XXH_STATIC_LINKING_ONLY,
960
- * @ref XXH_INLINE_ALL, or @ref XXH_IMPLEMENTATION is defined. Otherwise it is
961
- * an opaque type. This allows fields to safely be changed.
1054
+ * @ref XXH_INLINE_ALL, or @ref XXH_IMPLEMENTATION is defined.
1055
+ * Otherwise it is an opaque type.
1056
+ * Never use this definition in combination with dynamic library.
1057
+ * This allows fields to safely be changed in the future.
962
1058
  *
963
- * @note **This structure has a strict alignment requirement of 64 bytes.** Do
964
- * not allocate this with `malloc()` or `new`, it will not be sufficiently
965
- * aligned. Use @ref XXH3_createState() and @ref XXH3_freeState(), or stack
966
- * allocation.
1059
+ * @note ** This structure has a strict alignment requirement of 64 bytes!! **
1060
+ * Do not allocate this with `malloc()` or `new`,
1061
+ * it will not be sufficiently aligned.
1062
+ * Use @ref XXH3_createState() and @ref XXH3_freeState(), or stack allocation.
967
1063
  *
968
1064
  * Typedef'd to @ref XXH3_state_t.
969
- * Do not access the members of this struct directly.
1065
+ * Do never access the members of this struct directly.
970
1066
  *
971
1067
  * @see XXH3_INITSTATE() for stack initialization.
972
1068
  * @see XXH3_createState(), XXH3_freeState().
@@ -981,7 +1077,7 @@ struct XXH3_state_s {
981
1077
  /*!< The internal buffer. @see XXH32_state_s::mem32 */
982
1078
  XXH32_hash_t bufferedSize;
983
1079
  /*!< The amount of memory in @ref buffer, @see XXH32_state_s::memsize */
984
- XXH32_hash_t reserved32;
1080
+ XXH32_hash_t useSeed;
985
1081
  /*!< Reserved field. Needed for padding on 64-bit. */
986
1082
  size_t nbStripesSoFar;
987
1083
  /*!< Number or stripes processed. */
@@ -1017,6 +1113,12 @@ struct XXH3_state_s {
1017
1113
  #define XXH3_INITSTATE(XXH3_state_ptr) { (XXH3_state_ptr)->seed = 0; }
1018
1114
 
1019
1115
 
1116
+ /* XXH128() :
1117
+ * simple alias to pre-selected XXH3_128bits variant
1118
+ */
1119
+ XXH_PUBLIC_API XXH128_hash_t XXH128(const void* data, size_t len, XXH64_hash_t seed);
1120
+
1121
+
1020
1122
  /* === Experimental API === */
1021
1123
  /* Symbols defined below must be considered tied to a specific library version. */
1022
1124
 
@@ -1029,31 +1131,89 @@ struct XXH3_state_s {
1029
1131
  * as it becomes much more difficult for an external actor to guess how to impact the calculation logic.
1030
1132
  *
1031
1133
  * The function accepts as input a custom seed of any length and any content,
1032
- * and derives from it a high-entropy secret of length XXH3_SECRET_DEFAULT_SIZE
1033
- * into an already allocated buffer secretBuffer.
1034
- * The generated secret is _always_ XXH_SECRET_DEFAULT_SIZE bytes long.
1134
+ * and derives from it a high-entropy secret of length @secretSize
1135
+ * into an already allocated buffer @secretBuffer.
1136
+ * @secretSize must be >= XXH3_SECRET_SIZE_MIN
1035
1137
  *
1036
1138
  * The generated secret can then be used with any `*_withSecret()` variant.
1037
1139
  * Functions `XXH3_128bits_withSecret()`, `XXH3_64bits_withSecret()`,
1038
1140
  * `XXH3_128bits_reset_withSecret()` and `XXH3_64bits_reset_withSecret()`
1039
1141
  * are part of this list. They all accept a `secret` parameter
1040
- * which must be very long for implementation reasons (>= XXH3_SECRET_SIZE_MIN)
1142
+ * which must be large enough for implementation reasons (>= XXH3_SECRET_SIZE_MIN)
1041
1143
  * _and_ feature very high entropy (consist of random-looking bytes).
1042
1144
  * These conditions can be a high bar to meet, so
1043
- * this function can be used to generate a secret of proper quality.
1145
+ * XXH3_generateSecret() can be employed to ensure proper quality.
1044
1146
  *
1045
1147
  * customSeed can be anything. It can have any size, even small ones,
1046
- * and its content can be anything, even stupidly "low entropy" source such as a bunch of zeroes.
1047
- * The resulting `secret` will nonetheless provide all expected qualities.
1148
+ * and its content can be anything, even "poor entropy" sources such as a bunch of zeroes.
1149
+ * The resulting `secret` will nonetheless provide all required qualities.
1048
1150
  *
1049
- * Supplying NULL as the customSeed copies the default secret into `secretBuffer`.
1050
1151
  * When customSeedSize > 0, supplying NULL as customSeed is undefined behavior.
1051
1152
  */
1052
- XXH_PUBLIC_API void XXH3_generateSecret(void* secretBuffer, const void* customSeed, size_t customSeedSize);
1153
+ XXH_PUBLIC_API XXH_errorcode XXH3_generateSecret(void* secretBuffer, size_t secretSize, const void* customSeed, size_t customSeedSize);
1053
1154
 
1054
1155
 
1055
- /* simple short-cut to pre-selected XXH3_128bits variant */
1056
- XXH_PUBLIC_API XXH128_hash_t XXH128(const void* data, size_t len, XXH64_hash_t seed);
1156
+ /*
1157
+ * XXH3_generateSecret_fromSeed():
1158
+ *
1159
+ * Generate the same secret as the _withSeed() variants.
1160
+ *
1161
+ * The resulting secret has a length of XXH3_SECRET_DEFAULT_SIZE (necessarily).
1162
+ * @secretBuffer must be already allocated, of size at least XXH3_SECRET_DEFAULT_SIZE bytes.
1163
+ *
1164
+ * The generated secret can be used in combination with
1165
+ *`*_withSecret()` and `_withSecretandSeed()` variants.
1166
+ * This generator is notably useful in combination with `_withSecretandSeed()`,
1167
+ * as a way to emulate a faster `_withSeed()` variant.
1168
+ */
1169
+ XXH_PUBLIC_API void XXH3_generateSecret_fromSeed(void* secretBuffer, XXH64_hash_t seed);
1170
+
1171
+ /*
1172
+ * *_withSecretandSeed() :
1173
+ * These variants generate hash values using either
1174
+ * @seed for "short" keys (< XXH3_MIDSIZE_MAX = 240 bytes)
1175
+ * or @secret for "large" keys (>= XXH3_MIDSIZE_MAX).
1176
+ *
1177
+ * This generally benefits speed, compared to `_withSeed()` or `_withSecret()`.
1178
+ * `_withSeed()` has to generate the secret on the fly for "large" keys.
1179
+ * It's fast, but can be perceptible for "not so large" keys (< 1 KB).
1180
+ * `_withSecret()` has to generate the masks on the fly for "small" keys,
1181
+ * which requires more instructions than _withSeed() variants.
1182
+ * Therefore, _withSecretandSeed variant combines the best of both worlds.
1183
+ *
1184
+ * When @secret has been generated by XXH3_generateSecret_fromSeed(),
1185
+ * this variant produces *exactly* the same results as `_withSeed()` variant,
1186
+ * hence offering only a pure speed benefit on "large" input,
1187
+ * by skipping the need to regenerate the secret for every large input.
1188
+ *
1189
+ * Another usage scenario is to hash the secret to a 64-bit hash value,
1190
+ * for example with XXH3_64bits(), which then becomes the seed,
1191
+ * and then employ both the seed and the secret in _withSecretandSeed().
1192
+ * On top of speed, an added benefit is that each bit in the secret
1193
+ * has a 50% chance to swap each bit in the output,
1194
+ * via its impact to the seed.
1195
+ * This is not guaranteed when using the secret directly in "small data" scenarios,
1196
+ * because only portions of the secret are employed for small data.
1197
+ */
1198
+ XXH_PUBLIC_API XXH64_hash_t
1199
+ XXH3_64bits_withSecretandSeed(const void* data, size_t len,
1200
+ const void* secret, size_t secretSize,
1201
+ XXH64_hash_t seed);
1202
+
1203
+ XXH_PUBLIC_API XXH128_hash_t
1204
+ XXH3_128bits_withSecretandSeed(const void* data, size_t len,
1205
+ const void* secret, size_t secretSize,
1206
+ XXH64_hash_t seed64);
1207
+
1208
+ XXH_PUBLIC_API XXH_errorcode
1209
+ XXH3_64bits_reset_withSecretandSeed(XXH3_state_t* statePtr,
1210
+ const void* secret, size_t secretSize,
1211
+ XXH64_hash_t seed64);
1212
+
1213
+ XXH_PUBLIC_API XXH_errorcode
1214
+ XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr,
1215
+ const void* secret, size_t secretSize,
1216
+ XXH64_hash_t seed64);
1057
1217
 
1058
1218
 
1059
1219
  #endif /* XXH_NO_LONG_LONG */
@@ -1159,22 +1319,12 @@ XXH_PUBLIC_API XXH128_hash_t XXH128(const void* data, size_t len, XXH64_hash_t s
1159
1319
  * care, as what works on one compiler/platform/optimization level may cause
1160
1320
  * another to read garbage data or even crash.
1161
1321
  *
1162
- * See https://stackoverflow.com/a/32095106/646947 for details.
1322
+ * See http://fastcompression.blogspot.com/2015/08/accessing-unaligned-memory.html for details.
1163
1323
  *
1164
1324
  * Prefer these methods in priority order (0 > 3 > 1 > 2)
1165
1325
  */
1166
1326
  # define XXH_FORCE_MEMORY_ACCESS 0
1167
- /*!
1168
- * @def XXH_ACCEPT_NULL_INPUT_POINTER
1169
- * @brief Whether to add explicit `NULL` checks.
1170
- *
1171
- * If the input pointer is `NULL` and the length is non-zero, xxHash's default
1172
- * behavior is to dereference it, triggering a segfault.
1173
- *
1174
- * When this macro is enabled, xxHash actively checks the input for a null pointer.
1175
- * If it is, the result for null input pointers is the same as a zero-length input.
1176
- */
1177
- # define XXH_ACCEPT_NULL_INPUT_POINTER 0
1327
+
1178
1328
  /*!
1179
1329
  * @def XXH_FORCE_ALIGN_CHECK
1180
1330
  * @brief If defined to non-zero, adds a special path for aligned inputs (XXH32()
@@ -1226,18 +1376,16 @@ XXH_PUBLIC_API XXH128_hash_t XXH128(const void* data, size_t len, XXH64_hash_t s
1226
1376
  # define XXH_NO_INLINE_HINTS 0
1227
1377
 
1228
1378
  /*!
1229
- * @def XXH_REROLL
1230
- * @brief Whether to reroll `XXH32_finalize` and `XXH64_finalize`.
1231
- *
1232
- * For performance, `XXH32_finalize` and `XXH64_finalize` use an unrolled loop
1233
- * in the form of a switch statement.
1379
+ * @def XXH32_ENDJMP
1380
+ * @brief Whether to use a jump for `XXH32_finalize`.
1234
1381
  *
1235
- * This is not always desirable, as it generates larger code, and depending on
1236
- * the architecture, may even be slower
1382
+ * For performance, `XXH32_finalize` uses multiple branches in the finalizer.
1383
+ * This is generally preferable for performance,
1384
+ * but depending on exact architecture, a jmp may be preferable.
1237
1385
  *
1238
- * This is automatically defined with `-Os`/`-Oz` on GCC and Clang.
1386
+ * This setting is only possibly making a difference for very small inputs.
1239
1387
  */
1240
- # define XXH_REROLL 0
1388
+ # define XXH32_ENDJMP 0
1241
1389
 
1242
1390
  /*!
1243
1391
  * @internal
@@ -1254,18 +1402,25 @@ XXH_PUBLIC_API XXH128_hash_t XXH128(const void* data, size_t len, XXH64_hash_t s
1254
1402
  */
1255
1403
 
1256
1404
  #ifndef XXH_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */
1257
- /* prefer __packed__ structures (method 1) for gcc on armv7 and armv8 */
1258
- # if !defined(__clang__) && ( \
1405
+ /* prefer __packed__ structures (method 1) for gcc on armv7+ and mips */
1406
+ # if !defined(__clang__) && \
1407
+ ( \
1259
1408
  (defined(__INTEL_COMPILER) && !defined(_WIN32)) || \
1260
- (defined(__GNUC__) && (defined(__ARM_ARCH) && __ARM_ARCH >= 7)) )
1409
+ ( \
1410
+ defined(__GNUC__) && ( \
1411
+ (defined(__ARM_ARCH) && __ARM_ARCH >= 7) || \
1412
+ ( \
1413
+ defined(__mips__) && \
1414
+ (__mips <= 5 || __mips_isa_rev < 6) && \
1415
+ (!defined(__mips16) || defined(__mips_mips16e2)) \
1416
+ ) \
1417
+ ) \
1418
+ ) \
1419
+ )
1261
1420
  # define XXH_FORCE_MEMORY_ACCESS 1
1262
1421
  # endif
1263
1422
  #endif
1264
1423
 
1265
- #ifndef XXH_ACCEPT_NULL_INPUT_POINTER /* can be defined externally */
1266
- # define XXH_ACCEPT_NULL_INPUT_POINTER 0
1267
- #endif
1268
-
1269
1424
  #ifndef XXH_FORCE_ALIGN_CHECK /* can be defined externally */
1270
1425
  # if defined(__i386) || defined(__x86_64__) || defined(__aarch64__) \
1271
1426
  || defined(_M_IX86) || defined(_M_X64) || defined(_M_ARM64) /* visual */
@@ -1284,12 +1439,9 @@ XXH_PUBLIC_API XXH128_hash_t XXH128(const void* data, size_t len, XXH64_hash_t s
1284
1439
  # endif
1285
1440
  #endif
1286
1441
 
1287
- #ifndef XXH_REROLL
1288
- # if defined(__OPTIMIZE_SIZE__)
1289
- # define XXH_REROLL 1
1290
- # else
1291
- # define XXH_REROLL 0
1292
- # endif
1442
+ #ifndef XXH32_ENDJMP
1443
+ /* generally preferable for performance */
1444
+ # define XXH32_ENDJMP 0
1293
1445
  #endif
1294
1446
 
1295
1447
  /*!
@@ -1341,19 +1493,19 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size)
1341
1493
  #endif
1342
1494
 
1343
1495
  #if XXH_NO_INLINE_HINTS /* disable inlining hints */
1344
- # if defined(__GNUC__)
1496
+ # if defined(__GNUC__) || defined(__clang__)
1345
1497
  # define XXH_FORCE_INLINE static __attribute__((unused))
1346
1498
  # else
1347
1499
  # define XXH_FORCE_INLINE static
1348
1500
  # endif
1349
1501
  # define XXH_NO_INLINE static
1350
1502
  /* enable inlining hints */
1503
+ #elif defined(__GNUC__) || defined(__clang__)
1504
+ # define XXH_FORCE_INLINE static __inline__ __attribute__((always_inline, unused))
1505
+ # define XXH_NO_INLINE static __attribute__((noinline))
1351
1506
  #elif defined(_MSC_VER) /* Visual Studio */
1352
1507
  # define XXH_FORCE_INLINE static __forceinline
1353
1508
  # define XXH_NO_INLINE static __declspec(noinline)
1354
- #elif defined(__GNUC__)
1355
- # define XXH_FORCE_INLINE static __inline__ __attribute__((always_inline, unused))
1356
- # define XXH_NO_INLINE static __attribute__((noinline))
1357
1509
  #elif defined (__cplusplus) \
1358
1510
  || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) /* C99 */
1359
1511
  # define XXH_FORCE_INLINE static inline
@@ -1392,7 +1544,17 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size)
1392
1544
  #endif
1393
1545
 
1394
1546
  /* note: use after variable declarations */
1395
- #define XXH_STATIC_ASSERT(c) do { enum { XXH_sa = 1/(int)(!!(c)) }; } while (0)
1547
+ #ifndef XXH_STATIC_ASSERT
1548
+ # if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* C11 */
1549
+ # include <assert.h>
1550
+ # define XXH_STATIC_ASSERT_WITH_MESSAGE(c,m) do { static_assert((c),m); } while(0)
1551
+ # elif defined(__cplusplus) && (__cplusplus >= 201103L) /* C++11 */
1552
+ # define XXH_STATIC_ASSERT_WITH_MESSAGE(c,m) do { static_assert((c),m); } while(0)
1553
+ # else
1554
+ # define XXH_STATIC_ASSERT_WITH_MESSAGE(c,m) do { struct xxh_sa { char x[(c) ? 1 : -1]; }; } while(0)
1555
+ # endif
1556
+ # define XXH_STATIC_ASSERT(c) XXH_STATIC_ASSERT_WITH_MESSAGE((c),#c)
1557
+ #endif
1396
1558
 
1397
1559
  /*!
1398
1560
  * @internal
@@ -1410,7 +1572,7 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size)
1410
1572
  * We also use it to prevent unwanted constant folding for AArch64 in
1411
1573
  * XXH3_initCustomSecret_scalar().
1412
1574
  */
1413
- #ifdef __GNUC__
1575
+ #if defined(__GNUC__) || defined(__clang__)
1414
1576
  # define XXH_COMPILER_GUARD(var) __asm__ __volatile__("" : "+r" (var))
1415
1577
  #else
1416
1578
  # define XXH_COMPILER_GUARD(var) ((void)0)
@@ -1521,12 +1683,12 @@ static xxh_u32 XXH_read32(const void* ptr)
1521
1683
 
1522
1684
  /*
1523
1685
  * Portable and safe solution. Generally efficient.
1524
- * see: https://stackoverflow.com/a/32095106/646947
1686
+ * see: http://fastcompression.blogspot.com/2015/08/accessing-unaligned-memory.html
1525
1687
  */
1526
1688
  static xxh_u32 XXH_read32(const void* memPtr)
1527
1689
  {
1528
1690
  xxh_u32 val;
1529
- memcpy(&val, memPtr, sizeof(val));
1691
+ XXH_memcpy(&val, memPtr, sizeof(val));
1530
1692
  return val;
1531
1693
  }
1532
1694
 
@@ -1534,7 +1696,6 @@ static xxh_u32 XXH_read32(const void* memPtr)
1534
1696
 
1535
1697
 
1536
1698
  /* *** Endianness *** */
1537
- typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess;
1538
1699
 
1539
1700
  /*!
1540
1701
  * @ingroup tuning
@@ -1544,8 +1705,8 @@ typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess;
1544
1705
  * Defined to 1 if the target is little endian, or 0 if it is big endian.
1545
1706
  * It can be defined externally, for example on the compiler command line.
1546
1707
  *
1547
- * If it is not defined, a runtime check (which is usually constant folded)
1548
- * is used instead.
1708
+ * If it is not defined,
1709
+ * a runtime check (which is usually constant folded) is used instead.
1549
1710
  *
1550
1711
  * @note
1551
1712
  * This is not necessarily defined to an integer constant.
@@ -1844,8 +2005,10 @@ XXH32_finalize(xxh_u32 h32, const xxh_u8* ptr, size_t len, XXH_alignment align)
1844
2005
  h32 = XXH_rotl32(h32, 17) * XXH_PRIME32_4; \
1845
2006
  } while (0)
1846
2007
 
1847
- /* Compact rerolled version */
1848
- if (XXH_REROLL) {
2008
+ if (ptr==NULL) XXH_ASSERT(len == 0);
2009
+
2010
+ /* Compact rerolled version; generally faster */
2011
+ if (!XXH32_ENDJMP) {
1849
2012
  len &= 15;
1850
2013
  while (len >= 4) {
1851
2014
  XXH_PROCESS4;
@@ -1859,41 +2022,41 @@ XXH32_finalize(xxh_u32 h32, const xxh_u8* ptr, size_t len, XXH_alignment align)
1859
2022
  } else {
1860
2023
  switch(len&15) /* or switch(bEnd - p) */ {
1861
2024
  case 12: XXH_PROCESS4;
1862
- /* fallthrough */
2025
+ XXH_FALLTHROUGH;
1863
2026
  case 8: XXH_PROCESS4;
1864
- /* fallthrough */
2027
+ XXH_FALLTHROUGH;
1865
2028
  case 4: XXH_PROCESS4;
1866
2029
  return XXH32_avalanche(h32);
1867
2030
 
1868
2031
  case 13: XXH_PROCESS4;
1869
- /* fallthrough */
2032
+ XXH_FALLTHROUGH;
1870
2033
  case 9: XXH_PROCESS4;
1871
- /* fallthrough */
2034
+ XXH_FALLTHROUGH;
1872
2035
  case 5: XXH_PROCESS4;
1873
2036
  XXH_PROCESS1;
1874
2037
  return XXH32_avalanche(h32);
1875
2038
 
1876
2039
  case 14: XXH_PROCESS4;
1877
- /* fallthrough */
2040
+ XXH_FALLTHROUGH;
1878
2041
  case 10: XXH_PROCESS4;
1879
- /* fallthrough */
2042
+ XXH_FALLTHROUGH;
1880
2043
  case 6: XXH_PROCESS4;
1881
2044
  XXH_PROCESS1;
1882
2045
  XXH_PROCESS1;
1883
2046
  return XXH32_avalanche(h32);
1884
2047
 
1885
2048
  case 15: XXH_PROCESS4;
1886
- /* fallthrough */
2049
+ XXH_FALLTHROUGH;
1887
2050
  case 11: XXH_PROCESS4;
1888
- /* fallthrough */
2051
+ XXH_FALLTHROUGH;
1889
2052
  case 7: XXH_PROCESS4;
1890
- /* fallthrough */
2053
+ XXH_FALLTHROUGH;
1891
2054
  case 3: XXH_PROCESS1;
1892
- /* fallthrough */
2055
+ XXH_FALLTHROUGH;
1893
2056
  case 2: XXH_PROCESS1;
1894
- /* fallthrough */
2057
+ XXH_FALLTHROUGH;
1895
2058
  case 1: XXH_PROCESS1;
1896
- /* fallthrough */
2059
+ XXH_FALLTHROUGH;
1897
2060
  case 0: return XXH32_avalanche(h32);
1898
2061
  }
1899
2062
  XXH_ASSERT(0);
@@ -1913,24 +2076,19 @@ XXH32_finalize(xxh_u32 h32, const xxh_u8* ptr, size_t len, XXH_alignment align)
1913
2076
  * @internal
1914
2077
  * @brief The implementation for @ref XXH32().
1915
2078
  *
1916
- * @param input, len, seed Directly passed from @ref XXH32().
2079
+ * @param input , len , seed Directly passed from @ref XXH32().
1917
2080
  * @param align Whether @p input is aligned.
1918
2081
  * @return The calculated hash.
1919
2082
  */
1920
2083
  XXH_FORCE_INLINE xxh_u32
1921
2084
  XXH32_endian_align(const xxh_u8* input, size_t len, xxh_u32 seed, XXH_alignment align)
1922
2085
  {
1923
- const xxh_u8* bEnd = input ? input + len : NULL;
1924
2086
  xxh_u32 h32;
1925
2087
 
1926
- #if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1)
1927
- if (input==NULL) {
1928
- len=0;
1929
- bEnd=input=(const xxh_u8*)(size_t)16;
1930
- }
1931
- #endif
2088
+ if (input==NULL) XXH_ASSERT(len == 0);
1932
2089
 
1933
2090
  if (len>=16) {
2091
+ const xxh_u8* const bEnd = input + len;
1934
2092
  const xxh_u8* const limit = bEnd - 15;
1935
2093
  xxh_u32 v1 = seed + XXH_PRIME32_1 + XXH_PRIME32_2;
1936
2094
  xxh_u32 v2 = seed + XXH_PRIME32_2;
@@ -1994,7 +2152,7 @@ XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr)
1994
2152
  /*! @ingroup xxh32_family */
1995
2153
  XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dstState, const XXH32_state_t* srcState)
1996
2154
  {
1997
- memcpy(dstState, srcState, sizeof(*dstState));
2155
+ XXH_memcpy(dstState, srcState, sizeof(*dstState));
1998
2156
  }
1999
2157
 
2000
2158
  /*! @ingroup xxh32_family */
@@ -2002,12 +2160,12 @@ XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, XXH32_hash_t s
2002
2160
  {
2003
2161
  XXH32_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */
2004
2162
  memset(&state, 0, sizeof(state));
2005
- state.v1 = seed + XXH_PRIME32_1 + XXH_PRIME32_2;
2006
- state.v2 = seed + XXH_PRIME32_2;
2007
- state.v3 = seed + 0;
2008
- state.v4 = seed - XXH_PRIME32_1;
2163
+ state.v[0] = seed + XXH_PRIME32_1 + XXH_PRIME32_2;
2164
+ state.v[1] = seed + XXH_PRIME32_2;
2165
+ state.v[2] = seed + 0;
2166
+ state.v[3] = seed - XXH_PRIME32_1;
2009
2167
  /* do not write into reserved, planned to be removed in a future version */
2010
- memcpy(statePtr, &state, sizeof(state) - sizeof(state.reserved));
2168
+ XXH_memcpy(statePtr, &state, sizeof(state) - sizeof(state.reserved));
2011
2169
  return XXH_OK;
2012
2170
  }
2013
2171
 
@@ -2016,12 +2174,10 @@ XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, XXH32_hash_t s
2016
2174
  XXH_PUBLIC_API XXH_errorcode
2017
2175
  XXH32_update(XXH32_state_t* state, const void* input, size_t len)
2018
2176
  {
2019
- if (input==NULL)
2020
- #if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1)
2177
+ if (input==NULL) {
2178
+ XXH_ASSERT(len == 0);
2021
2179
  return XXH_OK;
2022
- #else
2023
- return XXH_ERROR;
2024
- #endif
2180
+ }
2025
2181
 
2026
2182
  { const xxh_u8* p = (const xxh_u8*)input;
2027
2183
  const xxh_u8* const bEnd = p + len;
@@ -2038,10 +2194,10 @@ XXH32_update(XXH32_state_t* state, const void* input, size_t len)
2038
2194
  if (state->memsize) { /* some data left from previous update */
2039
2195
  XXH_memcpy((xxh_u8*)(state->mem32) + state->memsize, input, 16-state->memsize);
2040
2196
  { const xxh_u32* p32 = state->mem32;
2041
- state->v1 = XXH32_round(state->v1, XXH_readLE32(p32)); p32++;
2042
- state->v2 = XXH32_round(state->v2, XXH_readLE32(p32)); p32++;
2043
- state->v3 = XXH32_round(state->v3, XXH_readLE32(p32)); p32++;
2044
- state->v4 = XXH32_round(state->v4, XXH_readLE32(p32));
2197
+ state->v[0] = XXH32_round(state->v[0], XXH_readLE32(p32)); p32++;
2198
+ state->v[1] = XXH32_round(state->v[1], XXH_readLE32(p32)); p32++;
2199
+ state->v[2] = XXH32_round(state->v[2], XXH_readLE32(p32)); p32++;
2200
+ state->v[3] = XXH32_round(state->v[3], XXH_readLE32(p32));
2045
2201
  }
2046
2202
  p += 16-state->memsize;
2047
2203
  state->memsize = 0;
@@ -2049,22 +2205,14 @@ XXH32_update(XXH32_state_t* state, const void* input, size_t len)
2049
2205
 
2050
2206
  if (p <= bEnd-16) {
2051
2207
  const xxh_u8* const limit = bEnd - 16;
2052
- xxh_u32 v1 = state->v1;
2053
- xxh_u32 v2 = state->v2;
2054
- xxh_u32 v3 = state->v3;
2055
- xxh_u32 v4 = state->v4;
2056
2208
 
2057
2209
  do {
2058
- v1 = XXH32_round(v1, XXH_readLE32(p)); p+=4;
2059
- v2 = XXH32_round(v2, XXH_readLE32(p)); p+=4;
2060
- v3 = XXH32_round(v3, XXH_readLE32(p)); p+=4;
2061
- v4 = XXH32_round(v4, XXH_readLE32(p)); p+=4;
2210
+ state->v[0] = XXH32_round(state->v[0], XXH_readLE32(p)); p+=4;
2211
+ state->v[1] = XXH32_round(state->v[1], XXH_readLE32(p)); p+=4;
2212
+ state->v[2] = XXH32_round(state->v[2], XXH_readLE32(p)); p+=4;
2213
+ state->v[3] = XXH32_round(state->v[3], XXH_readLE32(p)); p+=4;
2062
2214
  } while (p<=limit);
2063
2215
 
2064
- state->v1 = v1;
2065
- state->v2 = v2;
2066
- state->v3 = v3;
2067
- state->v4 = v4;
2068
2216
  }
2069
2217
 
2070
2218
  if (p < bEnd) {
@@ -2083,12 +2231,12 @@ XXH_PUBLIC_API XXH32_hash_t XXH32_digest(const XXH32_state_t* state)
2083
2231
  xxh_u32 h32;
2084
2232
 
2085
2233
  if (state->large_len) {
2086
- h32 = XXH_rotl32(state->v1, 1)
2087
- + XXH_rotl32(state->v2, 7)
2088
- + XXH_rotl32(state->v3, 12)
2089
- + XXH_rotl32(state->v4, 18);
2234
+ h32 = XXH_rotl32(state->v[0], 1)
2235
+ + XXH_rotl32(state->v[1], 7)
2236
+ + XXH_rotl32(state->v[2], 12)
2237
+ + XXH_rotl32(state->v[3], 18);
2090
2238
  } else {
2091
- h32 = state->v3 /* == seed */ + XXH_PRIME32_5;
2239
+ h32 = state->v[2] /* == seed */ + XXH_PRIME32_5;
2092
2240
  }
2093
2241
 
2094
2242
  h32 += state->total_len_32;
@@ -2117,7 +2265,7 @@ XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t
2117
2265
  {
2118
2266
  XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t));
2119
2267
  if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash);
2120
- memcpy(dst, &hash, sizeof(*dst));
2268
+ XXH_memcpy(dst, &hash, sizeof(*dst));
2121
2269
  }
2122
2270
  /*! @ingroup xxh32_family */
2123
2271
  XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src)
@@ -2178,12 +2326,12 @@ static xxh_u64 XXH_read64(const void* ptr)
2178
2326
 
2179
2327
  /*
2180
2328
  * Portable and safe solution. Generally efficient.
2181
- * see: https://stackoverflow.com/a/32095106/646947
2329
+ * see: http://fastcompression.blogspot.com/2015/08/accessing-unaligned-memory.html
2182
2330
  */
2183
2331
  static xxh_u64 XXH_read64(const void* memPtr)
2184
2332
  {
2185
2333
  xxh_u64 val;
2186
- memcpy(&val, memPtr, sizeof(val));
2334
+ XXH_memcpy(&val, memPtr, sizeof(val));
2187
2335
  return val;
2188
2336
  }
2189
2337
 
@@ -2313,6 +2461,7 @@ static xxh_u64 XXH64_avalanche(xxh_u64 h64)
2313
2461
  static xxh_u64
2314
2462
  XXH64_finalize(xxh_u64 h64, const xxh_u8* ptr, size_t len, XXH_alignment align)
2315
2463
  {
2464
+ if (ptr==NULL) XXH_ASSERT(len == 0);
2316
2465
  len &= 31;
2317
2466
  while (len >= 8) {
2318
2467
  xxh_u64 const k1 = XXH64_round(0, XXH_get64bits(ptr));
@@ -2348,18 +2497,12 @@ XXH64_finalize(xxh_u64 h64, const xxh_u8* ptr, size_t len, XXH_alignment align)
2348
2497
  XXH_FORCE_INLINE xxh_u64
2349
2498
  XXH64_endian_align(const xxh_u8* input, size_t len, xxh_u64 seed, XXH_alignment align)
2350
2499
  {
2351
- const xxh_u8* bEnd = input ? input + len : NULL;
2352
2500
  xxh_u64 h64;
2353
-
2354
- #if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1)
2355
- if (input==NULL) {
2356
- len=0;
2357
- bEnd=input=(const xxh_u8*)(size_t)32;
2358
- }
2359
- #endif
2501
+ if (input==NULL) XXH_ASSERT(len == 0);
2360
2502
 
2361
2503
  if (len>=32) {
2362
- const xxh_u8* const limit = bEnd - 32;
2504
+ const xxh_u8* const bEnd = input + len;
2505
+ const xxh_u8* const limit = bEnd - 31;
2363
2506
  xxh_u64 v1 = seed + XXH_PRIME64_1 + XXH_PRIME64_2;
2364
2507
  xxh_u64 v2 = seed + XXH_PRIME64_2;
2365
2508
  xxh_u64 v3 = seed + 0;
@@ -2370,7 +2513,7 @@ XXH64_endian_align(const xxh_u8* input, size_t len, xxh_u64 seed, XXH_alignment
2370
2513
  v2 = XXH64_round(v2, XXH_get64bits(input)); input+=8;
2371
2514
  v3 = XXH64_round(v3, XXH_get64bits(input)); input+=8;
2372
2515
  v4 = XXH64_round(v4, XXH_get64bits(input)); input+=8;
2373
- } while (input<=limit);
2516
+ } while (input<limit);
2374
2517
 
2375
2518
  h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
2376
2519
  h64 = XXH64_mergeRound(h64, v1);
@@ -2425,7 +2568,7 @@ XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr)
2425
2568
  /*! @ingroup xxh64_family */
2426
2569
  XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dstState, const XXH64_state_t* srcState)
2427
2570
  {
2428
- memcpy(dstState, srcState, sizeof(*dstState));
2571
+ XXH_memcpy(dstState, srcState, sizeof(*dstState));
2429
2572
  }
2430
2573
 
2431
2574
  /*! @ingroup xxh64_family */
@@ -2433,12 +2576,12 @@ XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, XXH64_hash_t s
2433
2576
  {
2434
2577
  XXH64_state_t state; /* use a local state to memcpy() in order to avoid strict-aliasing warnings */
2435
2578
  memset(&state, 0, sizeof(state));
2436
- state.v1 = seed + XXH_PRIME64_1 + XXH_PRIME64_2;
2437
- state.v2 = seed + XXH_PRIME64_2;
2438
- state.v3 = seed + 0;
2439
- state.v4 = seed - XXH_PRIME64_1;
2579
+ state.v[0] = seed + XXH_PRIME64_1 + XXH_PRIME64_2;
2580
+ state.v[1] = seed + XXH_PRIME64_2;
2581
+ state.v[2] = seed + 0;
2582
+ state.v[3] = seed - XXH_PRIME64_1;
2440
2583
  /* do not write into reserved64, might be removed in a future version */
2441
- memcpy(statePtr, &state, sizeof(state) - sizeof(state.reserved64));
2584
+ XXH_memcpy(statePtr, &state, sizeof(state) - sizeof(state.reserved64));
2442
2585
  return XXH_OK;
2443
2586
  }
2444
2587
 
@@ -2446,12 +2589,10 @@ XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, XXH64_hash_t s
2446
2589
  XXH_PUBLIC_API XXH_errorcode
2447
2590
  XXH64_update (XXH64_state_t* state, const void* input, size_t len)
2448
2591
  {
2449
- if (input==NULL)
2450
- #if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1)
2592
+ if (input==NULL) {
2593
+ XXH_ASSERT(len == 0);
2451
2594
  return XXH_OK;
2452
- #else
2453
- return XXH_ERROR;
2454
- #endif
2595
+ }
2455
2596
 
2456
2597
  { const xxh_u8* p = (const xxh_u8*)input;
2457
2598
  const xxh_u8* const bEnd = p + len;
@@ -2466,32 +2607,24 @@ XXH64_update (XXH64_state_t* state, const void* input, size_t len)
2466
2607
 
2467
2608
  if (state->memsize) { /* tmp buffer is full */
2468
2609
  XXH_memcpy(((xxh_u8*)state->mem64) + state->memsize, input, 32-state->memsize);
2469
- state->v1 = XXH64_round(state->v1, XXH_readLE64(state->mem64+0));
2470
- state->v2 = XXH64_round(state->v2, XXH_readLE64(state->mem64+1));
2471
- state->v3 = XXH64_round(state->v3, XXH_readLE64(state->mem64+2));
2472
- state->v4 = XXH64_round(state->v4, XXH_readLE64(state->mem64+3));
2610
+ state->v[0] = XXH64_round(state->v[0], XXH_readLE64(state->mem64+0));
2611
+ state->v[1] = XXH64_round(state->v[1], XXH_readLE64(state->mem64+1));
2612
+ state->v[2] = XXH64_round(state->v[2], XXH_readLE64(state->mem64+2));
2613
+ state->v[3] = XXH64_round(state->v[3], XXH_readLE64(state->mem64+3));
2473
2614
  p += 32 - state->memsize;
2474
2615
  state->memsize = 0;
2475
2616
  }
2476
2617
 
2477
2618
  if (p+32 <= bEnd) {
2478
2619
  const xxh_u8* const limit = bEnd - 32;
2479
- xxh_u64 v1 = state->v1;
2480
- xxh_u64 v2 = state->v2;
2481
- xxh_u64 v3 = state->v3;
2482
- xxh_u64 v4 = state->v4;
2483
2620
 
2484
2621
  do {
2485
- v1 = XXH64_round(v1, XXH_readLE64(p)); p+=8;
2486
- v2 = XXH64_round(v2, XXH_readLE64(p)); p+=8;
2487
- v3 = XXH64_round(v3, XXH_readLE64(p)); p+=8;
2488
- v4 = XXH64_round(v4, XXH_readLE64(p)); p+=8;
2622
+ state->v[0] = XXH64_round(state->v[0], XXH_readLE64(p)); p+=8;
2623
+ state->v[1] = XXH64_round(state->v[1], XXH_readLE64(p)); p+=8;
2624
+ state->v[2] = XXH64_round(state->v[2], XXH_readLE64(p)); p+=8;
2625
+ state->v[3] = XXH64_round(state->v[3], XXH_readLE64(p)); p+=8;
2489
2626
  } while (p<=limit);
2490
2627
 
2491
- state->v1 = v1;
2492
- state->v2 = v2;
2493
- state->v3 = v3;
2494
- state->v4 = v4;
2495
2628
  }
2496
2629
 
2497
2630
  if (p < bEnd) {
@@ -2510,18 +2643,13 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_digest(const XXH64_state_t* state)
2510
2643
  xxh_u64 h64;
2511
2644
 
2512
2645
  if (state->total_len >= 32) {
2513
- xxh_u64 const v1 = state->v1;
2514
- xxh_u64 const v2 = state->v2;
2515
- xxh_u64 const v3 = state->v3;
2516
- xxh_u64 const v4 = state->v4;
2517
-
2518
- h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
2519
- h64 = XXH64_mergeRound(h64, v1);
2520
- h64 = XXH64_mergeRound(h64, v2);
2521
- h64 = XXH64_mergeRound(h64, v3);
2522
- h64 = XXH64_mergeRound(h64, v4);
2646
+ h64 = XXH_rotl64(state->v[0], 1) + XXH_rotl64(state->v[1], 7) + XXH_rotl64(state->v[2], 12) + XXH_rotl64(state->v[3], 18);
2647
+ h64 = XXH64_mergeRound(h64, state->v[0]);
2648
+ h64 = XXH64_mergeRound(h64, state->v[1]);
2649
+ h64 = XXH64_mergeRound(h64, state->v[2]);
2650
+ h64 = XXH64_mergeRound(h64, state->v[3]);
2523
2651
  } else {
2524
- h64 = state->v3 /*seed*/ + XXH_PRIME64_5;
2652
+ h64 = state->v[2] /*seed*/ + XXH_PRIME64_5;
2525
2653
  }
2526
2654
 
2527
2655
  h64 += (xxh_u64) state->total_len;
@@ -2537,7 +2665,7 @@ XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t
2537
2665
  {
2538
2666
  XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t));
2539
2667
  if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap64(hash);
2540
- memcpy(dst, &hash, sizeof(*dst));
2668
+ XXH_memcpy(dst, &hash, sizeof(*dst));
2541
2669
  }
2542
2670
 
2543
2671
  /*! @ingroup xxh64_family */
@@ -2734,10 +2862,13 @@ enum XXH_VECTOR_TYPE /* fake enum */ {
2734
2862
  # define XXH_VECTOR XXH_AVX2
2735
2863
  # elif defined(__SSE2__) || defined(_M_AMD64) || defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP == 2))
2736
2864
  # define XXH_VECTOR XXH_SSE2
2737
- # elif defined(__GNUC__) /* msvc support maybe later */ \
2738
- && (defined(__ARM_NEON__) || defined(__ARM_NEON)) \
2739
- && (defined(__LITTLE_ENDIAN__) /* We only support little endian NEON */ \
2740
- || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
2865
+ # elif ( \
2866
+ defined(__ARM_NEON__) || defined(__ARM_NEON) /* gcc */ \
2867
+ || defined(_M_ARM64) || defined(_M_ARM_ARMV7VE) /* msvc */ \
2868
+ ) && ( \
2869
+ defined(_WIN32) || defined(__LITTLE_ENDIAN__) /* little endian only */ \
2870
+ || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) \
2871
+ )
2741
2872
  # define XXH_VECTOR XXH_NEON
2742
2873
  # elif (defined(__PPC64__) && defined(__POWER8_VECTOR__)) \
2743
2874
  || (defined(__s390x__) && defined(__VEC__)) \
@@ -2889,7 +3020,7 @@ enum XXH_VECTOR_TYPE /* fake enum */ {
2889
3020
  */
2890
3021
  # if !defined(XXH_NO_VZIP_HACK) /* define to disable */ \
2891
3022
  && defined(__GNUC__) \
2892
- && !defined(__aarch64__) && !defined(__arm64__)
3023
+ && !defined(__aarch64__) && !defined(__arm64__) && !defined(_M_ARM64)
2893
3024
  # define XXH_SPLIT_IN_PLACE(in, outLo, outHi) \
2894
3025
  do { \
2895
3026
  /* Undocumented GCC/Clang operand modifier: %e0 = lower D half, %f0 = upper D half */ \
@@ -2972,7 +3103,7 @@ XXH_FORCE_INLINE xxh_u64x2 XXH_vec_revb(xxh_u64x2 val)
2972
3103
  XXH_FORCE_INLINE xxh_u64x2 XXH_vec_loadu(const void *ptr)
2973
3104
  {
2974
3105
  xxh_u64x2 ret;
2975
- memcpy(&ret, ptr, sizeof(xxh_u64x2));
3106
+ XXH_memcpy(&ret, ptr, sizeof(xxh_u64x2));
2976
3107
  # if XXH_VSX_BE
2977
3108
  ret = XXH_vec_revb(ret);
2978
3109
  # endif
@@ -3101,7 +3232,7 @@ XXH_mult32to64(xxh_u64 x, xxh_u64 y)
3101
3232
  * Uses `__uint128_t` and `_umul128` if available, otherwise uses a scalar
3102
3233
  * version.
3103
3234
  *
3104
- * @param lhs, rhs The 64-bit integers to be multiplied
3235
+ * @param lhs , rhs The 64-bit integers to be multiplied
3105
3236
  * @return The 128-bit result represented in an @ref XXH128_hash_t.
3106
3237
  */
3107
3238
  static XXH128_hash_t
@@ -3151,6 +3282,21 @@ XXH_mult64to128(xxh_u64 lhs, xxh_u64 rhs)
3151
3282
  r128.high64 = product_high;
3152
3283
  return r128;
3153
3284
 
3285
+ /*
3286
+ * MSVC for ARM64's __umulh method.
3287
+ *
3288
+ * This compiles to the same MUL + UMULH as GCC/Clang's __uint128_t method.
3289
+ */
3290
+ #elif defined(_M_ARM64)
3291
+
3292
+ #ifndef _MSC_VER
3293
+ # pragma intrinsic(__umulh)
3294
+ #endif
3295
+ XXH128_hash_t r128;
3296
+ r128.low64 = lhs * rhs;
3297
+ r128.high64 = __umulh(lhs, rhs);
3298
+ return r128;
3299
+
3154
3300
  #else
3155
3301
  /*
3156
3302
  * Portable scalar method. Optimized for 32-bit and 64-bit ALUs.
@@ -3219,7 +3365,7 @@ XXH_mult64to128(xxh_u64 lhs, xxh_u64 rhs)
3219
3365
  * The reason for the separate function is to prevent passing too many structs
3220
3366
  * around by value. This will hopefully inline the multiply, but we don't force it.
3221
3367
  *
3222
- * @param lhs, rhs The 64-bit integers to multiply
3368
+ * @param lhs , rhs The 64-bit integers to multiply
3223
3369
  * @return The low 64 bits of the product XOR'd by the high 64 bits.
3224
3370
  * @see XXH_mult64to128()
3225
3371
  */
@@ -3521,7 +3667,7 @@ XXH3_len_129to240_64b(const xxh_u8* XXH_RESTRICT input, size_t len,
3521
3667
  XXH_FORCE_INLINE void XXH_writeLE64(void* dst, xxh_u64 v64)
3522
3668
  {
3523
3669
  if (!XXH_CPU_LITTLE_ENDIAN) v64 = XXH_swap64(v64);
3524
- memcpy(dst, &v64, sizeof(v64));
3670
+ XXH_memcpy(dst, &v64, sizeof(v64));
3525
3671
  }
3526
3672
 
3527
3673
  /* Several intrinsic functions below are supposed to accept __int64 as argument,
@@ -3573,7 +3719,7 @@ XXH3_accumulate_512_avx512(void* XXH_RESTRICT acc,
3573
3719
  const void* XXH_RESTRICT input,
3574
3720
  const void* XXH_RESTRICT secret)
3575
3721
  {
3576
- XXH_ALIGN(64) __m512i* const xacc = (__m512i *) acc;
3722
+ __m512i* const xacc = (__m512i *) acc;
3577
3723
  XXH_ASSERT((((size_t)acc) & 63) == 0);
3578
3724
  XXH_STATIC_ASSERT(XXH_STRIPE_LEN == sizeof(__m512i));
3579
3725
 
@@ -3622,7 +3768,7 @@ XXH3_scrambleAcc_avx512(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret)
3622
3768
  {
3623
3769
  XXH_ASSERT((((size_t)acc) & 63) == 0);
3624
3770
  XXH_STATIC_ASSERT(XXH_STRIPE_LEN == sizeof(__m512i));
3625
- { XXH_ALIGN(64) __m512i* const xacc = (__m512i*) acc;
3771
+ { __m512i* const xacc = (__m512i*) acc;
3626
3772
  const __m512i prime32 = _mm512_set1_epi32((int)XXH_PRIME32_1);
3627
3773
 
3628
3774
  /* xacc[0] ^= (xacc[0] >> 47) */
@@ -3649,17 +3795,19 @@ XXH3_initCustomSecret_avx512(void* XXH_RESTRICT customSecret, xxh_u64 seed64)
3649
3795
  XXH_ASSERT(((size_t)customSecret & 63) == 0);
3650
3796
  (void)(&XXH_writeLE64);
3651
3797
  { int const nbRounds = XXH_SECRET_DEFAULT_SIZE / sizeof(__m512i);
3652
- __m512i const seed = _mm512_mask_set1_epi64(_mm512_set1_epi64((xxh_i64)seed64), 0xAA, -(xxh_i64)seed64);
3798
+ __m512i const seed = _mm512_mask_set1_epi64(_mm512_set1_epi64((xxh_i64)seed64), 0xAA, (xxh_i64)(0U - seed64));
3653
3799
 
3654
- XXH_ALIGN(64) const __m512i* const src = (const __m512i*) XXH3_kSecret;
3655
- XXH_ALIGN(64) __m512i* const dest = ( __m512i*) customSecret;
3800
+ const __m512i* const src = (const __m512i*) ((const void*) XXH3_kSecret);
3801
+ __m512i* const dest = ( __m512i*) customSecret;
3656
3802
  int i;
3803
+ XXH_ASSERT(((size_t)src & 63) == 0); /* control alignment */
3804
+ XXH_ASSERT(((size_t)dest & 63) == 0);
3657
3805
  for (i=0; i < nbRounds; ++i) {
3658
3806
  /* GCC has a bug, _mm512_stream_load_si512 accepts 'void*', not 'void const*',
3659
- * this will warn "discards const qualifier". */
3807
+ * this will warn "discards 'const' qualifier". */
3660
3808
  union {
3661
- XXH_ALIGN(64) const __m512i* cp;
3662
- XXH_ALIGN(64) void* p;
3809
+ const __m512i* cp;
3810
+ void* p;
3663
3811
  } remote_const_void;
3664
3812
  remote_const_void.cp = src + i;
3665
3813
  dest[i] = _mm512_add_epi64(_mm512_stream_load_si512(remote_const_void.p), seed);
@@ -3681,7 +3829,7 @@ XXH3_accumulate_512_avx2( void* XXH_RESTRICT acc,
3681
3829
  const void* XXH_RESTRICT secret)
3682
3830
  {
3683
3831
  XXH_ASSERT((((size_t)acc) & 31) == 0);
3684
- { XXH_ALIGN(32) __m256i* const xacc = (__m256i *) acc;
3832
+ { __m256i* const xacc = (__m256i *) acc;
3685
3833
  /* Unaligned. This is mainly for pointer arithmetic, and because
3686
3834
  * _mm256_loadu_si256 requires a const __m256i * pointer for some reason. */
3687
3835
  const __m256i* const xinput = (const __m256i *) input;
@@ -3713,7 +3861,7 @@ XXH_FORCE_INLINE XXH_TARGET_AVX2 void
3713
3861
  XXH3_scrambleAcc_avx2(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret)
3714
3862
  {
3715
3863
  XXH_ASSERT((((size_t)acc) & 31) == 0);
3716
- { XXH_ALIGN(32) __m256i* const xacc = (__m256i*) acc;
3864
+ { __m256i* const xacc = (__m256i*) acc;
3717
3865
  /* Unaligned. This is mainly for pointer arithmetic, and because
3718
3866
  * _mm256_loadu_si256 requires a const __m256i * pointer for some reason. */
3719
3867
  const __m256i* const xsecret = (const __m256i *) secret;
@@ -3745,10 +3893,10 @@ XXH_FORCE_INLINE XXH_TARGET_AVX2 void XXH3_initCustomSecret_avx2(void* XXH_RESTR
3745
3893
  XXH_STATIC_ASSERT(XXH_SEC_ALIGN <= 64);
3746
3894
  (void)(&XXH_writeLE64);
3747
3895
  XXH_PREFETCH(customSecret);
3748
- { __m256i const seed = _mm256_set_epi64x(-(xxh_i64)seed64, (xxh_i64)seed64, -(xxh_i64)seed64, (xxh_i64)seed64);
3896
+ { __m256i const seed = _mm256_set_epi64x((xxh_i64)(0U - seed64), (xxh_i64)seed64, (xxh_i64)(0U - seed64), (xxh_i64)seed64);
3749
3897
 
3750
- XXH_ALIGN(64) const __m256i* const src = (const __m256i*) XXH3_kSecret;
3751
- XXH_ALIGN(64) __m256i* dest = ( __m256i*) customSecret;
3898
+ const __m256i* const src = (const __m256i*) ((const void*) XXH3_kSecret);
3899
+ __m256i* dest = ( __m256i*) customSecret;
3752
3900
 
3753
3901
  # if defined(__GNUC__) || defined(__clang__)
3754
3902
  /*
@@ -3758,6 +3906,8 @@ XXH_FORCE_INLINE XXH_TARGET_AVX2 void XXH3_initCustomSecret_avx2(void* XXH_RESTR
3758
3906
  */
3759
3907
  XXH_COMPILER_GUARD(dest);
3760
3908
  # endif
3909
+ XXH_ASSERT(((size_t)src & 31) == 0); /* control alignment */
3910
+ XXH_ASSERT(((size_t)dest & 31) == 0);
3761
3911
 
3762
3912
  /* GCC -O2 need unroll loop manually */
3763
3913
  dest[0] = _mm256_add_epi64(_mm256_stream_load_si256(src+0), seed);
@@ -3785,7 +3935,7 @@ XXH3_accumulate_512_sse2( void* XXH_RESTRICT acc,
3785
3935
  {
3786
3936
  /* SSE2 is just a half-scale version of the AVX2 version. */
3787
3937
  XXH_ASSERT((((size_t)acc) & 15) == 0);
3788
- { XXH_ALIGN(16) __m128i* const xacc = (__m128i *) acc;
3938
+ { __m128i* const xacc = (__m128i *) acc;
3789
3939
  /* Unaligned. This is mainly for pointer arithmetic, and because
3790
3940
  * _mm_loadu_si128 requires a const __m128i * pointer for some reason. */
3791
3941
  const __m128i* const xinput = (const __m128i *) input;
@@ -3817,7 +3967,7 @@ XXH_FORCE_INLINE XXH_TARGET_SSE2 void
3817
3967
  XXH3_scrambleAcc_sse2(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret)
3818
3968
  {
3819
3969
  XXH_ASSERT((((size_t)acc) & 15) == 0);
3820
- { XXH_ALIGN(16) __m128i* const xacc = (__m128i*) acc;
3970
+ { __m128i* const xacc = (__m128i*) acc;
3821
3971
  /* Unaligned. This is mainly for pointer arithmetic, and because
3822
3972
  * _mm_loadu_si128 requires a const __m128i * pointer for some reason. */
3823
3973
  const __m128i* const xsecret = (const __m128i *) secret;
@@ -3849,27 +3999,29 @@ XXH_FORCE_INLINE XXH_TARGET_SSE2 void XXH3_initCustomSecret_sse2(void* XXH_RESTR
3849
3999
  { int const nbRounds = XXH_SECRET_DEFAULT_SIZE / sizeof(__m128i);
3850
4000
 
3851
4001
  # if defined(_MSC_VER) && defined(_M_IX86) && _MSC_VER < 1900
3852
- // MSVC 32bit mode does not support _mm_set_epi64x before 2015
3853
- XXH_ALIGN(16) const xxh_i64 seed64x2[2] = { (xxh_i64)seed64, -(xxh_i64)seed64 };
4002
+ /* MSVC 32bit mode does not support _mm_set_epi64x before 2015 */
4003
+ XXH_ALIGN(16) const xxh_i64 seed64x2[2] = { (xxh_i64)seed64, (xxh_i64)(0U - seed64) };
3854
4004
  __m128i const seed = _mm_load_si128((__m128i const*)seed64x2);
3855
4005
  # else
3856
- __m128i const seed = _mm_set_epi64x(-(xxh_i64)seed64, (xxh_i64)seed64);
4006
+ __m128i const seed = _mm_set_epi64x((xxh_i64)(0U - seed64), (xxh_i64)seed64);
3857
4007
  # endif
3858
4008
  int i;
3859
4009
 
3860
- XXH_ALIGN(64) const float* const src = (float const*) XXH3_kSecret;
3861
- XXH_ALIGN(XXH_SEC_ALIGN) __m128i* dest = (__m128i*) customSecret;
4010
+ const void* const src16 = XXH3_kSecret;
4011
+ __m128i* dst16 = (__m128i*) customSecret;
3862
4012
  # if defined(__GNUC__) || defined(__clang__)
3863
4013
  /*
3864
4014
  * On GCC & Clang, marking 'dest' as modified will cause the compiler:
3865
4015
  * - do not extract the secret from sse registers in the internal loop
3866
4016
  * - use less common registers, and avoid pushing these reg into stack
3867
4017
  */
3868
- XXH_COMPILER_GUARD(dest);
4018
+ XXH_COMPILER_GUARD(dst16);
3869
4019
  # endif
4020
+ XXH_ASSERT(((size_t)src16 & 15) == 0); /* control alignment */
4021
+ XXH_ASSERT(((size_t)dst16 & 15) == 0);
3870
4022
 
3871
4023
  for (i=0; i < nbRounds; ++i) {
3872
- dest[i] = _mm_add_epi64(_mm_castps_si128(_mm_load_ps(src+i*4)), seed);
4024
+ dst16[i] = _mm_add_epi64(_mm_load_si128((const __m128i *)src16+i), seed);
3873
4025
  } }
3874
4026
  }
3875
4027
 
@@ -3884,7 +4036,7 @@ XXH3_accumulate_512_neon( void* XXH_RESTRICT acc,
3884
4036
  {
3885
4037
  XXH_ASSERT((((size_t)acc) & 15) == 0);
3886
4038
  {
3887
- XXH_ALIGN(16) uint64x2_t* const xacc = (uint64x2_t *) acc;
4039
+ uint64x2_t* const xacc = (uint64x2_t *) acc;
3888
4040
  /* We don't use a uint32x4_t pointer because it causes bus errors on ARMv7. */
3889
4041
  uint8_t const* const xinput = (const uint8_t *) input;
3890
4042
  uint8_t const* const xsecret = (const uint8_t *) secret;
@@ -3931,8 +4083,8 @@ XXH3_scrambleAcc_neon(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret)
3931
4083
  uint64x2_t data_vec = veorq_u64 (acc_vec, shifted);
3932
4084
 
3933
4085
  /* xacc[i] ^= xsecret[i]; */
3934
- uint8x16_t key_vec = vld1q_u8(xsecret + (i * 16));
3935
- uint64x2_t data_key = veorq_u64(data_vec, vreinterpretq_u64_u8(key_vec));
4086
+ uint8x16_t key_vec = vld1q_u8 (xsecret + (i * 16));
4087
+ uint64x2_t data_key = veorq_u64 (data_vec, vreinterpretq_u64_u8(key_vec));
3936
4088
 
3937
4089
  /* xacc[i] *= XXH_PRIME32_1 */
3938
4090
  uint32x2_t data_key_lo, data_key_hi;
@@ -3976,7 +4128,8 @@ XXH3_accumulate_512_vsx( void* XXH_RESTRICT acc,
3976
4128
  const void* XXH_RESTRICT input,
3977
4129
  const void* XXH_RESTRICT secret)
3978
4130
  {
3979
- xxh_u64x2* const xacc = (xxh_u64x2*) acc; /* presumed aligned */
4131
+ /* presumed aligned */
4132
+ unsigned long long* const xacc = (unsigned long long*) acc;
3980
4133
  xxh_u64x2 const* const xinput = (xxh_u64x2 const*) input; /* no alignment restriction */
3981
4134
  xxh_u64x2 const* const xsecret = (xxh_u64x2 const*) secret; /* no alignment restriction */
3982
4135
  xxh_u64x2 const v32 = { 32, 32 };
@@ -3991,14 +4144,18 @@ XXH3_accumulate_512_vsx( void* XXH_RESTRICT acc,
3991
4144
  xxh_u32x4 const shuffled = (xxh_u32x4)vec_rl(data_key, v32);
3992
4145
  /* product = ((xxh_u64x2)data_key & 0xFFFFFFFF) * ((xxh_u64x2)shuffled & 0xFFFFFFFF); */
3993
4146
  xxh_u64x2 const product = XXH_vec_mulo((xxh_u32x4)data_key, shuffled);
3994
- xacc[i] += product;
4147
+ /* acc_vec = xacc[i]; */
4148
+ xxh_u64x2 acc_vec = vec_xl(0, xacc + 2 * i);
4149
+ acc_vec += product;
3995
4150
 
3996
4151
  /* swap high and low halves */
3997
4152
  #ifdef __s390x__
3998
- xacc[i] += vec_permi(data_vec, data_vec, 2);
4153
+ acc_vec += vec_permi(data_vec, data_vec, 2);
3999
4154
  #else
4000
- xacc[i] += vec_xxpermdi(data_vec, data_vec, 2);
4155
+ acc_vec += vec_xxpermdi(data_vec, data_vec, 2);
4001
4156
  #endif
4157
+ /* xacc[i] = acc_vec; */
4158
+ vec_xst(acc_vec, 0, xacc + 2 * i);
4002
4159
  }
4003
4160
  }
4004
4161
 
@@ -4041,7 +4198,7 @@ XXH3_accumulate_512_scalar(void* XXH_RESTRICT acc,
4041
4198
  const void* XXH_RESTRICT input,
4042
4199
  const void* XXH_RESTRICT secret)
4043
4200
  {
4044
- XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64* const xacc = (xxh_u64*) acc; /* presumed aligned */
4201
+ xxh_u64* const xacc = (xxh_u64*) acc; /* presumed aligned */
4045
4202
  const xxh_u8* const xinput = (const xxh_u8*) input; /* no alignment restriction */
4046
4203
  const xxh_u8* const xsecret = (const xxh_u8*) secret; /* no alignment restriction */
4047
4204
  size_t i;
@@ -4057,7 +4214,7 @@ XXH3_accumulate_512_scalar(void* XXH_RESTRICT acc,
4057
4214
  XXH_FORCE_INLINE void
4058
4215
  XXH3_scrambleAcc_scalar(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret)
4059
4216
  {
4060
- XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64* const xacc = (xxh_u64*) acc; /* presumed aligned */
4217
+ xxh_u64* const xacc = (xxh_u64*) acc; /* presumed aligned */
4061
4218
  const xxh_u8* const xsecret = (const xxh_u8*) secret; /* no alignment restriction */
4062
4219
  size_t i;
4063
4220
  XXH_ASSERT((((size_t)acc) & (XXH_ACC_ALIGN-1)) == 0);
@@ -4305,9 +4462,11 @@ XXH3_hashLong_64b_internal(const void* XXH_RESTRICT input, size_t len,
4305
4462
  }
4306
4463
 
4307
4464
  /*
4308
- * It's important for performance that XXH3_hashLong is not inlined.
4465
+ * It's important for performance to transmit secret's size (when it's static)
4466
+ * so that the compiler can properly optimize the vectorized loop.
4467
+ * This makes a big performance difference for "medium" keys (<1 KB) when using AVX instruction set.
4309
4468
  */
4310
- XXH_NO_INLINE XXH64_hash_t
4469
+ XXH_FORCE_INLINE XXH64_hash_t
4311
4470
  XXH3_hashLong_64b_withSecret(const void* XXH_RESTRICT input, size_t len,
4312
4471
  XXH64_hash_t seed64, const xxh_u8* XXH_RESTRICT secret, size_t secretLen)
4313
4472
  {
@@ -4316,11 +4475,10 @@ XXH3_hashLong_64b_withSecret(const void* XXH_RESTRICT input, size_t len,
4316
4475
  }
4317
4476
 
4318
4477
  /*
4319
- * It's important for performance that XXH3_hashLong is not inlined.
4320
- * Since the function is not inlined, the compiler may not be able to understand that,
4321
- * in some scenarios, its `secret` argument is actually a compile time constant.
4322
- * This variant enforces that the compiler can detect that,
4323
- * and uses this opportunity to streamline the generated code for better performance.
4478
+ * It's preferable for performance that XXH3_hashLong is not inlined,
4479
+ * as it results in a smaller function for small data, easier to the instruction cache.
4480
+ * Note that inside this no_inline function, we do inline the internal loop,
4481
+ * and provide a statically defined secret size to allow optimization of vector loop.
4324
4482
  */
4325
4483
  XXH_NO_INLINE XXH64_hash_t
4326
4484
  XXH3_hashLong_64b_default(const void* XXH_RESTRICT input, size_t len,
@@ -4420,6 +4578,14 @@ XXH3_64bits_withSeed(const void* input, size_t len, XXH64_hash_t seed)
4420
4578
  return XXH3_64bits_internal(input, len, seed, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_hashLong_64b_withSeed);
4421
4579
  }
4422
4580
 
4581
+ XXH_PUBLIC_API XXH64_hash_t
4582
+ XXH3_64bits_withSecretandSeed(const void* input, size_t len, const void* secret, size_t secretSize, XXH64_hash_t seed)
4583
+ {
4584
+ if (len <= XXH3_MIDSIZE_MAX)
4585
+ return XXH3_64bits_internal(input, len, seed, XXH3_kSecret, sizeof(XXH3_kSecret), NULL);
4586
+ return XXH3_hashLong_64b_withSecret(input, len, seed, (const xxh_u8*)secret, secretSize);
4587
+ }
4588
+
4423
4589
 
4424
4590
  /* === XXH3 streaming === */
4425
4591
 
@@ -4508,13 +4674,13 @@ XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t* statePtr)
4508
4674
  XXH_PUBLIC_API void
4509
4675
  XXH3_copyState(XXH3_state_t* dst_state, const XXH3_state_t* src_state)
4510
4676
  {
4511
- memcpy(dst_state, src_state, sizeof(*dst_state));
4677
+ XXH_memcpy(dst_state, src_state, sizeof(*dst_state));
4512
4678
  }
4513
4679
 
4514
4680
  static void
4515
4681
  XXH3_reset_internal(XXH3_state_t* statePtr,
4516
- XXH64_hash_t seed,
4517
- const void* secret, size_t secretSize)
4682
+ XXH64_hash_t seed,
4683
+ const void* secret, size_t secretSize)
4518
4684
  {
4519
4685
  size_t const initStart = offsetof(XXH3_state_t, bufferedSize);
4520
4686
  size_t const initLength = offsetof(XXH3_state_t, nbStripesPerBlock) - initStart;
@@ -4531,6 +4697,7 @@ XXH3_reset_internal(XXH3_state_t* statePtr,
4531
4697
  statePtr->acc[6] = XXH_PRIME64_5;
4532
4698
  statePtr->acc[7] = XXH_PRIME32_1;
4533
4699
  statePtr->seed = seed;
4700
+ statePtr->useSeed = (seed != 0);
4534
4701
  statePtr->extSecret = (const unsigned char*)secret;
4535
4702
  XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN);
4536
4703
  statePtr->secretLimit = secretSize - XXH_STRIPE_LEN;
@@ -4563,11 +4730,24 @@ XXH3_64bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed)
4563
4730
  {
4564
4731
  if (statePtr == NULL) return XXH_ERROR;
4565
4732
  if (seed==0) return XXH3_64bits_reset(statePtr);
4566
- if (seed != statePtr->seed) XXH3_initCustomSecret(statePtr->customSecret, seed);
4733
+ if ((seed != statePtr->seed) || (statePtr->extSecret != NULL))
4734
+ XXH3_initCustomSecret(statePtr->customSecret, seed);
4567
4735
  XXH3_reset_internal(statePtr, seed, NULL, XXH_SECRET_DEFAULT_SIZE);
4568
4736
  return XXH_OK;
4569
4737
  }
4570
4738
 
4739
+ /*! @ingroup xxh3_family */
4740
+ XXH_PUBLIC_API XXH_errorcode
4741
+ XXH3_64bits_reset_withSecretandSeed(XXH3_state_t* statePtr, const void* secret, size_t secretSize, XXH64_hash_t seed64)
4742
+ {
4743
+ if (statePtr == NULL) return XXH_ERROR;
4744
+ if (secret == NULL) return XXH_ERROR;
4745
+ if (secretSize < XXH3_SECRET_SIZE_MIN) return XXH_ERROR;
4746
+ XXH3_reset_internal(statePtr, seed64, secret, secretSize);
4747
+ statePtr->useSeed = 1; /* always, even if seed64==0 */
4748
+ return XXH_OK;
4749
+ }
4750
+
4571
4751
  /* Note : when XXH3_consumeStripes() is invoked,
4572
4752
  * there must be a guarantee that at least one more byte must be consumed from input
4573
4753
  * so that the function can blindly consume all stripes using the "normal" secret segment */
@@ -4595,35 +4775,48 @@ XXH3_consumeStripes(xxh_u64* XXH_RESTRICT acc,
4595
4775
  }
4596
4776
  }
4597
4777
 
4778
+ #ifndef XXH3_STREAM_USE_STACK
4779
+ # ifndef __clang__ /* clang doesn't need additional stack space */
4780
+ # define XXH3_STREAM_USE_STACK 1
4781
+ # endif
4782
+ #endif
4598
4783
  /*
4599
4784
  * Both XXH3_64bits_update and XXH3_128bits_update use this routine.
4600
4785
  */
4601
4786
  XXH_FORCE_INLINE XXH_errorcode
4602
- XXH3_update(XXH3_state_t* state,
4603
- const xxh_u8* input, size_t len,
4787
+ XXH3_update(XXH3_state_t* XXH_RESTRICT const state,
4788
+ const xxh_u8* XXH_RESTRICT input, size_t len,
4604
4789
  XXH3_f_accumulate_512 f_acc512,
4605
4790
  XXH3_f_scrambleAcc f_scramble)
4606
4791
  {
4607
- if (input==NULL)
4608
- #if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1)
4792
+ if (input==NULL) {
4793
+ XXH_ASSERT(len == 0);
4609
4794
  return XXH_OK;
4610
- #else
4611
- return XXH_ERROR;
4612
- #endif
4795
+ }
4613
4796
 
4797
+ XXH_ASSERT(state != NULL);
4614
4798
  { const xxh_u8* const bEnd = input + len;
4615
4799
  const unsigned char* const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret;
4616
-
4800
+ #if defined(XXH3_STREAM_USE_STACK) && XXH3_STREAM_USE_STACK >= 1
4801
+ /* For some reason, gcc and MSVC seem to suffer greatly
4802
+ * when operating accumulators directly into state.
4803
+ * Operating into stack space seems to enable proper optimization.
4804
+ * clang, on the other hand, doesn't seem to need this trick */
4805
+ XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64 acc[8]; memcpy(acc, state->acc, sizeof(acc));
4806
+ #else
4807
+ xxh_u64* XXH_RESTRICT const acc = state->acc;
4808
+ #endif
4617
4809
  state->totalLen += len;
4618
4810
  XXH_ASSERT(state->bufferedSize <= XXH3_INTERNALBUFFER_SIZE);
4619
4811
 
4620
- if (state->bufferedSize + len <= XXH3_INTERNALBUFFER_SIZE) { /* fill in tmp buffer */
4812
+ /* small input : just fill in tmp buffer */
4813
+ if (state->bufferedSize + len <= XXH3_INTERNALBUFFER_SIZE) {
4621
4814
  XXH_memcpy(state->buffer + state->bufferedSize, input, len);
4622
4815
  state->bufferedSize += (XXH32_hash_t)len;
4623
4816
  return XXH_OK;
4624
4817
  }
4625
- /* total input is now > XXH3_INTERNALBUFFER_SIZE */
4626
4818
 
4819
+ /* total input is now > XXH3_INTERNALBUFFER_SIZE */
4627
4820
  #define XXH3_INTERNALBUFFER_STRIPES (XXH3_INTERNALBUFFER_SIZE / XXH_STRIPE_LEN)
4628
4821
  XXH_STATIC_ASSERT(XXH3_INTERNALBUFFER_SIZE % XXH_STRIPE_LEN == 0); /* clean multiple */
4629
4822
 
@@ -4635,7 +4828,7 @@ XXH3_update(XXH3_state_t* state,
4635
4828
  size_t const loadSize = XXH3_INTERNALBUFFER_SIZE - state->bufferedSize;
4636
4829
  XXH_memcpy(state->buffer + state->bufferedSize, input, loadSize);
4637
4830
  input += loadSize;
4638
- XXH3_consumeStripes(state->acc,
4831
+ XXH3_consumeStripes(acc,
4639
4832
  &state->nbStripesSoFar, state->nbStripesPerBlock,
4640
4833
  state->buffer, XXH3_INTERNALBUFFER_STRIPES,
4641
4834
  secret, state->secretLimit,
@@ -4644,25 +4837,62 @@ XXH3_update(XXH3_state_t* state,
4644
4837
  }
4645
4838
  XXH_ASSERT(input < bEnd);
4646
4839
 
4647
- /* Consume input by a multiple of internal buffer size */
4648
- if (input+XXH3_INTERNALBUFFER_SIZE < bEnd) {
4649
- const xxh_u8* const limit = bEnd - XXH3_INTERNALBUFFER_SIZE;
4650
- do {
4651
- XXH3_consumeStripes(state->acc,
4652
- &state->nbStripesSoFar, state->nbStripesPerBlock,
4653
- input, XXH3_INTERNALBUFFER_STRIPES,
4654
- secret, state->secretLimit,
4655
- f_acc512, f_scramble);
4656
- input += XXH3_INTERNALBUFFER_SIZE;
4657
- } while (input<limit);
4658
- /* for last partial stripe */
4659
- memcpy(state->buffer + sizeof(state->buffer) - XXH_STRIPE_LEN, input - XXH_STRIPE_LEN, XXH_STRIPE_LEN);
4840
+ /* large input to consume : ingest per full block */
4841
+ if ((size_t)(bEnd - input) > state->nbStripesPerBlock * XXH_STRIPE_LEN) {
4842
+ size_t nbStripes = (size_t)(bEnd - 1 - input) / XXH_STRIPE_LEN;
4843
+ XXH_ASSERT(state->nbStripesPerBlock >= state->nbStripesSoFar);
4844
+ /* join to current block's end */
4845
+ { size_t const nbStripesToEnd = state->nbStripesPerBlock - state->nbStripesSoFar;
4846
+ XXH_ASSERT(nbStripes <= nbStripes);
4847
+ XXH3_accumulate(acc, input, secret + state->nbStripesSoFar * XXH_SECRET_CONSUME_RATE, nbStripesToEnd, f_acc512);
4848
+ f_scramble(acc, secret + state->secretLimit);
4849
+ state->nbStripesSoFar = 0;
4850
+ input += nbStripesToEnd * XXH_STRIPE_LEN;
4851
+ nbStripes -= nbStripesToEnd;
4852
+ }
4853
+ /* consume per entire blocks */
4854
+ while(nbStripes >= state->nbStripesPerBlock) {
4855
+ XXH3_accumulate(acc, input, secret, state->nbStripesPerBlock, f_acc512);
4856
+ f_scramble(acc, secret + state->secretLimit);
4857
+ input += state->nbStripesPerBlock * XXH_STRIPE_LEN;
4858
+ nbStripes -= state->nbStripesPerBlock;
4859
+ }
4860
+ /* consume last partial block */
4861
+ XXH3_accumulate(acc, input, secret, nbStripes, f_acc512);
4862
+ input += nbStripes * XXH_STRIPE_LEN;
4863
+ XXH_ASSERT(input < bEnd); /* at least some bytes left */
4864
+ state->nbStripesSoFar = nbStripes;
4865
+ /* buffer predecessor of last partial stripe */
4866
+ XXH_memcpy(state->buffer + sizeof(state->buffer) - XXH_STRIPE_LEN, input - XXH_STRIPE_LEN, XXH_STRIPE_LEN);
4867
+ XXH_ASSERT(bEnd - input <= XXH_STRIPE_LEN);
4868
+ } else {
4869
+ /* content to consume <= block size */
4870
+ /* Consume input by a multiple of internal buffer size */
4871
+ if (bEnd - input > XXH3_INTERNALBUFFER_SIZE) {
4872
+ const xxh_u8* const limit = bEnd - XXH3_INTERNALBUFFER_SIZE;
4873
+ do {
4874
+ XXH3_consumeStripes(acc,
4875
+ &state->nbStripesSoFar, state->nbStripesPerBlock,
4876
+ input, XXH3_INTERNALBUFFER_STRIPES,
4877
+ secret, state->secretLimit,
4878
+ f_acc512, f_scramble);
4879
+ input += XXH3_INTERNALBUFFER_SIZE;
4880
+ } while (input<limit);
4881
+ /* buffer predecessor of last partial stripe */
4882
+ XXH_memcpy(state->buffer + sizeof(state->buffer) - XXH_STRIPE_LEN, input - XXH_STRIPE_LEN, XXH_STRIPE_LEN);
4883
+ }
4660
4884
  }
4661
- XXH_ASSERT(input < bEnd);
4662
4885
 
4663
4886
  /* Some remaining input (always) : buffer it */
4887
+ XXH_ASSERT(input < bEnd);
4888
+ XXH_ASSERT(bEnd - input <= XXH3_INTERNALBUFFER_SIZE);
4889
+ XXH_ASSERT(state->bufferedSize == 0);
4664
4890
  XXH_memcpy(state->buffer, input, (size_t)(bEnd-input));
4665
4891
  state->bufferedSize = (XXH32_hash_t)(bEnd-input);
4892
+ #if defined(XXH3_STREAM_USE_STACK) && XXH3_STREAM_USE_STACK >= 1
4893
+ /* save stack accumulators into state */
4894
+ memcpy(state->acc, acc, sizeof(acc));
4895
+ #endif
4666
4896
  }
4667
4897
 
4668
4898
  return XXH_OK;
@@ -4686,7 +4916,7 @@ XXH3_digest_long (XXH64_hash_t* acc,
4686
4916
  * Digest on a local copy. This way, the state remains unaltered, and it can
4687
4917
  * continue ingesting more input afterwards.
4688
4918
  */
4689
- memcpy(acc, state->acc, sizeof(state->acc));
4919
+ XXH_memcpy(acc, state->acc, sizeof(state->acc));
4690
4920
  if (state->bufferedSize >= XXH_STRIPE_LEN) {
4691
4921
  size_t const nbStripes = (state->bufferedSize - 1) / XXH_STRIPE_LEN;
4692
4922
  size_t nbStripesSoFar = state->nbStripesSoFar;
@@ -4703,8 +4933,8 @@ XXH3_digest_long (XXH64_hash_t* acc,
4703
4933
  xxh_u8 lastStripe[XXH_STRIPE_LEN];
4704
4934
  size_t const catchupSize = XXH_STRIPE_LEN - state->bufferedSize;
4705
4935
  XXH_ASSERT(state->bufferedSize > 0); /* there is always some input buffered */
4706
- memcpy(lastStripe, state->buffer + sizeof(state->buffer) - catchupSize, catchupSize);
4707
- memcpy(lastStripe + catchupSize, state->buffer, state->bufferedSize);
4936
+ XXH_memcpy(lastStripe, state->buffer + sizeof(state->buffer) - catchupSize, catchupSize);
4937
+ XXH_memcpy(lastStripe + catchupSize, state->buffer, state->bufferedSize);
4708
4938
  XXH3_accumulate_512(acc,
4709
4939
  lastStripe,
4710
4940
  secret + state->secretLimit - XXH_SECRET_LASTACC_START);
@@ -4723,58 +4953,13 @@ XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (const XXH3_state_t* state)
4723
4953
  (xxh_u64)state->totalLen * XXH_PRIME64_1);
4724
4954
  }
4725
4955
  /* totalLen <= XXH3_MIDSIZE_MAX: digesting a short input */
4726
- if (state->seed)
4956
+ if (state->useSeed)
4727
4957
  return XXH3_64bits_withSeed(state->buffer, (size_t)state->totalLen, state->seed);
4728
4958
  return XXH3_64bits_withSecret(state->buffer, (size_t)(state->totalLen),
4729
4959
  secret, state->secretLimit + XXH_STRIPE_LEN);
4730
4960
  }
4731
4961
 
4732
4962
 
4733
- #define XXH_MIN(x, y) (((x) > (y)) ? (y) : (x))
4734
-
4735
- /*! @ingroup xxh3_family */
4736
- XXH_PUBLIC_API void
4737
- XXH3_generateSecret(void* secretBuffer, const void* customSeed, size_t customSeedSize)
4738
- {
4739
- XXH_ASSERT(secretBuffer != NULL);
4740
- if (customSeedSize == 0) {
4741
- memcpy(secretBuffer, XXH3_kSecret, XXH_SECRET_DEFAULT_SIZE);
4742
- return;
4743
- }
4744
- XXH_ASSERT(customSeed != NULL);
4745
-
4746
- { size_t const segmentSize = sizeof(XXH128_hash_t);
4747
- size_t const nbSegments = XXH_SECRET_DEFAULT_SIZE / segmentSize;
4748
- XXH128_canonical_t scrambler;
4749
- XXH64_hash_t seeds[12];
4750
- size_t segnb;
4751
- XXH_ASSERT(nbSegments == 12);
4752
- XXH_ASSERT(segmentSize * nbSegments == XXH_SECRET_DEFAULT_SIZE); /* exact multiple */
4753
- XXH128_canonicalFromHash(&scrambler, XXH128(customSeed, customSeedSize, 0));
4754
-
4755
- /*
4756
- * Copy customSeed to seeds[], truncating or repeating as necessary.
4757
- */
4758
- { size_t toFill = XXH_MIN(customSeedSize, sizeof(seeds));
4759
- size_t filled = toFill;
4760
- memcpy(seeds, customSeed, toFill);
4761
- while (filled < sizeof(seeds)) {
4762
- toFill = XXH_MIN(filled, sizeof(seeds) - filled);
4763
- memcpy((char*)seeds + filled, seeds, toFill);
4764
- filled += toFill;
4765
- } }
4766
-
4767
- /* generate secret */
4768
- memcpy(secretBuffer, &scrambler, sizeof(scrambler));
4769
- for (segnb=1; segnb < nbSegments; segnb++) {
4770
- size_t const segmentStart = segnb * segmentSize;
4771
- XXH128_canonical_t segment;
4772
- XXH128_canonicalFromHash(&segment,
4773
- XXH128(&scrambler, sizeof(scrambler), XXH_readLE64(seeds + segnb) + segnb) );
4774
- memcpy((char*)secretBuffer + segmentStart, &segment, sizeof(segment));
4775
- } }
4776
- }
4777
-
4778
4963
 
4779
4964
  /* ==========================================
4780
4965
  * XXH3 128 bits (a.k.a XXH128)
@@ -5076,9 +5261,10 @@ XXH3_hashLong_128b_default(const void* XXH_RESTRICT input, size_t len,
5076
5261
  }
5077
5262
 
5078
5263
  /*
5079
- * It's important for performance that XXH3_hashLong is not inlined.
5264
+ * It's important for performance to pass @secretLen (when it's static)
5265
+ * to the compiler, so that it can properly optimize the vectorized loop.
5080
5266
  */
5081
- XXH_NO_INLINE XXH128_hash_t
5267
+ XXH_FORCE_INLINE XXH128_hash_t
5082
5268
  XXH3_hashLong_128b_withSecret(const void* XXH_RESTRICT input, size_t len,
5083
5269
  XXH64_hash_t seed64,
5084
5270
  const void* XXH_RESTRICT secret, size_t secretLen)
@@ -5171,6 +5357,15 @@ XXH3_128bits_withSeed(const void* input, size_t len, XXH64_hash_t seed)
5171
5357
  XXH3_hashLong_128b_withSeed);
5172
5358
  }
5173
5359
 
5360
+ /*! @ingroup xxh3_family */
5361
+ XXH_PUBLIC_API XXH128_hash_t
5362
+ XXH3_128bits_withSecretandSeed(const void* input, size_t len, const void* secret, size_t secretSize, XXH64_hash_t seed)
5363
+ {
5364
+ if (len <= XXH3_MIDSIZE_MAX)
5365
+ return XXH3_128bits_internal(input, len, seed, XXH3_kSecret, sizeof(XXH3_kSecret), NULL);
5366
+ return XXH3_hashLong_128b_withSecret(input, len, seed, secret, secretSize);
5367
+ }
5368
+
5174
5369
  /*! @ingroup xxh3_family */
5175
5370
  XXH_PUBLIC_API XXH128_hash_t
5176
5371
  XXH128(const void* input, size_t len, XXH64_hash_t seed)
@@ -5182,7 +5377,7 @@ XXH128(const void* input, size_t len, XXH64_hash_t seed)
5182
5377
  /* === XXH3 128-bit streaming === */
5183
5378
 
5184
5379
  /*
5185
- * All the functions are actually the same as for 64-bit streaming variant.
5380
+ * All initialization and update functions are identical to 64-bit streaming variant.
5186
5381
  * The only difference is the finalization routine.
5187
5382
  */
5188
5383
 
@@ -5190,31 +5385,28 @@ XXH128(const void* input, size_t len, XXH64_hash_t seed)
5190
5385
  XXH_PUBLIC_API XXH_errorcode
5191
5386
  XXH3_128bits_reset(XXH3_state_t* statePtr)
5192
5387
  {
5193
- if (statePtr == NULL) return XXH_ERROR;
5194
- XXH3_reset_internal(statePtr, 0, XXH3_kSecret, XXH_SECRET_DEFAULT_SIZE);
5195
- return XXH_OK;
5388
+ return XXH3_64bits_reset(statePtr);
5196
5389
  }
5197
5390
 
5198
5391
  /*! @ingroup xxh3_family */
5199
5392
  XXH_PUBLIC_API XXH_errorcode
5200
5393
  XXH3_128bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize)
5201
5394
  {
5202
- if (statePtr == NULL) return XXH_ERROR;
5203
- XXH3_reset_internal(statePtr, 0, secret, secretSize);
5204
- if (secret == NULL) return XXH_ERROR;
5205
- if (secretSize < XXH3_SECRET_SIZE_MIN) return XXH_ERROR;
5206
- return XXH_OK;
5395
+ return XXH3_64bits_reset_withSecret(statePtr, secret, secretSize);
5207
5396
  }
5208
5397
 
5209
5398
  /*! @ingroup xxh3_family */
5210
5399
  XXH_PUBLIC_API XXH_errorcode
5211
5400
  XXH3_128bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed)
5212
5401
  {
5213
- if (statePtr == NULL) return XXH_ERROR;
5214
- if (seed==0) return XXH3_128bits_reset(statePtr);
5215
- if (seed != statePtr->seed) XXH3_initCustomSecret(statePtr->customSecret, seed);
5216
- XXH3_reset_internal(statePtr, seed, NULL, XXH_SECRET_DEFAULT_SIZE);
5217
- return XXH_OK;
5402
+ return XXH3_64bits_reset_withSeed(statePtr, seed);
5403
+ }
5404
+
5405
+ /*! @ingroup xxh3_family */
5406
+ XXH_PUBLIC_API XXH_errorcode
5407
+ XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr, const void* secret, size_t secretSize, XXH64_hash_t seed)
5408
+ {
5409
+ return XXH3_64bits_reset_withSecretandSeed(statePtr, secret, secretSize, seed);
5218
5410
  }
5219
5411
 
5220
5412
  /*! @ingroup xxh3_family */
@@ -5289,8 +5481,8 @@ XXH128_canonicalFromHash(XXH128_canonical_t* dst, XXH128_hash_t hash)
5289
5481
  hash.high64 = XXH_swap64(hash.high64);
5290
5482
  hash.low64 = XXH_swap64(hash.low64);
5291
5483
  }
5292
- memcpy(dst, &hash.high64, sizeof(hash.high64));
5293
- memcpy((char*)dst + sizeof(hash.high64), &hash.low64, sizeof(hash.low64));
5484
+ XXH_memcpy(dst, &hash.high64, sizeof(hash.high64));
5485
+ XXH_memcpy((char*)dst + sizeof(hash.high64), &hash.low64, sizeof(hash.low64));
5294
5486
  }
5295
5487
 
5296
5488
  /*! @ingroup xxh3_family */
@@ -5303,6 +5495,69 @@ XXH128_hashFromCanonical(const XXH128_canonical_t* src)
5303
5495
  return h;
5304
5496
  }
5305
5497
 
5498
+
5499
+
5500
+ /* ==========================================
5501
+ * Secret generators
5502
+ * ==========================================
5503
+ */
5504
+ #define XXH_MIN(x, y) (((x) > (y)) ? (y) : (x))
5505
+
5506
+ static void XXH3_combine16(void* dst, XXH128_hash_t h128)
5507
+ {
5508
+ XXH_writeLE64( dst, XXH_readLE64(dst) ^ h128.low64 );
5509
+ XXH_writeLE64( (char*)dst+8, XXH_readLE64((char*)dst+8) ^ h128.high64 );
5510
+ }
5511
+
5512
+ /*! @ingroup xxh3_family */
5513
+ XXH_PUBLIC_API XXH_errorcode
5514
+ XXH3_generateSecret(void* secretBuffer, size_t secretSize, const void* customSeed, size_t customSeedSize)
5515
+ {
5516
+ XXH_ASSERT(secretBuffer != NULL);
5517
+ if (secretBuffer == NULL) return XXH_ERROR;
5518
+ XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN);
5519
+ if (secretSize < XXH3_SECRET_SIZE_MIN) return XXH_ERROR;
5520
+ if (customSeedSize == 0) {
5521
+ customSeed = XXH3_kSecret;
5522
+ customSeedSize = XXH_SECRET_DEFAULT_SIZE;
5523
+ }
5524
+ XXH_ASSERT(customSeed != NULL);
5525
+ if (customSeed == NULL) return XXH_ERROR;
5526
+
5527
+ /* Fill secretBuffer with a copy of customSeed - repeat as needed */
5528
+ { size_t pos = 0;
5529
+ while (pos < secretSize) {
5530
+ size_t const toCopy = XXH_MIN((secretSize - pos), customSeedSize);
5531
+ memcpy((char*)secretBuffer + pos, customSeed, toCopy);
5532
+ pos += toCopy;
5533
+ } }
5534
+
5535
+ { size_t const nbSeg16 = secretSize / 16;
5536
+ size_t n;
5537
+ XXH128_canonical_t scrambler;
5538
+ XXH128_canonicalFromHash(&scrambler, XXH128(customSeed, customSeedSize, 0));
5539
+ for (n=0; n<nbSeg16; n++) {
5540
+ XXH128_hash_t const h128 = XXH128(&scrambler, sizeof(scrambler), n);
5541
+ XXH3_combine16((char*)secretBuffer + n*16, h128);
5542
+ }
5543
+ /* last segment */
5544
+ XXH3_combine16((char*)secretBuffer + secretSize - 16, XXH128_hashFromCanonical(&scrambler));
5545
+ }
5546
+ return XXH_OK;
5547
+ }
5548
+
5549
+ /*! @ingroup xxh3_family */
5550
+ XXH_PUBLIC_API void
5551
+ XXH3_generateSecret_fromSeed(void* secretBuffer, XXH64_hash_t seed)
5552
+ {
5553
+ XXH_ALIGN(XXH_SEC_ALIGN) xxh_u8 secret[XXH_SECRET_DEFAULT_SIZE];
5554
+ XXH3_initCustomSecret(secret, seed);
5555
+ XXH_ASSERT(secretBuffer != NULL);
5556
+ memcpy(secretBuffer, secret, XXH_SECRET_DEFAULT_SIZE);
5557
+ }
5558
+
5559
+
5560
+
5306
5561
  /* Pop our optimization override from above */
5307
5562
  #if XXH_VECTOR == XXH_AVX2 /* AVX2 */ \
5308
5563
  && defined(__GNUC__) && !defined(__clang__) /* GCC, not Clang */ \