Skip to content

Conversation

@rtjd6554
Copy link
Collaborator

@rtjd6554 rtjd6554 commented Nov 27, 2025

Make sure you have checked all steps below.

Issue

  • My PR fully resolves the following issues. I've referenced an issue in the PR title, for example "Issue 1234 - My
    Feature". Note that before an issue is finished, you can still make a pull request by raising a separate issue
    for your progress.

Tests

  • My PR adds the following tests based on our test strategy OR does not need testing for this extremely good reason:
    • Existing execution of test suite
    • New tests for classes created: ByteArrayTest

Documentation

  • In case of new functionality, my PR adds documentation that describes how to use it, or I have linked to a
    separate issue for that below.
  • If I have added new Java code, I have added Javadoc that explains it following our conventions and style.
  • If I have added or removed any dependencies from the project, I have updated the NOTICES file.

@m09526
Copy link
Member

m09526 commented Nov 28, 2025

Could we replace this with a commons lang3 Pair? They have ImmutablePair and MutablePair as required.

@patchwork01
Copy link
Collaborator

Personally I'd rather avoid using a Pair-type data structure at all, in favour of something with a more descriptive name. Using a Java record lets you achieve that with very little boilerplate, something like this:

public record FieldValue<T>(String fieldName, T value) {
}

I'd keep that in the Athena code, next to where it's used, maybe nest it in the class and make it static.

@rtjd6554 rtjd6554 marked this pull request as ready for review December 2, 2025 15:34
@rtjd6554 rtjd6554 added the needs-reviewer Pull requests that need a reviewer to be assigned label Dec 2, 2025
@ca61688 ca61688 self-assigned this Dec 2, 2025
@ca61688 ca61688 removed the needs-reviewer Pull requests that need a reviewer to be assigned label Dec 2, 2025
*/
package sleeper.athena.record;

public record FieldAtDimension(int dimension, Object value) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is field AT dimension whereas other is field AS String. Is that correct?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Addressed typo

*
* @param array1 first ByteArray object
* @param array2 second ByteArray object
* @return true is equal
Copy link
Collaborator

Choose a reason for hiding this comment

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

true if* equal

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Addressed typo

* Method for checking equality versus generic object declaration.
*
* @param o object to compare versus
* @return true is equal
Copy link
Collaborator

Choose a reason for hiding this comment

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

true if* equal

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Addressed typo


import static org.assertj.core.api.Assertions.assertThat;

public class ByteArrayTest {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is it worth testing equals validation for one null one not and for the contents of the arrays being equal?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Addressed

Copy link
Collaborator

@ca61688 ca61688 left a comment

Choose a reason for hiding this comment

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

Few small comments otherwise looks good

@ca61688 ca61688 assigned rtjd6554 and unassigned ca61688 Dec 2, 2025
@rtjd6554 rtjd6554 added the needs-reviewer Pull requests that need a reviewer to be assigned label Dec 3, 2025
@rtjd6554 rtjd6554 removed their assignment Dec 3, 2025
@ca61688 ca61688 self-assigned this Dec 3, 2025
@ca61688 ca61688 removed the needs-reviewer Pull requests that need a reviewer to be assigned label Dec 3, 2025
@ca61688 ca61688 assigned rtjd6554 and unassigned ca61688 Dec 3, 2025
}

/**
* Method for checking equaility.
Copy link
Member

Choose a reason for hiding this comment

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

Typo on equaility - should be equality

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Addressed

Copy link
Collaborator

@patchwork01 patchwork01 left a comment

Choose a reason for hiding this comment

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

Facebook have the same license as this project. I'm basing this review on my own reading of the terms:

https://github.com/facebookarchive/jcommon/blob/master/LICENSE


Facebook Jcommon collections (com.facebook.jcommon:collections:0.*)

- Apache License, Version 2.0
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is no longer a Maven dependency, but we've copied code directly from there so I think we need to state that in this file. I think we still need this notice, but in its own section explaining we copied the ByteArray class.

/**
* Class to provide wrapper object for primitive byte array into an object.
* Require as hashCode and equals requied for usage of type within a HashSet.
*
Copy link
Collaborator

Choose a reason for hiding this comment

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

There's an extra blank line here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Addressed


/**
* Class to provide wrapper object for primitive byte array into an object.
* Require as hashCode and equals requied for usage of type within a HashSet.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please see the Oracle Javadoc style guide:

https://www.oracle.com/uk/technical-resources/articles/java/javadoc-tool.html#styleguide

A class description shouldn't start with "class", see "Class/interface/field descriptions can omit the subject and simply state the object." If we take the first sentence as it is, it could start with "A wrapper for ...".

There's a typo at "requied".

There are grammatical problems at "for primitive", "Require as", "equals required", "usage of type".

It's not technically true that by wrapping a byte array we turn it into an object. A byte array is already an object.

I don't think HashSet is relevant to this class?

I think the important part for us is it implements Comparable and equals/hashCode.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Addressed,

disagree on the HashSet comment as otherwise we could just use the primitive here, it is directly because we use in within HashSets that we need it as a separate class.

public static final ByteArrayComparator BYTE_ARRAY_COMPARATOR = new ByteArrayComparator();

/**
* Returns contents of object as primitive type.
Copy link
Collaborator

Choose a reason for hiding this comment

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

It's fine for this to be a phrase rather than a full sentence, but there are grammatical problems. It's missing "the", "this", "a". I'd put "Returns the contents of this object as a primitive byte array".

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Addressed

/**
* Returns contents of object as primitive type.
*
* @return array details in primitive type
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm not sure what "details" or "in primitive type" means here. I'd just put "the byte array".

}

/**
* Method for checking equaility.
Copy link
Collaborator

Choose a reason for hiding this comment

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

A method description shouldn't start with "method", see "Class/interface/field descriptions can omit the subject and simply state the object."

https://www.oracle.com/uk/technical-resources/articles/java/javadoc-tool.html#styleguide

There's also a typo at "equaility".

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Addressed

* @param o object to compare versus
* @return true if equal
*/
public boolean equals(Object o) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Usually for equals/hashCode/toString we use an @Override annotation and inherit the Javadoc from Object. The Javadoc you get when you just use @Override explains a bit more.

There are a number of instances of this in this file.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Addressed

/**
* Declared implementation of PureByteArray to match design for Arrays comparion.
*/
class PureByteArray extends ByteArray {
Copy link
Collaborator

Choose a reason for hiding this comment

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

If we make this a nested static class as it was in the Facebook code, this can be private.

/**
* Comparator for ByteArray type.
*/
class ByteArrayComparator implements Comparator<ByteArray> {
Copy link
Collaborator

Choose a reason for hiding this comment

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

If we make this a nested static class as it was in the Facebook code, this can be private.

}

/**
* Declared implementation of PureByteArray to match design for Arrays comparion.
Copy link
Collaborator

Choose a reason for hiding this comment

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

What is this trying to say?

There's a typo at "comparion".

ByteArray second = ByteArray.wrap(new byte[]{7, 8, 9});

// When / Then
assertThat(first.getArray()).isEqualTo(second.getArray());
Copy link
Collaborator

Choose a reason for hiding this comment

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

This isn't testing comparison of the ByteArray objects, it's retrieving the arrays and asserting that those are equal.

I think we need to call first.equals(second) directly.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Addressed

ByteArray second = ByteArray.wrap(data);

// Then
assertThat(first.getArray()).isEqualTo(second.getArray());
Copy link
Collaborator

Choose a reason for hiding this comment

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

This isn't testing comparison of the ByteArray objects, it's retrieving the arrays and asserting that those are equal.

I think we need to call first.equals(second) directly.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Addressed

ByteArray result = ByteArray.wrap(data);

// Then
assertThat(result.getArray()).isEqualTo(data);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Isn't this the same as the first test?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Addressed, was from time where first test was validation something different

}

@Test
void shouldValidateEqualityWhenContentsOfArraysComeFromSameSource() {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This could be more specific than "validate equality", e.g. shouldFindByteArraysAreEqualWithSameSourceArray.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Addressed

}

@Test
void shouldCompareByteArraysCorrectly() {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This test name is too vague, it suggests it's asserting more than it is. I think you wanted to assert that when we wrap two separate arrays containing the same data, they are equal?

}

@Test
void shouldValidateEqualsMethodWithNullObjects() {
Copy link
Collaborator

Choose a reason for hiding this comment

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

A test name should describe the behaviour being asserted, rather than name the method being tested.

ByteArray valid = ByteArray.wrap(new byte[]{'a', 2, 3});

// When / Then
assertThat(ByteArray.equals(valid, null)).isFalse();
Copy link
Collaborator

Choose a reason for hiding this comment

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

It looks like we need a version of these tests for the instance method as well?

I don't think we ever use ByteArray.equals(ByteArray, ByteArray), so it might be simpler to get rid of that and only keep the instance method?

void shouldValidateEqualsMethodsWithDeclaredEmptyArrays() {
// Given
ByteArray first = ByteArray.wrap(null);
ByteArray second = ByteArray.wrap(null);
Copy link
Collaborator

Choose a reason for hiding this comment

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

These aren't empty arrays, they're nulls.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Addressed

@Test
void shouldAllowUsageWithinAHashSet() {
//Give
TreeSet<ByteArray> treeSet = new TreeSet<>();
Copy link
Collaborator

Choose a reason for hiding this comment

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

This isn't a HashSet, it's a TreeSet.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Addressed


import static org.assertj.core.api.Assertions.assertThat;

public class ByteArrayTest {
Copy link
Collaborator

Choose a reason for hiding this comment

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

It doesn't look like we've got any tests for cases where the byte arrays aren't equal, or for using the comparator, e.g. for sorting.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Addresed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Remove Facebook collections library

6 participants