diff --git a/cdm/src/main/java/ucar/nc2/NetcdfFile.java b/cdm/src/main/java/ucar/nc2/NetcdfFile.java index 6bb581e..d5650f7 100644 --- a/cdm/src/main/java/ucar/nc2/NetcdfFile.java +++ b/cdm/src/main/java/ucar/nc2/NetcdfFile.java @@ -998,6 +998,19 @@ public class NetcdfFile implements ucar.nc2.util.cache.FileCacheable { } /** + * Return true if this file supports querying for locality information. + * @return if the file can return locality information + * @throws IOException if there is not an IOServiceProvider set + */ + public boolean supportsLocalityInformation() throws IOException { + if (spi == null) { + throw new IOException("spi is null"); + } + + return spi.supportsLocalityInformation(); + } + + /** * Return the unlimited (record) dimension, or null if not exist. * If there are multiple unlimited dimensions, it will return the first one. * @return the unlimited Dimension, or null if none. @@ -1737,6 +1750,15 @@ public class NetcdfFile implements ucar.nc2.util.cache.FileCacheable { sbuff.append( escapeName(v.getShortName())); } + public Array getLocalityInformation(ucar.nc2.Variable v, Section ranges) throws IOException, InvalidRangeException { + if (spi == null) { + throw new IOException("spi is null"); + } else if (!spi.supportsLocalityInformation()) { + throw new IOException("IOSP " + spi.getFileTypeId() + " does not support getLocalityInformation()"); + } + + return spi.getLocalityInformation(v, ranges); + } ////////////////////////////////////////////////////////////////////////////////////// // Service Provider calls diff --git a/cdm/src/main/java/ucar/nc2/Variable.java b/cdm/src/main/java/ucar/nc2/Variable.java index 172e447..963e9b8 100644 --- a/cdm/src/main/java/ucar/nc2/Variable.java +++ b/cdm/src/main/java/ucar/nc2/Variable.java @@ -592,6 +592,36 @@ public class Variable implements VariableIF, ProxyReader { } /** + * Return an ArrayLong structure with the same shape as the shape arguement + * where each entry is the offset in the byte-stream where the corresponding + * data element begins + * @param origin int array specifying the starting index. If null, assume all zeroes. + * @param shape int array specifying the extents in each dimension. + * This becomes the shape of the returned Array. + * @return a memory-resdient array of longs with offsets or -1 if the offset + * for the corresponding cell can't be determined + */ + public Array getLocalityInformation(int[] origin, int[] shape) throws IOException, InvalidRangeException { + return ncfile.getLocalityInformation( this, new Section(origin, shape)); + } + + /** + * Return an ArrayLong structure with the same shape as the shape arguement + * where each entry is the offset in the byte-stream where the corresponding + * data element begins. + * + * @param section list of Range specifying the section of data to read. + * Must be null or same rank as variable. + * If list is null, assume all data. + * Each Range corresponds to a Dimension. If the Range object is null, it means use the entire dimension. + * @return a memory-resdient array of longs with offsets or -1 if the offset + * for the corresponding cell can't be determined + */ + public Array getLocalityInformation(Section section) throws IOException, InvalidRangeException { + return ncfile.getLocalityInformation(this, section); + } + + /** * Read data section specified by a "section selector", and return a memory resident Array. Uses * Fortran 90 array section syntax. * diff --git a/cdm/src/main/java/ucar/nc2/iosp/AbstractIOServiceProvider.java b/cdm/src/main/java/ucar/nc2/iosp/AbstractIOServiceProvider.java index 27aa316..9d61d95 100644 --- a/cdm/src/main/java/ucar/nc2/iosp/AbstractIOServiceProvider.java +++ b/cdm/src/main/java/ucar/nc2/iosp/AbstractIOServiceProvider.java @@ -105,6 +105,16 @@ public abstract class AbstractIOServiceProvider implements IOServiceProvider { } @Override + public boolean supportsLocalityInformation() throws IOException { + throw new IOException("This IOSP does not support getLocalityInformation()"); + } + + @Override + public Array getLocalityInformation(ucar.nc2.Variable v2, Section section) throws IOException, InvalidRangeException { + throw new IOException("This IOSP does not support getLocalityInformation()"); + } + + @Override public StructureDataIterator getStructureIterator(Structure s, int bufferSize) throws java.io.IOException { return null; } diff --git a/cdm/src/main/java/ucar/nc2/iosp/IOServiceProvider.java b/cdm/src/main/java/ucar/nc2/iosp/IOServiceProvider.java index e4f4e85..61d070f 100644 --- a/cdm/src/main/java/ucar/nc2/iosp/IOServiceProvider.java +++ b/cdm/src/main/java/ucar/nc2/iosp/IOServiceProvider.java @@ -124,6 +124,32 @@ public interface IOServiceProvider { */ public ucar.ma2.Array readSection(ParsedSectionSpec cer) throws IOException, InvalidRangeException; + /** + * Calculate the offset in the underlying byte-stream for each value + * indicated by the section and variable objects + * + * @param v2 a top-level Variable + * @param section the section of data to read. + * There must be a Range for each Dimension in the variable, in order. + * Note: no nulls allowed. IOSP may not modify. + * @return an ArrayLong the same shape as section where each entry is the + * offset of the corresponding data element + * @throws java.io.IOException if read error or if this IOSP doesn't + * support getLocalityInformation() + * @throws ucar.ma2.InvalidRangeException if invalid section + */ + public ucar.ma2.Array getLocalityInformation(ucar.nc2.Variable v2, Section section) + throws IOException, InvalidRangeException; + + /** + * Determine if this IOServiceProvider supports the getLocalityInformation() function + * + * @return a boolean indicating if getLocalityInformation is supported by + * this IOServiceProvider + */ + public boolean supportsLocalityInformation() throws IOException; + + // iosps with top level sequences must override public StructureDataIterator getStructureIterator(Structure s, int bufferSize) throws java.io.IOException;