Class Partitioning

java.lang.Object
org.acemq.amqp.api.Partitioning

public final class Partitioning extends Object
Decides which partition an ordering key belongs to.

This is a wire contract, not an implementation detail. A Java publisher and a Go consumer have to agree about where a key lands or ordering breaks silently across languages, so the hash is specified rather than borrowed: FNV-1a, 32-bit, over the key's UTF-8 bytes.

String.hashCode() was the obvious candidate and is the wrong one. It is stable across Java versions but it is Java's, and reimplementing it in Go or Python to keep a fleet in agreement is a strange thing to ask of anybody. FNV-1a is eight lines in any language and has no library behind it.

The golden values in the test suite exist for exactly this reason: a port that produces different partitions is a port that reorders messages, and nothing else would catch it.

Changing the partition count is not free

Partition n for a key is a function of the count, so raising it moves most keys somewhere new. During the change a key can have messages in two partitions at once, and their relative order is not defined. There is no clever fix — consistent hashing reduces how many keys move but does not stop it. Drain first, then change.

  • Method Details

    • hash

      public static int hash(String key)
      Parameters:
      key - the ordering key, such as a customer or account identifier
      Returns:
      the FNV-1a 32-bit hash of its UTF-8 bytes
    • partitionFor

      public static int partitionFor(String key, int partitions)
      Parameters:
      key - the ordering key
      partitions - how many partitions exist, at least 1
      Returns:
      the partition this key belongs to, from 0 to partitions - 1
    • routingKeyFor

      public static String routingKeyFor(int partition)
      Parameters:
      partition - partition number
      Returns:
      the routing key it is bound with, p0, p1 and so on