-
Notifications
You must be signed in to change notification settings - Fork 4k
ARROW-7329: [Java] AllocationManager: Allow managing different types … #5973
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
Conversation
…of memory other than those are allocated using Netty
|
Nice work. Can you make a change so that allocationmanager is the base class and NettyAllocationManager is the subclass? Will make this much easier to review and track history. |
|
@jacques-n - Sure, will do. I was to avoid breaking change to AllocationManager, but not sure if it's necessary. Thanks for your suggestion. |
fbeae99 to
1e6e844
Compare
4890805 to
4ba7796
Compare
| // which now has been removed, it implies we can safely destroy the | ||
| // underlying memory chunk as it is no longer being referenced | ||
| ((BaseAllocator)oldLedger.getAllocator()).releaseBytes(size); | ||
| ((BaseAllocator)oldLedger.getAllocator()).releaseBytes(getSize()); |
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.
why the change?
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 to keep up with the current behaviour. Following is the constructor code of current AllocationManager:
arrow/java/memory/src/main/java/org/apache/arrow/memory/AllocationManager.java
Lines 73 to 84 in 21a4ffe
| AllocationManager(BaseAllocator accountingAllocator, int size) { | |
| Preconditions.checkNotNull(accountingAllocator); | |
| accountingAllocator.assertOpen(); | |
| this.root = accountingAllocator.root; | |
| this.memoryChunk = INNER_ALLOCATOR.allocate(size); | |
| // we do a no retain association since our creator will want to retrieve the newly created | |
| // ledger and will create a reference count at that point | |
| this.owningLedger = associate(accountingAllocator, false); | |
| this.size = memoryChunk.capacity(); | |
| } |
This allows an AllocationManager allocates different bytes of memory comparing to desired. So at here, size is desired size passed by constructor, while getSize() should be the actual size. I'll do some name changes in case of confusing.
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.
If size and getSize() are different, maybe this should be made explicit in the JavaDoc?
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.
yeah, maybe call one requested_size and one size (or similar)
| /** | ||
| * Release the underling memory chunk. | ||
| */ | ||
| abstract void release0(); |
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.
protected?
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.
I was thinking to force the implementations to be packaged under org.apache.arrow.memory... Which doesn't seem to be necessary.
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.
Done. Also changed memoryAddress() and constructor.
| } | ||
|
|
||
| /** | ||
| * All {@link AllocationManager} instances created are defaulted to Netty implementation. |
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.
comment arguemnts
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.
Done.
| * chunk. In that case, the ledger should inform the allocation manager | ||
| * about releasing its ownership for the chunk. Whether or not the memory | ||
| * chunk will be released is something that {@link AllocationManager} will | ||
| * chunk will be released is something that {@link NettyAllocationManager} will |
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.
why change?
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.
Seems to be mistake. Thanks for catch.
|
|
||
| @Override | ||
| protected AllocationManager newAllocationManager(BaseAllocator accountingAllocator, int size) { | ||
| // to expect consistent behavior with parent on creating allocation managers |
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 kind of wonky. Let's have a factory instead.
java/memory/src/main/java/org/apache/arrow/memory/AllocationManager.java
Show resolved
Hide resolved
25d8a27 to
017f31a
Compare
017f31a to
98901aa
Compare
1e7a187 to
1e7f21b
Compare
| /** | ||
| * Returns a builder class for configuring BaseAllocator's options. | ||
| */ | ||
| public static ConfigBuilder configBuilder() { |
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.
Can you add Immutables to the project and use that instead. Should allow us to avoid creation/management of builders. I've started using it in another project and found it quite helpful at avoiding lots of scaffolding code.
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.
Let's add a new method which is
T unwrap(Class clazz)
Done.
Can you add Immutables to the project and use that instead.
Thanks for suggesting Immutables, I have tried and it works pretty well. The only thing I am worried about is it slightly increases the development complexity.
Done.
| @Test | ||
| public void testAllocator_childRemovedOnClose() throws Exception { | ||
| try (final RootAllocator rootAllocator = new RootAllocator(MAX_ALLOCATION)) { | ||
| try (final RootAllocator rootAllocator = createRootAllocator(MAX_ALLOCATION)) { |
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.
let's avoid this change
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.
Agreed. Something is over-tested.
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.
Done.
This reverts commit 8a54af4.
7fbd438 to
9e8b348
Compare
9e8b348 to
81b1076
Compare
jacques-n
left a comment
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.
Sorry I missed coming back to this. This LGTM. Thanks for pulling it to completion.
+1
lidavidm
left a comment
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.
Just some quick general questions - I'm willing to go ahead and merge this though if nobody else gets to it.
| <groupId>org.slf4j</groupId> | ||
| <artifactId>slf4j-api</artifactId> | ||
| </dependency> | ||
| <dependency> |
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.
Is it worth taking a dependency for a single builder? At the very least, let's file a follow-up to see if we can replace any other builders in the project with Immutables as well.
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.
I second the idea to factor other builders. So far I didn't have a check but we may make relevant changes in other issue/pr.
And I don't think the new dependency matters much as it's a single jar library and it is not needed in runtime.
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.
I think this would be useful elsewhere. For example, we should really use it for the *.pojo classes. Also, as mentioned, this isn't used/required at runtime
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.
Ah - my mistake, non-runtime dependencies are even better.
| import static org.junit.Assert.assertTrue; | ||
| import static org.junit.Assert.fail; | ||
|
|
||
| import static org.junit.Assert.*; |
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.
Please expand this to avoid style errors.
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 but It's weird that I didn't see any style errors on this.
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.
Done
|
|
||
| private static final PooledByteBufAllocatorL INNER_ALLOCATOR = new PooledByteBufAllocatorL(); | ||
| static final UnsafeDirectLittleEndian EMPTY = INNER_ALLOCATOR.empty; | ||
| static final long CHUNK_SIZE = INNER_ALLOCATOR.getChunkSize(); |
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.
It seems this is not used.
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.
Actually it is used in DefaultRoundingPolicy via reflection:
arrow/java/memory/src/main/java/org/apache/arrow/memory/rounding/DefaultRoundingPolicy.java
Lines 39 to 47 in 7bd4e73
| private DefaultRoundingPolicy() { | |
| try { | |
| Field field = AllocationManager.class.getDeclaredField("CHUNK_SIZE"); | |
| field.setAccessible(true); | |
| chunkSize = (Long) field.get(null); | |
| } catch (Exception e) { | |
| throw new RuntimeException("Failed to get chunk size from allocation manager"); | |
| } | |
| } |
jacques-n
left a comment
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.
I think this looks good. The size thing could be dealt with in a follow-on.
+1
| <groupId>org.slf4j</groupId> | ||
| <artifactId>slf4j-api</artifactId> | ||
| </dependency> | ||
| <dependency> |
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.
I think this would be useful elsewhere. For example, we should really use it for the *.pojo classes. Also, as mentioned, this isn't used/required at runtime
| // which now has been removed, it implies we can safely destroy the | ||
| // underlying memory chunk as it is no longer being referenced | ||
| ((BaseAllocator)oldLedger.getAllocator()).releaseBytes(size); | ||
| ((BaseAllocator)oldLedger.getAllocator()).releaseBytes(getSize()); |
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.
yeah, maybe call one requested_size and one size (or similar)
|
|
||
| @Override | ||
| public BufferAllocator getParentAllocator() { | ||
| public BaseAllocator getParentAllocator() { |
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.
It is okay to expose here as long as the BufferAllocator interface is BufferAllocator.
|
I'll go ahead and merge, then file an issue to clarify the naming. Thanks @zhztheplayer for carrying this through! |
|
I filed https://issues.apache.org/jira/browse/ARROW-7538 for the actual vs desired size clarification. |
|
Thanks for everyone's review! |
This is a follow up on #5973. Closes #6204 from walterddr/ARROW-7538 and squashes the following commits: 15878d1 <Rong Rong> revert change and make API still public 10547bf <Rong Rong> address patch comment 97e7d3b <Rong Rong> address patch comments 489c203 <Rong Rong> fix checkstyle 1784f92 <Rong Rong> fix requested and allocated size difference Authored-by: Rong Rong <rongr@apache.org> Signed-off-by: Micah Kornfield <emkornfield@gmail.com>
…of memory other than those are allocated using Netty See https://jira.apache.org/jira/browse/ARROW-7329 Closes apache#5973 from zhztheplayer/ARROW-7329 and squashes the following commits: c0345c0 <Hongze Zhang> Expand star import 81b1076 <Hongze Zhang> Introduce Immutables for config builder 214230e <Hongze Zhang> Add method BufferLedger#unwrap a38853f <Hongze Zhang> Revert "Use existing test cases in TestBaseAllocator" 1309a08 <Hongze Zhang> Revert "Visibility change" 1e7f21b <Hongze Zhang> Use existing test cases in TestBaseAllocator 8a54af4 <Hongze Zhang> Visibility change 96e3e52 <Hongze Zhang> Oops 101d529 <Hongze Zhang> Pass config to root allocator 98901aa <Hongze Zhang> Use AllocationManager.Factory c049ab6 <Hongze Zhang> getSize() was public, should keep the visibility 13629f4 <Hongze Zhang> Patch a4f96f3 <Hongze Zhang> Visibility f9891d5 <Hongze Zhang> Typo a366e99 <Hongze Zhang> Address review comments 4ba7796 <Hongze Zhang> Inconsistency on creating AllocationManager between child and parent 7627be8 <Hongze Zhang> A default implementation for AllocationManager::size() 7db394b <Hongze Zhang> Import order 8a3f79d <Hongze Zhang> Correct class names in comments 1e6e844 <Hongze Zhang> Change class names 538a543 <Hongze Zhang> ARROW-7329: AllocationManager: Allow managing different types of memory other than those are allocated using Netty Authored-by: Hongze Zhang <hongze.zhang@intel.com> Signed-off-by: David Li <li.davidm96@gmail.com>
This is a follow up on apache#5973. Closes apache#6204 from walterddr/ARROW-7538 and squashes the following commits: 15878d1 <Rong Rong> revert change and make API still public 10547bf <Rong Rong> address patch comment 97e7d3b <Rong Rong> address patch comments 489c203 <Rong Rong> fix checkstyle 1784f92 <Rong Rong> fix requested and allocated size difference Authored-by: Rong Rong <rongr@apache.org> Signed-off-by: Micah Kornfield <emkornfield@gmail.com>
…of memory other than those are allocated using Netty
See https://jira.apache.org/jira/browse/ARROW-7329