Skip to content

Refactoring to use CollectionUtils.mapValues#8059

Merged
clintropolis merged 10 commits intoapache:masterfrom
surekhasaharan:overhsadowed-segments-follow-up
Jul 18, 2019
Merged

Refactoring to use CollectionUtils.mapValues#8059
clintropolis merged 10 commits intoapache:masterfrom
surekhasaharan:overhsadowed-segments-follow-up

Conversation

@surekhasaharan
Copy link
Copy Markdown

Description

This PR has some follow-ups changes left from #7595. Some minor doc updates and code updates to use CollectionUtils.mapValues and CollectionUtils.mapKeys utility methods.

This PR has:

  • been self-reviewed.
  • added Javadocs for most classes and all non-trivial methods. Linked related entities via Javadoc links.

@surekhasaharan surekhasaharan added this to the 0.16.0 milestone Jul 11, 2019


@Override
@SuppressWarnings("SSBasedInspection")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

When suppressing SSBasedInspection, please always add a comment -- what specifically you suppress (mapValues() in this case), and why -- it's not obvious for me in this case.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

ah, so i suppressed this, since the valueMapper function of CollectionUtils.mapValues() is not independent in this situation and needs map's key. May be there is a way around this, but was not clear to me, let me know if you have any suggestion so that i can remove the suppression.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I see, thanks.

);
versions = locks.entrySet().stream()
.collect(Collectors.toMap(Entry::getKey, entry -> entry.getValue().getVersion()));
versions = CollectionUtils.mapValues(locks, v -> v.getVersion());
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It's more readable to use method references in such cases because it makes evident the type of the value: versions = CollectionUtils.mapValues(locks, TaskLock::getVersion);. Or, it's better to choose more descriptive lambda param names (e. g. taskLock) than just v.

Same applies to many other places in this PR.

<constraint name="k" within="" contains="" />
<constraint name="__context__" target="true" within="" contains="" />
</searchConfiguration>
<searchConfiguration name="Use CollectionUtils.mapValues(Map&lt;k,v&gt;, Function&lt;v,v2&gt;)" text="$x$.entrySet().stream().collect(Collectors.toMap(Entry::getKey, $y$))" recursive="true" caseInsensitive="true" type="JAVA">
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please add patterns for mapKeys()

public static <K, V, K2> Map<K2, V> mapKeys(Map<K, V> map, Function<K, K2> keyMapper)
{
final Map<K2, V> result = Maps.newHashMapWithExpectedSize(map.size());
map.forEach((k, v) -> result.put(keyMapper.apply(k), v));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think it's better if this method fails with IllegalStateException on keys collisions if the key mapper is not a bijection, similar to ImmutableMap.Builder. This should also be reflected in the method's javadoc.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Added a check for key collisions with keyMapper.

map.forEach((k, v) -> result.put(keyMapper.apply(k), v));
map.forEach((k, v) -> {
final K2 k2 = keyMapper.apply(k);
if (result.containsKey(k2)) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please make just one lookup operation for every key: putIfAbsent().

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@surekhasaharan the idea of this replacement was to get rid of containsKey() call, so that only one lookup operation (putIfAbsent() itself) is done on each iteration instead of two (containsKey() and put()):

if (result.putIfAbsent(k2, v) != null) {
  throw new ISE("Conflicting key[%s] calculated via keyMapper for original key[%s]", k2, k);
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

i see, fixed.

*
* @throws ISE if key collisions occur while applying specified keyMapper
*/

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Extra line

Copy link
Copy Markdown
Member

@leventov leventov left a comment

Choose a reason for hiding this comment

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

Thanks for following up

Copy link
Copy Markdown
Member

@clintropolis clintropolis left a comment

Choose a reason for hiding this comment

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

this is very nice 🤘

@clintropolis clintropolis merged commit da16144 into apache:master Jul 18, 2019
@surekhasaharan surekhasaharan deleted the overhsadowed-segments-follow-up branch July 18, 2019 17:56
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.

3 participants