m2m模型翻译
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

102 lines
2.8 KiB

6 months ago
  1. from __future__ import absolute_import
  2. import random
  3. from kafka.vendor import six
  4. class DefaultPartitioner(object):
  5. """Default partitioner.
  6. Hashes key to partition using murmur2 hashing (from java client)
  7. If key is None, selects partition randomly from available,
  8. or from all partitions if none are currently available
  9. """
  10. @classmethod
  11. def __call__(cls, key, all_partitions, available):
  12. """
  13. Get the partition corresponding to key
  14. :param key: partitioning key
  15. :param all_partitions: list of all partitions sorted by partition ID
  16. :param available: list of available partitions in no particular order
  17. :return: one of the values from all_partitions or available
  18. """
  19. if key is None:
  20. if available:
  21. return random.choice(available)
  22. return random.choice(all_partitions)
  23. idx = murmur2(key)
  24. idx &= 0x7fffffff
  25. idx %= len(all_partitions)
  26. return all_partitions[idx]
  27. # https://github.com/apache/kafka/blob/0.8.2/clients/src/main/java/org/apache/kafka/common/utils/Utils.java#L244
  28. def murmur2(data):
  29. """Pure-python Murmur2 implementation.
  30. Based on java client, see org.apache.kafka.common.utils.Utils.murmur2
  31. Args:
  32. data (bytes): opaque bytes
  33. Returns: MurmurHash2 of data
  34. """
  35. # Python2 bytes is really a str, causing the bitwise operations below to fail
  36. # so convert to bytearray.
  37. if six.PY2:
  38. data = bytearray(bytes(data))
  39. length = len(data)
  40. seed = 0x9747b28c
  41. # 'm' and 'r' are mixing constants generated offline.
  42. # They're not really 'magic', they just happen to work well.
  43. m = 0x5bd1e995
  44. r = 24
  45. # Initialize the hash to a random value
  46. h = seed ^ length
  47. length4 = length // 4
  48. for i in range(length4):
  49. i4 = i * 4
  50. k = ((data[i4 + 0] & 0xff) +
  51. ((data[i4 + 1] & 0xff) << 8) +
  52. ((data[i4 + 2] & 0xff) << 16) +
  53. ((data[i4 + 3] & 0xff) << 24))
  54. k &= 0xffffffff
  55. k *= m
  56. k &= 0xffffffff
  57. k ^= (k % 0x100000000) >> r # k ^= k >>> r
  58. k &= 0xffffffff
  59. k *= m
  60. k &= 0xffffffff
  61. h *= m
  62. h &= 0xffffffff
  63. h ^= k
  64. h &= 0xffffffff
  65. # Handle the last few bytes of the input array
  66. extra_bytes = length % 4
  67. if extra_bytes >= 3:
  68. h ^= (data[(length & ~3) + 2] & 0xff) << 16
  69. h &= 0xffffffff
  70. if extra_bytes >= 2:
  71. h ^= (data[(length & ~3) + 1] & 0xff) << 8
  72. h &= 0xffffffff
  73. if extra_bytes >= 1:
  74. h ^= (data[length & ~3] & 0xff)
  75. h &= 0xffffffff
  76. h *= m
  77. h &= 0xffffffff
  78. h ^= (h % 0x100000000) >> 13 # h >>> 13;
  79. h &= 0xffffffff
  80. h *= m
  81. h &= 0xffffffff
  82. h ^= (h % 0x100000000) >> 15 # h >>> 15;
  83. h &= 0xffffffff
  84. return h