code: func (t *Topic) generatePartitionAssignments(brokers []int32, partitionCount int, replicationFactor int) (PartitionList, error) {
  	if partitionCount <= 0 {
  		return nil, ErrInvalidPartitionCount
  	}
  	if replicationFactor <= 0 || len(brokers) < replicationFactor {
  		return nil, ErrInvalidReplicationFactor
  	}
  
  	result := make(PartitionList, partitionCount)
  
  	brokerCount := len(brokers)
  	brokerIdx := rand.Intn(brokerCount)
  
  	for p := 0; p < partitionCount; p++ {
  		partition := &Partition{topic: t, ID: int32(p), Replicas: make([]int32, replicationFactor)}
  
  		brokerIndices := rand.Perm(len(brokers))[0:replicationFactor]
  
  		for r := 0; r < replicationFactor; r++ {
  			partition.Replicas[r] = brokers[brokerIndices[r]]
  		}
  
  		result[p] = partition
  		brokerIdx = (brokerIdx + 1) % brokerCount
  	}
  
  	return result, nil
  }
docs: // generatePartitionAssignments creates a partition list for a topic. The primary replica for
  // each partition is assigned in a round-robin fashion starting at a random broker.
  // Additional replicas are assigned to subsequent brokers to ensure there is no overlap