synchronized SystemStreamPartition allocate(String stream) throws NoAvailablePartitionException {
    Validate.notNull(availableSsps.get(stream),
        String.format("availableSsps is null for stream %s", stream));

    if (availableSsps.get(stream).isEmpty()) {
      // Set a flag in system consumer so that it could throw an exception in the subsequent poll.
      throw new NoAvailablePartitionException(String.format("More shards detected for stream %s than initially"
          + " registered. Could be the result of dynamic resharding.", stream));
    }

    SystemStreamPartition ssp = availableSsps.get(stream).iterator().next();
    availableSsps.get(stream).remove(ssp);

    LOG.info("Number of unassigned partitions for system-stream {} is {}.", ssp.getSystemStream(),
        availableSsps.get(ssp.getStream()).size());
    return ssp;
  }
SSPAllocator is responsible for assigning Samza SystemStreamPartitions (SSPs). It provides two APIs:
<ul>
  <li> allocate: Given a stream, returns free ssp.
  <li> free: Adds ssp back to the free pool.
</ul>
A free (unallocated) ssp is returned for every allocate request and when there is no available ssp to allocate,
the allocator throws NoAvailablePartitionException. Allocator could run out of free ssps as a result of dynamic
shard splits.
samza-aws/src/main/java/org/apache/samza/system/kinesis/consumer/SSPAllocator.java