Because of apache/druid#5335 (comment) (see the last part of the message) Memory objects are going to need to carry minimal overhead over the memory bytes themselves, at least, in comparison with ByteBuffer (in the linked message, an example API uses ByteBuffer, because it's what currently used in Druid, but it's really going to be replaced with Memory).
In order to achieve this, I think separate ResourceState objects need to be dropped. Memory is either it's own "resource state" (for Memory objects, obtained from wrap(), allocate(), or map() calls), or references to another Memory as it's "resource state" (for Memory objects, obtained from region() calls). Buffer also references to some Memory as it's resource state.
Memory has the functionality of ResourceState as package-private methods.
StepBooleans should be "inlined" to be just volatile boolean fields. (And isReadOnly shouldn't be volatile, it should be just final, because it's not changing during Memory lifetime.
Heap and off-heap Memory should also probably be separated, because off-heap needs a lot of fields, not needed by on-heap Memory: handle, valid (we change the validity state only when we unmap of deallocate direct memory, so not needed for on-heap), reference to ByteBuffer, etc. Off-heap Memory could be much beefier than on-heap, because we are not going to map or allocate small off-heap Memories.
Because of this, I think hasByteBuffer() method should be removed, because we cannot consistently support it, when wrapping on-heap ByteBuffers. Also, I think this method is useless.
Class hierarchy could look like this:
Memory
|
WritableMemory
|
BaseWritableMemoryImpl------
| |
WritableMemoryImpl NonNativeEndianWritableMemoryImpl
| |
OffHeapWritableMemoryImpl OffHeapNonNativeEndianWritableMemoryImpl
OffHeapWritableMemoryImpl and OffHeapNonNativeEndianWritableMemoryImpl have pretty much the same bodies, but I don't see how to avoid this repetition.
Because of apache/druid#5335 (comment) (see the last part of the message)
Memoryobjects are going to need to carry minimal overhead over the memory bytes themselves, at least, in comparison withByteBuffer(in the linked message, an example API usesByteBuffer, because it's what currently used in Druid, but it's really going to be replaced withMemory).In order to achieve this, I think separate
ResourceStateobjects need to be dropped. Memory is either it's own "resource state" (for Memory objects, obtained from wrap(), allocate(), or map() calls), or references to another Memory as it's "resource state" (for Memory objects, obtained from region() calls). Buffer also references to some Memory as it's resource state.Memory has the functionality of
ResourceStateas package-private methods.StepBooleans should be "inlined" to be just volatile boolean fields. (And isReadOnly shouldn't be volatile, it should be just final, because it's not changing during
Memorylifetime.Heap and off-heap Memory should also probably be separated, because off-heap needs a lot of fields, not needed by on-heap Memory: handle, valid (we change the validity state only when we unmap of deallocate direct memory, so not needed for on-heap), reference to ByteBuffer, etc. Off-heap Memory could be much beefier than on-heap, because we are not going to map or allocate small off-heap Memories.
Because of this, I think
hasByteBuffer()method should be removed, because we cannot consistently support it, when wrapping on-heap ByteBuffers. Also, I think this method is useless.Class hierarchy could look like this:
OffHeapWritableMemoryImplandOffHeapNonNativeEndianWritableMemoryImplhave pretty much the same bodies, but I don't see how to avoid this repetition.