Skip to content

MINOR: Add primitive collections for the uniform2 assignor - #7

Closed
dajac wants to merge 1 commit into
trunkfrom
uniform2-util
Closed

dajac wants to merge 1 commit into
trunkfrom
uniform2-util

Conversation

@dajac

@dajac dajac commented Sep 18, 2026

Copy link
Copy Markdown
Owner

This is the first of three changes adding the uniform2 consumer group assignor. It adds the four small collections the assignor is built on, in the package assignor.uniform2.util. The assignor works on members, topics and partitions numbered from zero and keeps its state in arrays, so these collections let it avoid boxing and hashing, which matters for the memory and the time an assignment takes on groups of thousands of members and topics.

  • IntArrayList: a growable list of ints, for the many small lists of members, topics and partitions the phases collect.
  • IntArraySet: an immutable Set<Integer> over a sorted array, for the partition sets of the assignments. It is cheaper to build and to store than a HashSet<Integer>, looks values up by binary search, and is equal to any Set with the same integers.
  • LongArrayHeap: a binary min-heap of longs, for members ordered by keys packing a load and a member index into one long.
  • UuidIndex: the dense indices of a fixed set of Uuids, kept in open addressing tables of their two longs, for the topics.

The package is meant for the assignor only. Every class and public method is documented, and unit tests cover every method, including the growth of the list and the heap, the Set contract of IntArraySet and the colliding slots of UuidIndex.

Comment on lines +22 to +24
* A minimal growable list of ints for the uniform2 assignor, which avoids the boxing of a
* {@code List<Integer>}. The assignor collects members, topics and partitions in many small
* lists, so the boxed integers and their hashing would cost more than the assignment itself.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Let's avoid the ref to the uniform2 assignor. It is a generic collection so its documentation must be generic. Also, look at the recent comments regarding your comments to ensure that you incorporate the previous feedback.

* @param capacity The initial capacity. The list grows as needed from at least one value.
*/
public IntArrayList(int capacity) {
values = new int[Math.max(1, capacity)];

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Should it throw if the capacity is negative? Could it be zero?

/**
* Removes the first occurrence of the value, if any, shifting the following values down.
*/
public void removeValue(int value) {

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Should we name it remove to align with add?

Comment on lines +26 to +29
* An immutable {@link Set} of integers backed by a sorted array without duplicates, for the
* partition sets of the assignments built by the uniform2 assignor. It is much cheaper to build
* and to store than a {@code HashSet<Integer>}, which matters when an assignment holds many
* small partition sets: building one copies a sorted array, and a lookup is a binary search.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto about the documentation here.

Comment on lines +22 to +24
* A minimal binary min-heap of longs for the uniform2 assignor, which avoids the boxing of a
* {@code PriorityQueue<Long>}. The assignor orders members by keys packing a load and a member
* index into one long, so the smallest key is the next member to serve.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto about the doc.

* @param capacity The initial capacity. The heap grows as needed from at least one value.
*/
public LongArrayHeap(int capacity) {
values = new long[Math.max(1, capacity)];

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment about the capacity.

Comment on lines +24 to +28
* The dense indices of a fixed set of {@link Uuid}s, for the topics of the uniform2 assignor,
* which numbers them once and then works with the numbers. The ids are kept in open addressing
* tables of their two longs, so a lookup hashes and compares longs without boxing, which is much
* cheaper than a {@code HashMap<Uuid, Integer>} for the lookups the assignor does in large
* numbers.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto about the doc.

The uniform2 consumer group assignor, which follows in its own change,
works on members, topics and partitions numbered from zero and keeps
its state in arrays. Four small collections in the package
assignor.uniform2.util let it do so without boxing or hashing, which
matters for the memory and the time an assignment takes on groups of
thousands of members and topics:

- IntArrayList, a growable list of ints, for the many small lists of
  members, topics and partitions the phases collect.
- IntArraySet, an immutable Set<Integer> over a sorted array, for the
  partition sets of the assignments: cheaper to build and to store than
  a HashSet<Integer>, with a binary search for lookups, and equal to any
  Set with the same integers.
- LongArrayHeap, a binary min-heap of longs, for the members ordered by
  keys packing a load and a member index into one long.
- UuidIndex, the dense indices of a fixed set of Uuids kept in open
  addressing tables of their two longs, for the topics, numbered once
  and then referred to by number.

The package is meant for the assignor only, not as a module wide
toolbox. Every class and public method is documented, and unit tests
cover every method, including the growth of the list and the heap, the
Set contract of IntArraySet and the colliding slots of UuidIndex.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@dajac
dajac changed the base branch from topic-ids-to-array to trunk September 18, 2026 14:17
@dajac dajac closed this Sep 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant