-
Notifications
You must be signed in to change notification settings - Fork 690
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
reusing empty NamedList rather than recreating a new empty NamedList … #2932
reusing empty NamedList rather than recreating a new empty NamedList … #2932
Conversation
…every time the facet.field parameter is empty
@dsmiley this looks related to your named list vs simple map thread on dev list |
@madrob do you have a link to the mention thread? |
My general opinion here is wondering it it worth bothering with the micro optimization of using a shared instance. And more importantly, there is no immutable NamedList so I'm uncomfortable with introducing a shared mutable instance. |
@dsmiley I do get your point that a shared instance should be immutable. I could instantiate the shared empty instances with an immutable list, similar to what we do here: For my understanding: What is the purpose of SimpleOrderedMap, it is just to control the output format of the response writers? |
Yes, it's about the response format but moreover it communicates that keys do not (well technically "should" not) repeat. It's tempting to actually implement Map on this thing. |
Not being very familiar with the Solr source code, this construct with NamedList and SimpleOrderedMap is pretty confusing to me. Back in 2006 NamedList had the following todo on it:
But this one got removed at one point |
NamedList and thus SimpleOrderedMap is ordered (insertion order). HashMap is called HashMap because it explains its implementation via use of the hashCode() and thus get(key) is |
Thanks for the explanation. |
Adding an additional HashMap inside SimpleOrderedMap misses the point of why NamedList exists. It's for something super lean/fast that's only for transferring stuff (i.e. to be serialized), navigated by iteration once. For that use-case, a hashCode system is a waste. But Solr uses it for configuration as well, a questionable choice that's not in line with NamedList's advantages. Perhaps a radical point of view is that NamedList shouldn't even have "get" methods, leaving only iteration, thus emphasizing its purpose. For sure, Solr over-uses NamedList. And it's hard to stop using it because of SolrJ "javabin" compatibility. |
@@ -34,6 +35,8 @@ | |||
* serialized. It aims to minimize overhead and to be efficient at adding new elements. | |||
*/ | |||
public class SimpleOrderedMap<T> extends NamedList<T> { | |||
|
|||
private static final SimpleOrderedMap<Object> emptySimpleOrderedMap = new SimpleOrderedMap<>(Collections.emptyList()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
call it EMPTY ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also nowadays we just do List.of()
which is equivalent, shorter, and doesn't import another class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
" and doesn't import another class." Never thought of that advantages of List.of over Collections.empty(). Good point, will adjust it!
@@ -67,4 +70,8 @@ public SimpleOrderedMap<T> clone() { | |||
newList.addAll(nvPairs); | |||
return new SimpleOrderedMap<>(newList); | |||
} | |||
|
|||
public static SimpleOrderedMap<Object> emptySimpleOrderedMap() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs a javadoc. And that name is quite redundant given the type where we're declaring this.
WDYT of naming this simply of
thus mimicking the end effect of List.of()
or Set.of()
or Map.of()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The method name of() is implying, at least to me, that something can be passed in and and creates something else out of it. Like when you do List.of("String"). Maybe empty() would be the better option. What do you thing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using of
opens the door for some more static methods for more, which you could add now if it makes of
more attractive to you. Just a single pair would be fine and perhaps useful. I look to the JDK for inspiration on data structure conventions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, I see you point regarding of() vs empty(). I looked at how it is done on the List and have implemented some more of()-method for 1,2 and n-elements. what do you think?
/** | ||
* Returns an immutable instance of SimpleOrderedMap with a single element. | ||
* @return List containing the elements | ||
*/ | ||
public static SimpleOrderedMap<Object> of(Object o1) { | ||
return new SimpleOrderedMap<>(List.of(o1)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is illogical; the list should be key-value pairs. SimpleOrderedMap is fundamentally a Map. Look at Map's static "of" methods for inspiration.
* Returns an immutable instance of SimpleOrderedMap with two elements. | ||
* @return List containing the elements | ||
*/ | ||
public static SimpleOrderedMap<Object> of(Object o1, Object o2) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
named key and value, thus logically one pair
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
of course, was confused by the fact it internally holds a List t store the values.
Do you think it still makes sense to have and of for two key-value pairs e.g. like this:
of(String name1, Object val1, String name2, Object val2)
Looking at Map.of, I think it would also make to use type inference rather than , like this:
public static SimpleOrderedMap of(String name, T val)
What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Basically, if Map has it, we can to.
Any way, I also think we shouldn't over-invest in SimpleOrderedMap without callers of these methods.
* Returns an immutable instance of SimpleOrderedMap with an arbitrary number of elements. | ||
* @return List containing the elements | ||
*/ | ||
public static SimpleOrderedMap<Object> of(Object... elements) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Map.of has no similar array based argument so I suggest not doing the same here. Presumably the key and value distinction then becomes less obvious; easier to misuse.
) SimpleFacets: use this, avoiding needless new NamedList creation tidy (cherry picked from commit 6c02da2)
Also merged to branch_9x thus will appear in Solr 9.9. |
If you're interested: https://issues.apache.org/jira/browse/SOLR-17623 |
sure, i will give it a go. |
Yes; simply add methods to SimpleOrderedMap. JIRA: Should be in the header of the page: https://selfserve.apache.org/jira-account.html |
For every call with face=true which is not providing any facet.fields, we do create an empty NamedList.
Having a single instance of an empty NamedList feels like the more efficient approach to me.