-
Notifications
You must be signed in to change notification settings - Fork 91
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
Buffer-backed access (full implementation) #299
Conversation
Complete initial specification questions put forth by @hanslovsky in imglib#278
Also correct some prior typos
I went a bit further to parameterize |
Beautiful PR! I will have a look, baby boy permitting |
Thanks @hanslovsky . I really appreciated your initial notes on this issue. |
src/main/java/net/imglib2/img/basictypeaccess/nio/AbstractBufferAccess.java
Outdated
Show resolved
Hide resolved
src/main/java/net/imglib2/img/basictypeaccess/nio/BufferAccess.java
Outdated
Show resolved
Hide resolved
src/main/java/net/imglib2/img/basictypeaccess/nio/AbstractBufferAccess.java
Outdated
Show resolved
Hide resolved
I left a few comments. Overall, this looks good to me. My only real concern is that the buffer type is hard-coded to I will leave the more thorough review to the active maintainers. |
Change NUM_BYTES to NUM_BYTES_PER_ENTITY along with getter Make DEFAULT_IS_VALID final Allow longer type-specific Buffers
src/main/java/net/imglib2/img/basictypeaccess/nio/DoubleBufferAccess.java
Outdated
Show resolved
Hide resolved
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 proposed changes look good to me but I will leave further review/merging to the active maintainers
I pushed some changes to https://github.com/imglib/imglib2/commits/nio_buffers:
If you agree with these changes please merge into your PR. I'm not sure whether the replacement of |
On binary compatibility, I may have come across some examples where I had very generic code break because A was previously unconstrained and the method signatures no longer matched. This may be an extreme case, however. |
Yes, that is definitely a problem. It happened to us before, e.g. #280 Also here, the erasure of |
I went back a few commits, and I think the issue I encountered was more due to having multiple versions of imglib2 on my path at the time. I think this might have been the code that caused a public static < T extends NativeType< T >, A extends DataAccess > ArrayImg< T, A > createArrayImg(
final NativeTypeFactory< T, A > factory, final A data, final long... dims)
{
final Fraction fraction = factory.createLinkedType(null).getEntitiesPerPixel();
final ArrayImg< T, A > img = new ArrayImg< T, A >(data, dims, fraction);
final T linkedType = factory.createLinkedType(img);
img.setLinkedType(linkedType);
return img;
} |
After reading more about binary compatibility, it seems unwise to add a bound to public class ArrayImg< T extends NativeType< T >, A > extends AbstractNativeImg< T, A > implements SubIntervalIterable< T >
...
@SuppressWarnings("unchecked")
@Override
public A update( final Object o )
{
if(data instanceof DataAccess)
return ( A ) ( (DataAccess) data).createView( o );
else
return data;
} https://docs.oracle.com/javase/specs/jls/se8/html/jls-13.html#jls-13.4.13
|
I've removed bounds on |
Hmm, having an |
I moved the In For Let me know if you think these measures are worth saving API breakage for or not. |
I do not see a major performance regression when running the tests.
|
Without these latest changes the code is more understandable. I vote for API breakage. I think the fallout downstream will be minor if at all. @axtimwalde @StephanPreibisch what do you think? |
To summarize,
|
If we do not want to break binary compatibility, then the solution is
|
I prefer breaking API over |
OK, I forced pushed back to c6a9d07 by @tpietzsch . Might alternate constructors like the following help binary compatibility?
Let me see if I can write a test case. |
that's a great idea |
A was previously unbounded, but is now bounded by the new interface DataAccess
After adding the additional constructors, there are no longer any binary compatibility issues. For the I used the following code to test binary compatibility: ShortAccess data = new ShortArray(new short[] { 1, 2, 3, 4, 5});
long[] dim = new long[] { 5 };
ArrayImg< UnsignedShortType, ShortAccess > img = new ArrayImg<>(data, dim, new Fraction());
UnsignedShortType type = new UnsignedShortType( img );
img.setLinkedType(type);
ShortAccess updatedData = img.update(this);
System.out.println(updatedData); I put this in the Sandbox class from the imglib2-tutorials. Sandbox should be compiled against imglib2 via the scijava parent pom. I then I ran it directly from the command line with distinct exported jars of imglib2 from Eclipse. Without adding the constructors taking
Adding the constructors, everything seems to work fine. I get the following as output.
I expected to encounter issues with the update method, so I used
I then ran Compiled from "ArrayImg.java"
public class net.imglib2.img.array.ArrayImg<T extends net.imglib2.type.NativeType<T>, A extends net.imglib2.img.basictypeaccess.DataAccess> extends net.imglib2.img.AbstractNativeImg<T, A> implements net.imglib2.view.iteration.SubIntervalIterable<T> {
...
public A update(java.lang.Object);
descriptor: (Ljava/lang/Object;)Lnet/imglib2/img/basictypeaccess/DataAccess;
...
public java.lang.Object update(java.lang.Object);
descriptor: (Ljava/lang/Object;)Ljava/lang/Object;
} ArrayImg contains two distinct My conclusion is that with the added constructors in cacce9f, there are no longer binary compatibility issues with this pull request. |
This pull request has been mentioned on Image.sc Forum. There might be relevant details there: |
@tpietzsch Do you think this can be merged? |
We should merge this and fix problems as they emerge. |
Buffer-backed access (full implementation)
These changes complete #278 and fixes #5
7cc0468 implements a lightweight interface
DataAccess
with acreateView(Object)
method as per the Twitter discussion. It also includes a default implementation that just returnsthis
. The interface definition returns typeObject
, which seems better than my attempt to parameterize generics across the entireAccess
tree.6f851db contains the
BufferAccess
interface and its implementations. Per @hanslovsky's design in #278BufferAccess
implementsArrayDataAccess
andVolatileAccess
. The concrete classes share a commonAbstractBufferAccess
.The
net.imglib2.img.basictypeaccess.nio
tree is as follows:Answers to open questions in #278
General
ArrayDataAccess
is implemented as followscreateArray( int numEntities )
allocates a newjava.nio.Buffer
based on whether the current oneisDirect
or not and if the currentAccess
isValid
getCurrentStorageArray()
returns the rawBuffer
without duplicating itgetArrayLength()
is returnsBuffer.limit()
(as opposed toBuffer.capacity()
as in Buffer-backed accesses #278)VolatileAccess
is implemented with support fromAbstractBufferAccess
Buffer
java.nio.ByteBuffer
and contain afromByteBuffer
static method.Specific
createArray( int numEntities )
allocates aBuffer
that has the same directness as the currentBuffer
Differences to imglib[1] NIO*Array
The current implementation differs from the previous NIO*Array (e.g.
NIOLongArray
:java.nio.Buffer
directly rather than array. The user can wrap (e.g.LongBuffer.wrap
) an array if needed.getCurrentStorageArray
returns aBufferAccess
rather than anArray
New Items
LongBufferAccess
rather thanNIOLongArray
orLongBufferLongAccess
. The buffers are distinct from arrays. Also theBuffer
type andAccess
type are always the same in this implementation.get
andput
methods ofjava.nio.LongBuffer
asgetValues
andsetValues
that allows the user to quickly copy in or out data using the correspondingArray
access (e.g.AbstractLongArray
as of f5609a6). This is mainly a convenience and could be dropped.Buffer.duplicate()
is only used inDataAccess.createView(Object)
and in the bulkgetValues
andsetValues
methods.Buffer.duplicate()
only actually exists in Java 9+ but is implemented in the concrete classes in Java 8 (e.g.LongBuffer
)Change Log
Abstract*Array
types rather than*Array
.