Skip to content

Conversation

@yufeldman
Copy link

…AllocationManager

LowCostIdentityHashMap uses array only to store objects since key (BaseAllocator) is already included in the value (BufferLedger)
To make this class a bit more generic it uses values that implement ValueWithKeyIncluded interface that provides API : getKey()
BufferLedger provides implementation for it.
LowCostIdentityHashMap is not general purpose map it just provides some “map like” APIs to simplify switch over from IdentityHashMap.

* .netty.buffer package.
*/
public class BufferLedger {
public class BufferLedger implements ValueWithKeyIncluded {
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's make ValueWithKeyIncluded be generic so it can return BaseAllocator in this case.

Copy link
Author

Choose a reason for hiding this comment

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

done

/*
* The internal data structure to hold values.
*/
transient Object[] elementData;
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's make all the fields private.

Also, no reason to use transient as we aren't using Java serialization.

Copy link
Author

Choose a reason for hiding this comment

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

done

* differentiate a literal 'null' from an empty spot in the
* map.
*/
private static final Object NULL_OBJECT = new Object(); //$NON-LOCK-1$
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove strange comment

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, let's just not support not null values. Should simplify things.

Copy link
Author

Choose a reason for hiding this comment

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

done

* {@code false} otherwise.
*/
public boolean containsKey(Object key) {
if (key == null) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's just throw exception if use passes in null for key.

Copy link
Author

Choose a reason for hiding this comment

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

done

* @return {@code true} if this map contains the specified value,
* {@code false} otherwise.
*/
public boolean containsValue(Object value) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's make this a typed interface. E.g. containsValue(V value)

Copy link
Author

Choose a reason for hiding this comment

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

I know we don't follow Map iface, but just a note that in Map iface it is:
boolean containsValue(Object value)
If we follow the same pattern of "typing" we may also consider do it for other methods (get, remove, containsKey)

*/
public boolean containsValue(Object value) {
if (value == null) {
value = NULL_OBJECT;
Copy link
Contributor

Choose a reason for hiding this comment

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

As above, let's throw illegal if user tries to look for null value.

Copy link
Author

Choose a reason for hiding this comment

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

done

* @return the value of the mapping with the specified key.
*/
public V get(Object key) {
if (key == null) {
Copy link
Contributor

Choose a reason for hiding this comment

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

disallow nulls

Copy link
Author

Choose a reason for hiding this comment

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

done

* {@code null} if there was no such mapping.
*/
public V put(V value) {
Object _key = value.getKey();
Copy link
Contributor

Choose a reason for hiding this comment

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

Reject an insertion of null here.

Copy link
Author

Choose a reason for hiding this comment

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

done

* Helper Iface to generify a value to be included in the map where
* key is part of the value
*/
public interface ValueWithKeyIncluded {
Copy link
Contributor

Choose a reason for hiding this comment

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

as requested above, let's make this a generic interface so getKey is typed.

Copy link
Author

Choose a reason for hiding this comment

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

done

private final int size;
private final UnsafeDirectLittleEndian underlying;
private final IdentityHashMap<BufferAllocator, BufferLedger> map = new IdentityHashMap<>();
private final LowCostIdentityHasMap<BufferLedger> map = new LowCostIdentityHasMap<>();
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's add comment here on why we use this structure.

Copy link
Author

Choose a reason for hiding this comment

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

done

Copy link
Contributor

@jacques-n jacques-n left a comment

Choose a reason for hiding this comment

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

One small comment, otherwise looks good.

* @param <V>
*/
public class LowCostIdentityHasMap<V extends ValueWithKeyIncluded> {
public class LowCostIdentityHasMap<K, V extends ValueWithKeyIncluded<K>> {
Copy link
Contributor

Choose a reason for hiding this comment

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

No need to declare K since V already declares it.

Copy link
Author

Choose a reason for hiding this comment

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

done

@wesm
Copy link
Member

wesm commented Oct 3, 2017

Can you please rebase? I just rebased master after 0.7.1 release

Copy link
Contributor

@jacques-n jacques-n left a comment

Choose a reason for hiding this comment

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

One general comment/question. Otherwise looks good.

Copy link
Contributor

Choose a reason for hiding this comment

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

Isn't there a way to make this typed without requiring two fields in the class type definition?

Copy link
Author

Choose a reason for hiding this comment

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

The only thing that can be done is : public V get(K key)
But in this case it is quite detached from "K" defined in
ValueWithKeyIncluded

Copy link
Author

@yufeldman yufeldman Oct 3, 2017

Choose a reason for hiding this comment

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

Hmmm - it does not like angle brackets in comments:

public <K> V contains(K key)

Copy link
Contributor

Choose a reason for hiding this comment

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

same question as above

Copy link
Author

Choose a reason for hiding this comment

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

The only thing that can be done is : public V get(K key)
But in this case it is quite detached from "K" defined in
ValueWithKeyIncluded

Copy link
Author

Choose a reason for hiding this comment

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

Hmmm - it does not like angle brackets in comments:

public <K> V get(K key)

Copy link
Contributor

Choose a reason for hiding this comment

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

we can remove this function, right?

Copy link
Author

Choose a reason for hiding this comment

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

sure

Copy link
Contributor

Choose a reason for hiding this comment

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

should this be equals() since we're comparing values?

Copy link
Author

Choose a reason for hiding this comment

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

not really - IdentityHashMap compares references for both keys and values. Unless we want to change the behavior

Copy link
Contributor

@jacques-n jacques-n left a comment

Choose a reason for hiding this comment

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

Lgtm. +1 Thanks @yufeldman!

…AllocationManager

LowCostIdentityHashMap uses array only to store objects since key (BaseAllocator) is already included in the value (BufferLedger)
To make this class a bit more generic it uses values that implement ValueWithKeyIncluded interface that provides API : getKey()
BufferLedger provides implementation for it.
LowCostIdentityHashMap is not general purpose map it just provides some “map like” APIs to simplify switch over from IdentityHashMap.

ARROW-1627: Small improvement in hashing function.

ARROW-1627: Addressing review comments
@wesm
Copy link
Member

wesm commented Oct 5, 2017

Merging, thanks for your contribution @yufeldman!

@asfgit asfgit closed this in dc129d6 Oct 5, 2017
yufeldman pushed a commit to yufeldman/arrow that referenced this pull request Oct 5, 2017
…AllocationManager

LowCostIdentityHashMap uses array only to store objects since key (BaseAllocator) is already included in the value (BufferLedger)
To make this class a bit more generic it uses values that implement ValueWithKeyIncluded interface that provides API : getKey()
BufferLedger provides implementation for it.
LowCostIdentityHashMap is not general purpose map it just provides some “map like” APIs to simplify switch over from IdentityHashMap.

Author: Yuliya Feldman <yuliya@dremio.com>

Closes apache#1150 from yufeldman/ARROW-1627-master and squashes the following commits:

dcd5e29 [Yuliya Feldman] ARROW-1627: New class to handle collection of BufferLedger(s) within AllocationManager LowCostIdentityHashMap uses array only to store objects since key (BaseAllocator) is already included in the value (BufferLedger) To make this class a bit more generic it uses values that implement ValueWithKeyIncluded interface that provides API : getKey() BufferLedger provides implementation for it. LowCostIdentityHashMap is not general purpose map it just provides some “map like” APIs to simplify switch over from IdentityHashMap.
@sadikovi
Copy link
Contributor

sadikovi commented Nov 29, 2017

@wesm Should it be LowCostIdentityHasMap -> LowCostIdentityHashMap as class name?

@yufeldman
Copy link
Author

Good catch - spelling error

@sadikovi
Copy link
Contributor

Would it be okay to just open small PR without JIRA to fix this?

wesm pushed a commit that referenced this pull request Nov 29, 2017
JIRA: https://issues.apache.org/jira/browse/ARROW-1869

This PR fixes spelling error in class name for `LowCostIdentityHashMap`.
Follow-up for #1150.

Author: Ivan Sadikov <ivan.sadikov@team.telstra.com>

Closes #1372 from sadikovi/fix-low-cost-identity-hash-map and squashes the following commits:

e3529f6 [Ivan Sadikov] fix low cost identity hash map name
wesm pushed a commit that referenced this pull request Dec 1, 2017
JIRA: https://issues.apache.org/jira/browse/ARROW-1869

This PR fixes spelling error in class name for `LowCostIdentityHashMap`.
Follow-up for #1150.

Author: Ivan Sadikov <ivan.sadikov@team.telstra.com>

Closes #1372 from sadikovi/fix-low-cost-identity-hash-map and squashes the following commits:

e3529f6 [Ivan Sadikov] fix low cost identity hash map name
pribor pushed a commit to GlobalWebIndex/arrow that referenced this pull request Oct 24, 2025
…AllocationManager

LowCostIdentityHashMap uses array only to store objects since key (BaseAllocator) is already included in the value (BufferLedger)
To make this class a bit more generic it uses values that implement ValueWithKeyIncluded interface that provides API : getKey()
BufferLedger provides implementation for it.
LowCostIdentityHashMap is not general purpose map it just provides some “map like” APIs to simplify switch over from IdentityHashMap.

Author: Yuliya Feldman <yuliya@dremio.com>

Closes apache#1150 from yufeldman/ARROW-1627-master and squashes the following commits:

dcd5e29 [Yuliya Feldman] ARROW-1627: New class to handle collection of BufferLedger(s) within AllocationManager LowCostIdentityHashMap uses array only to store objects since key (BaseAllocator) is already included in the value (BufferLedger) To make this class a bit more generic it uses values that implement ValueWithKeyIncluded interface that provides API : getKey() BufferLedger provides implementation for it. LowCostIdentityHashMap is not general purpose map it just provides some “map like” APIs to simplify switch over from IdentityHashMap.
pribor pushed a commit to GlobalWebIndex/arrow that referenced this pull request Oct 24, 2025
JIRA: https://issues.apache.org/jira/browse/ARROW-1869

This PR fixes spelling error in class name for `LowCostIdentityHashMap`.
Follow-up for apache#1150.

Author: Ivan Sadikov <ivan.sadikov@team.telstra.com>

Closes apache#1372 from sadikovi/fix-low-cost-identity-hash-map and squashes the following commits:

e3529f6 [Ivan Sadikov] fix low cost identity hash map name
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.

4 participants