diff --git a/src/main/java/org/janelia/saalfeldlab/n5/CachedGsonKeyValueN5Writer.java b/src/main/java/org/janelia/saalfeldlab/n5/CachedGsonKeyValueN5Writer.java index 495883a3..1c6fee59 100644 --- a/src/main/java/org/janelia/saalfeldlab/n5/CachedGsonKeyValueN5Writer.java +++ b/src/main/java/org/janelia/saalfeldlab/n5/CachedGsonKeyValueN5Writer.java @@ -54,9 +54,9 @@ default void setVersion(final String path) throws N5Exception { default void createGroup(final String path) throws N5Exception { final String normalPath = N5URI.normalizeGroupPath(path); - // TODO: John document this! - // if you are a group, avoid hitting the backend - // if something exists, be safe + // avoid hitting the backend if this path is already a group according to the cache + // else if exists is true (then a dataset is present) so throw an exception to avoid + // overwriting / invalidating existing data if (cacheMeta()) { if (getCache().isGroup(normalPath, N5KeyValueReader.ATTRIBUTES_JSON)) return; @@ -67,10 +67,8 @@ else if (getCache().exists(normalPath, N5KeyValueReader.ATTRIBUTES_JSON)) { // N5Writer.super.createGroup(path); /* - * the 6 lines below duplicate the single line above but would have to - * call - * normalizeGroupPath again the below duplicates code, but avoids extra - * work + * the lines below duplicate the single line above but would have to call + * normalizeGroupPath again the below duplicates code, but avoids extra work */ try { getKeyValueAccess().createDirectories(absoluteGroupPath(normalPath)); @@ -140,10 +138,8 @@ default boolean remove(final String path) throws N5Exception { // GsonKeyValueN5Writer.super.remove(path) /* - * the 8 lines below duplicate the single line above but would have to - * call - * normalizeGroupPath again the below duplicates code, but avoids extra - * work + * the lines below duplicate the single line above but would have to call + * normalizeGroupPath again the below duplicates code, but avoids extra work */ final String normalPath = N5URI.normalizeGroupPath(path); final String groupPath = absoluteGroupPath(normalPath); diff --git a/src/main/java/org/janelia/saalfeldlab/n5/GsonKeyValueN5Reader.java b/src/main/java/org/janelia/saalfeldlab/n5/GsonKeyValueN5Reader.java index 2e824bb6..907c0f25 100644 --- a/src/main/java/org/janelia/saalfeldlab/n5/GsonKeyValueN5Reader.java +++ b/src/main/java/org/janelia/saalfeldlab/n5/GsonKeyValueN5Reader.java @@ -27,7 +27,6 @@ import java.io.IOException; import java.util.Arrays; -import java.util.stream.Stream; import org.janelia.saalfeldlab.n5.N5Exception.N5IOException; diff --git a/src/main/java/org/janelia/saalfeldlab/n5/GsonN5Reader.java b/src/main/java/org/janelia/saalfeldlab/n5/GsonN5Reader.java index dbec5973..0df07b35 100644 --- a/src/main/java/org/janelia/saalfeldlab/n5/GsonN5Reader.java +++ b/src/main/java/org/janelia/saalfeldlab/n5/GsonN5Reader.java @@ -25,7 +25,6 @@ */ package org.janelia.saalfeldlab.n5; -import java.io.IOException; import java.lang.reflect.Type; import java.util.Map; @@ -107,7 +106,7 @@ default T getAttribute(final String pathName, final String key, final Type t * @param pathName * group path * @return - * @throws IOException + * @throws N5Exception */ JsonElement getAttributes(final String pathName) throws N5Exception; } diff --git a/src/main/java/org/janelia/saalfeldlab/n5/N5Reader.java b/src/main/java/org/janelia/saalfeldlab/n5/N5Reader.java index 13637985..d034dd72 100644 --- a/src/main/java/org/janelia/saalfeldlab/n5/N5Reader.java +++ b/src/main/java/org/janelia/saalfeldlab/n5/N5Reader.java @@ -339,7 +339,7 @@ default T readSerializedBlock( boolean exists(final String pathName); /** - * Test whether a dataset exists. + * Test whether a dataset exists at a given path. * * @param pathName * dataset path @@ -364,7 +364,7 @@ default boolean datasetExists(final String pathName) throws N5Exception { String[] list(final String pathName) throws N5Exception; /** - * Recursively list all groups (including datasets) in the given group. + * Recursively list all groups and datasets in the given path. * Only paths that satisfy the provided filter will be included, but the * children of paths that were excluded may be included (filter does not * apply to the subtree). @@ -373,7 +373,7 @@ default boolean datasetExists(final String pathName) throws N5Exception { * base group path * @param filter * filter for children to be included - * @return list of groups + * @return list of child groups and datasets * @throws N5Exception * the exception */ @@ -396,11 +396,11 @@ default String[] deepList( } /** - * Recursively list all groups (including datasets) in the given group. + * Recursively list all groups and datasets in the given path. * * @param pathName * base group path - * @return list of groups + * @return list of groups and datasets * @throws N5Exception * the exception */ @@ -410,8 +410,7 @@ default String[] deepList(final String pathName) throws N5Exception { } /** - * Recursively list all datasets in the given group. Only paths that satisfy - * the + * Recursively list all datasets in the given path. Only paths that satisfy the * provided filter will be included, but the children of paths that were * excluded may be included (filter does not apply to the subtree). * @@ -431,19 +430,14 @@ default String[] deepList(final String pathName) throws N5Exception { * } * *

- * but will execute {@link #datasetExists(String)} only once per node. This - * can - * be relevant for performance on high latency backends such as cloud - * stores. + * but will execute {@link #datasetExists(String)} only once per node. This can + * be relevant for performance on high latency backends such as cloud stores. *

* - * @param pathName - * base group path - * @param filter - * filter for datasets to be included + * @param pathName base group path + * @param filter filter for datasets to be included * @return list of groups - * @throws N5Exception - * the exception + * @throws N5Exception the exception */ default String[] deepListDatasets( final String pathName, @@ -464,7 +458,7 @@ default String[] deepListDatasets( } /** - * Recursively list all including datasets in the given group. + * Recursively list all including datasets in the given path. * *

* This method delivers the same results as @@ -500,23 +494,18 @@ default String[] deepListDatasets(final String pathName) throws N5Exception { } /** - * Helper method to recursively list all groups. This method is not part - * of the public API and is accessible only because Java 8 does not support - * private interface methods yet. + * Helper method to recursively list all groups and datasets. This method is not part of the + * public API and is accessible only because Java 8 does not support private + * interface methods yet. * * TODO make private when committing to Java versions newer than 8 * - * @param n5 - * the n5 reader - * @param pathName - * the base group path - * @param datasetsOnly - * true if only dataset paths should be returned - * @param filter - * a dataset filter + * @param n5 the n5 reader + * @param pathName the base group path + * @param datasetsOnly true if only dataset paths should be returned + * @param filter a dataset filter * @return the list of all children - * @throws N5Exception - * the exception + * @throws N5Exception the exception */ static ArrayList deepList( final N5Reader n5, diff --git a/src/main/java/org/janelia/saalfeldlab/n5/N5URI.java b/src/main/java/org/janelia/saalfeldlab/n5/N5URI.java index 52001450..004c0de3 100644 --- a/src/main/java/org/janelia/saalfeldlab/n5/N5URI.java +++ b/src/main/java/org/janelia/saalfeldlab/n5/N5URI.java @@ -17,6 +17,12 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +/** + * A {@link URI} for N5 containers, groups, datasets, and attributes. + *

+ * Container paths are stored in the URI path. Group / dataset paths are stored in the URI query, + * and attribute paths are stored in the URI fragment. + */ public class N5URI { private static final Charset UTF8 = Charset.forName("UTF-8"); diff --git a/src/main/java/org/janelia/saalfeldlab/n5/cache/N5JsonCache.java b/src/main/java/org/janelia/saalfeldlab/n5/cache/N5JsonCache.java index ffca797b..20dbffae 100644 --- a/src/main/java/org/janelia/saalfeldlab/n5/cache/N5JsonCache.java +++ b/src/main/java/org/janelia/saalfeldlab/n5/cache/N5JsonCache.java @@ -8,6 +8,12 @@ import com.google.gson.JsonElement; +/* + * A cache containing JSON attributes and children for groups and + * datasets stored in N5 containers. Used by {@link CachedGsonKeyValueN5Reader} + * and {@link CachedGsonKeyValueN5Writer}. + * + */ public class N5JsonCache { public static final N5CacheInfo emptyCacheInfo = new N5CacheInfo(); diff --git a/src/main/java/org/janelia/saalfeldlab/n5/cache/N5JsonCacheableContainer.java b/src/main/java/org/janelia/saalfeldlab/n5/cache/N5JsonCacheableContainer.java index e8d59301..8c598ec9 100644 --- a/src/main/java/org/janelia/saalfeldlab/n5/cache/N5JsonCacheableContainer.java +++ b/src/main/java/org/janelia/saalfeldlab/n5/cache/N5JsonCacheableContainer.java @@ -10,7 +10,7 @@ * An N5 container whose structure and attributes can be cached. *

* Implementations of interface methods must explicitly query the backing - * storage. Cached implmentations (e.g {@link CachedGsonKeyValueN5Reader}) call + * storage unless noted otherwise. Cached implementations (e.g {@link CachedGsonKeyValueN5Reader}) call * these methods to update their {@link N5JsonCache}. Corresponding * {@link N5Reader} methods should use the cache, if present. */ @@ -60,8 +60,11 @@ public interface N5JsonCacheableContainer { boolean isDatasetFromContainer(final String normalPathName); /** - * If this method is called, its parent path must exist, - * and normalCacheKey must exist, with contents given by attributes. + * + * Returns true if a path is a group, given that the the given attributes exist + * for the given cache key. + *

+ * Should not call the backing storage. * * @param normalCacheKey * the cache key @@ -72,8 +75,10 @@ public interface N5JsonCacheableContainer { boolean isGroupFromAttributes(final String normalCacheKey, final JsonElement attributes); /** - * If this method is called, its parent path must exist, - * and normalCacheKey must exist, with contents given by attributes. + * Returns true if a path is a dataset, given that the the given attributes exist + * for the given cache key. + *

+ * Should not call the backing storage. * * @param normalCacheKey * the cache key