@Override
        Map<String, List<TopicPartition>> build() {
            if (log.isDebugEnabled()) {
                log.debug("Performing constrained assign with partitionsPerTopic: {}, currentAssignment: {}, rackInfo {}.",
                        partitionsPerTopic, currentAssignment, rackInfo);
            }

            assignOwnedPartitions();

            List<TopicPartition> unassignedPartitions = getUnassignedPartitions(assignedPartitions);

            if (log.isDebugEnabled()) {
                log.debug("After reassigning previously owned partitions, unfilled members: {}, unassigned partitions: {}, " +
                        "current assignment: {}", unfilledMembersWithUnderMinQuotaPartitions, unassignedPartitions, assignment);
            }

            Collections.sort(unfilledMembersWithUnderMinQuotaPartitions);
            Collections.sort(unfilledMembersWithExactlyMinQuotaPartitions);
            unassignedPartitions = rackInfo.sortPartitionsByRackConsumers(unassignedPartitions);

            assignRackAwareRoundRobin(unassignedPartitions);
            assignRoundRobin(unassignedPartitions);
            verifyUnfilledMembers();

            log.info("Final assignment of partitions to consumers: \n{}", assignment);

            return assignment;
        }
Constructs a constrained assignment builder.

@param partitionsPerTopic                   The partitions for each subscribed topic
@param rackInfo                             Rack information for consumers and racks
@param consumerToOwnedPartitions            Each consumer's previously owned and still-subscribed partitions
@param partitionsWithMultiplePreviousOwners The partitions being claimed in the previous assignment of multiple consumers
clients/src/main/java/org/apache/kafka/clients/consumer/internals/AbstractStickyAssignor.java