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

SOLR-17623: Simple ordered map should implement map #3048

Merged

Conversation

renatoh
Copy link
Contributor

@renatoh renatoh commented Jan 20, 2025

https://issues.apache.org/jira/browse/SOLR-17623

Implementing the interface Map on SimpleOrderedMap and adding Unit-Test for the new methods

@epugh
Copy link
Contributor

epugh commented Jan 20, 2025

Nitpicky, but can you title the PR SOLR-17623:, that is the style we use...

@renatoh
Copy link
Contributor Author

renatoh commented Jan 20, 2025

@dsmiley Could you please have a look at the implementation oaf the method from the Map interface?
Also, I had to make a few adjustment to other parts in the code to make it work with the new methods.
I need to add java-doc and tidy up the unit-tests but would be good to get some feedback before I take care of that.
Thanks

@renatoh renatoh changed the title Solr 17623 simple ordered map should implement map Solr 17623: Simple ordered map should implement map Jan 20, 2025
@renatoh
Copy link
Contributor Author

renatoh commented Jan 20, 2025

I am curious if there is a way to implement values() and entrySet(0 without an unchecked cast, e.g. (T) nvPairs.get(i)

@dsmiley
Copy link
Contributor

dsmiley commented Jan 20, 2025

As the PR template indicates, the PR title must use exactly the JIRA syntax. Thus all-caps and hyphen separating SOLR and 17623, probably then a colon. If you do it correctly, moments later a bot will update the JIRA to link to the PR. (albeit sometimes the bot is delayed inexplicably)

import org.junit.Assert;
import org.junit.Test;

public class SimpleOrderedMapTest extends Assert {
Copy link
Contributor

Choose a reason for hiding this comment

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

No; in Solr we extend SolrTestCase at a minimum for a unit test

@renatoh renatoh changed the title Solr 17623: Simple ordered map should implement map SOLR-17623: Simple ordered map should implement map Jan 20, 2025
@dsmiley
Copy link
Contributor

dsmiley commented Jan 21, 2025

I am curious if there is a way to implement values() and entrySet(0 without an unchecked cast, e.g. (T) nvPairs.get(i)

Almost nobody could answer a cast question like that without literally working on it in their IDE. I'll take a look at a future iteration of yours but meanwhile, don't worry about it -- it's not important.

@renatoh
Copy link
Contributor Author

renatoh commented Jan 21, 2025

@dsmiley Considering your improvements on NamedList..asShallowMap, could I just delegate the method keySet, values and entrySet to the shallowMap e.g. :

public Collection values() {
return super.asShallowMap(true).values();
}

@dsmiley
Copy link
Contributor

dsmiley commented Jan 21, 2025

I would implement the methods here, copying bits of code from #3050 if needed so that you don't call NamedList.asShallowMap. Take from that whatever you want. I'm not sure NamedList.asShallowMap was a wise idea since it can't implement the Map contract if the keys repeat. It might have pre-dated SimpleOrderedMap. Assuming you finish the PR here, I'm inclined to maybe make NamedList.asShallowMap do an instanceof check for SimpleOrderedMap and if so return "this" but otherwise throw an exception. Or remove it. Ideally we only use NamedList that isn't SimpleOrderedMap for the rare cases where it's appropriate.

@renatoh
Copy link
Contributor Author

renatoh commented Jan 23, 2025

@dsmiley Please have another look, thanks!

Copy link
Contributor

@dsmiley dsmiley left a comment

Choose a reason for hiding this comment

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

As part of this PR, let's have NamedList.asShallowMap do an instanceof check for Map and return it if so. That will lead to real usage / code coverage of the changes you've done.

}

/**
* Returns a shared, empty, and immutable instance of SimpleOrderedMap.
* Returns {@code true} if this map maps one or more keys to the specified value.
Copy link
Contributor

Choose a reason for hiding this comment

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

"one or more" -- why more? Any way, don't feel obliged to re-specify javadocs for interface implementations since it's automatically inherited.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

the java-doc is automatically inherited? isn't that only the case if I use the {@inheritdoc} tag in the java doc itself. And even then, it does not inherit the param, return and throw part of the java-doc, unless I tag them one by one. Nevertheless, I will move to {@inheritdoc} where possible, in order not to repeat java doc.
With respect to "one or more", I did not come up with that phrasing, that is on Map#contains, and although it sounds strange, it is technically correct.

Copy link
Contributor

Choose a reason for hiding this comment

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

If we don't have anything extra to say beyond the default javadoc, then add nothing at all (no javadoc). If you want to add a tidbit of extra info to say something O(N) then you can use {@inheritDoc} and add the sentence. But I think you could just augment the class level javadocs to warn users about usage of this as a general Map for large maps.

return EMPTY;
@Override
public boolean containsValue(final Object value) {
int sz = size();
Copy link
Contributor

Choose a reason for hiding this comment

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

instead of all these lines, could be a one-liner values().contains(value). It'll be rare if ever for any Solr code to call this.

}

/**
* Returns a shared, empty, and immutable instance of SimpleOrderedMap.
* Returns {@code true} if this map maps one or more keys to the specified value.
Copy link
Contributor

Choose a reason for hiding this comment

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

If we don't have anything extra to say beyond the default javadoc, then add nothing at all (no javadoc). If you want to add a tidbit of extra info to say something O(N) then you can use {@inheritDoc} and add the sentence. But I think you could just augment the class level javadocs to warn users about usage of this as a general Map for large maps.

solr/solrj/build.gradle Outdated Show resolved Hide resolved
Copy link
Contributor

@dsmiley dsmiley left a comment

Choose a reason for hiding this comment

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

Looks good; thank you! Just needs a CHANGES.txt entry.

My hope is for NamedList.asShallowMap's implementation to go away, ultimately mandating that if you want a Map, you must have a SimpleOrderedMap. That can be a separate issue/PR.

solr/solrj/build.gradle Outdated Show resolved Hide resolved
@renatoh
Copy link
Contributor Author

renatoh commented Jan 29, 2025

As part of this PR, let's have NamedList.asShallowMap do an instanceof check for Map and return it if so. That will lead to real usage / code coverage of the changes you've done.

Wouldn't it be a better approach just to override asShallowMap in SimpleOrderedMap and return itself?
Additionally,I have noticed that org.apache.solr.common.util.NamedList#asShallowMap(boolean) is not called outside NamedList, do we want to set it to private?

@dsmiley
Copy link
Contributor

dsmiley commented Jan 29, 2025

Wouldn't it be a better approach just to override asShallowMap in SimpleOrderedMap and return itself?

:face-palm: of course; wow I have no excuse for myself. Not enough coffee maybe.

Additionally,I have noticed that org.apache.solr.common.util.NamedList#asShallowMap(boolean) is not called outside NamedList, do we want to set it to private?

Separately in another issue/pr, NamedList needs some more attention around this and toMap. Definitely deprecating that one.

@renatoh
Copy link
Contributor Author

renatoh commented Jan 29, 2025

Separately in another issue/pr, NamedList needs some more attention around this and toMap. Definitely deprecating that one.

I interpreted you thumbs up on my comment early as OK for both of the issue mentioned, hence I committed and pushed it, was too quick:). Shall I revert it?

Copy link
Contributor

@dsmiley dsmiley left a comment

Choose a reason for hiding this comment

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

I have a slight concern if there's existing code relying on quirky sad behaviors of NamedList.asShallowMap having weird/sad implementations of keySet, values, entrySet because it calls asMap(1) on them. Had it been asMap(0), probably lower/no concern. Maybe this change should be in Solr 10 only. On the other hand... maybe it's an unlikely impact? Hard to say... right away I see SolrXmlConfig calling .asShallowMap().entrySet().

@@ -238,6 +238,14 @@ public int indexOf(String name, int start) {
return -1;
}

/***
* Scans the list sequentially beginning at index 0
Copy link
Contributor

Choose a reason for hiding this comment

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

nitpick: javadoc should include clarity that it's the index of the name. It's not great to require looking at a parameter's name to disambiguate the meaning of a method.

@@ -403,8 +411,8 @@ public Map<String, T> asShallowMap() {
return asShallowMap(false);
}

public Map<String, T> asShallowMap(boolean allowDps) {
return new Map<String, T>() {
private Map<String, T> asShallowMap(boolean allowDps) {
Copy link
Contributor

Choose a reason for hiding this comment

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

now's not the time to make private but feel free to deprecate.

}

@Override
public Map<String, T> asShallowMap() {
Copy link
Contributor

Choose a reason for hiding this comment

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

nitpick but place this up above implementing Map interfaces rather than arbitrarily somewhere in the middle.

@renatoh
Copy link
Contributor Author

renatoh commented Jan 29, 2025

Just needs a CHANGES.txt entry.

I've added that under Solr 9.9.0, is that correct?

@renatoh
Copy link
Contributor Author

renatoh commented Jan 29, 2025

have a slight concern if there's existing code relying on quirky sad behaviors of NamedList.asShallowMap having weird/sad implementations of keySet, values, entrySet because it calls asMap(1) on them. Had it been asMap(0), probably lower/no concern. Maybe this change should be in Solr 10 only. On the other hand... maybe it's an unlikely impact? Hard to say... right away I see SolrXmlConfig calling .asShallowMap().entrySet().

Isn't SolrXmlConfig always calling .asShallowMap on a NamedList, which is created in org.apache.solr.common.ConfigNode#forEachChild? So the changes do not make a difference here, or do they?

@dsmiley
Copy link
Contributor

dsmiley commented Jan 30, 2025

I removed the asShallowMap returning SimpleOrderedMap so such a decision can be in Solr 10.
I intend on merging this when the tests pass and back porting to 9x. Today/tomorrow.
Thanks again for your contribution!

@renatoh
Copy link
Contributor Author

renatoh commented Jan 30, 2025

I removed the asShallowMap returning SimpleOrderedMap so such a decision can be in Solr 10. I intend on merging this when the tests pass and back porting to 9x. Today/tomorrow. Thanks again for your contribution!

You are welcome, thanks for your support!

Now it is failing with:
Detected license header issues (skip with -Pvalidation.rat.failOnError=false):
Unknown license: /home/runner/work/solr/solr/solr/solrj/src/test/org/apache/solr/common/util/SimpleOrderedMapTest.java

No idea what this means

@dsmiley
Copy link
Contributor

dsmiley commented Jan 30, 2025

As you are a very new contributor, I can tell by your changes and your last question that you have not been running ./gradlew precommit, which will detect issues that you can correct before pushing.
BTW all source files need a header. IntelliJ does it automatically for me, as I've configured it to.

@renatoh
Copy link
Contributor Author

renatoh commented Jan 31, 2025

As you are a very new contributor, I can tell by your changes and your last question that you have not been running ./gradlew precommit, which will detect issues that you can correct before pushing.
BTW all source files need a header. IntelliJ does it automatically for me, as I've configured it to.

Ah yes, I've forgot about that one, was for some reason under the impression running the 'tidy' is sufficient, now I know:)

@dsmiley dsmiley merged commit dac5fe1 into apache:main Jan 31, 2025
4 checks passed
dsmiley pushed a commit that referenced this pull request Jan 31, 2025
Also added NamedList.indexOf(name) convenience method.

Does *not* adjust asShallowMap() yet.  Coming soon.

---------

Co-authored-by: David Smiley <[email protected]>
(cherry picked from commit dac5fe1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants