Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Discussion: Support adding in an accumulo-access expression to a column visibility #5293

Draft
wants to merge 2 commits into
base: 2.1
Choose a base branch
from

Conversation

ddanielr
Copy link
Contributor

Includes changes from #5217

This PR adds a new dependency to 2.1.4 which I'm not sure we want to do.
Using this PR to evaluate ColumnVisibility usages in 2.1 to think through performance concerns.

Merging this requires conversation about if we want to do this in 2.1 vs maybe doing a 2.2 release to use as a stepping stone.

@ddanielr ddanielr force-pushed the feature/support-accumulo-access branch from 16c43a9 to 9cd07f5 Compare January 29, 2025 17:09
*/
public ColumnVisibility(AccessExpression expression) {
// AccessExpression is a validated immutable object, so no need to re validate
this.expression = expression.getExpression().getBytes(UTF_8);
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this just an optimization, or does calling validate cause an issue? A client could use AccessExpression's and then create a ColumnVisibilty using the byte[] constructor.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is an optimization to avoid calling validate for performance reasons. If an AccessExpression is passed in then it has already performed a validate operation previous and does not need to parse the expression.

Copy link
Contributor

@dlmarion dlmarion Jan 29, 2025

Choose a reason for hiding this comment

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

We could add a constructor (byte[]) then that doesn't perform validation, mark it deprecated, and in the javadoc:

  1. that this constructor was added for clients that want to use Accumulo-Access before Accumulo 4.0
  2. this will be removed in 4.0
  3. using this incorrectly (with an invalid column visibility) will likely cause exceptions and no data to be returned

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm thinking that the above approach may be a good compromise to allow Accumulo-Access to be used with 2.1 without introducing the dependency in a patch release.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I like that approach.

Copy link
Contributor

Choose a reason for hiding this comment

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

Considering that we already have a ColumnVisibility(byte[]) constructor, we would likely need to create a ColumnVisibility(byte[], boolean) constructor.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Considering that we already have a ColumnVisibility(byte[]) constructor, we would likely need to create a ColumnVisibility(byte[], boolean) constructor.

I added that constructor but made it private. Then I added a new static method to use the private constructor called fromAccessExpression so that creation of these unvalidated ColumnVisibilities is very explicit.

public static ColumnVisibility fromAccessExpression(byte[] incomingExpression) {
    return new ColumnVisibility(incomingExpression, false);
  }

The name should probably be changed, so I'm open to suggestions.

Adds a new constructor that supports an AccessExpression.
Also adds deep copy method for existing ColumnVisibilities.
@ddanielr ddanielr force-pushed the feature/support-accumulo-access branch from 9cd07f5 to 1645738 Compare January 29, 2025 19:14
Removes accumulo-access and adds new private constructor that allows
validation to be skipped.

Created new static method to generate an unvalidated ColumnVisibility
* @param expression visibility expression, encoded as UTF-8 bytes
* @param validate enables or disables validation and parse tree generation
*/
private ColumnVisibility(byte[] expression, boolean validate) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

need to change the validate variable name to avoid conflicting with the validate method

public ColumnVisibility(ColumnVisibility visibility) {
byte[] incomingExpression = visibility.expression;
this.expression = Arrays.copyOf(incomingExpression, incomingExpression.length);
this.node = new Node(visibility.node);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This constructor is still needed since it also copies the parse tree from the original ColVis

Copy link
Contributor

Choose a reason for hiding this comment

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

I think there is an issue here with the parse tree being mutable. Given that ColumnVisibility's can be cached, and that the parse tree is mutable, it's possible that the parse tree could be mutating in another thread while this copy constructor is called. I'm not sure how to resolve this issue. Using the Cloneable interface and adding a clone method doesn't fully solve this issue either. I think this issue exists in #5217 as well.

Copy link
Contributor

Choose a reason for hiding this comment

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

It's possible that doing the following may help the issue I raised above:

  1. Modify Node.children to be Collections.synchronizedList(new ArrayList<>()) in Node.add
  2. synchronize on visibility.node in the copy constructor

@@ -238,6 +239,15 @@ public void testParseTreesOrdering() {
assertTrue(flat.indexOf('b') < flat.indexOf('a'), "shortest children sort first");
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Need to add test cases for new constructors.

validate(expression);
} else {
this.expression = Arrays.copyOf(expression, expression.length);
this.node = EMPTY_NODE;
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the expression needs to be parsed to populate node otherwise we run into issues in other areas of the code. For example, here in VisibilityEvaluator an Exception will be thrown. Here in NodeComparator all ColumnVisibilities that are created this way will be "equal".

public ColumnVisibility(ColumnVisibility visibility) {
byte[] incomingExpression = visibility.expression;
this.expression = Arrays.copyOf(incomingExpression, incomingExpression.length);
this.node = new Node(visibility.node);
Copy link
Contributor

Choose a reason for hiding this comment

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

I think there is an issue here with the parse tree being mutable. Given that ColumnVisibility's can be cached, and that the parse tree is mutable, it's possible that the parse tree could be mutating in another thread while this copy constructor is called. I'm not sure how to resolve this issue. Using the Cloneable interface and adding a clone method doesn't fully solve this issue either. I think this issue exists in #5217 as well.

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.

2 participants