Showing preview only (1,001K chars total). Download the full file or copy to clipboard to get everything.
Repository: saalfeldlab/n5
Branch: master
Commit: 273be1512b62
Files: 200
Total size: 931.3 KB
Directory structure:
gitextract_yquuu4ly/
├── .github/
│ ├── build.sh
│ ├── setup.sh
│ └── workflows/
│ └── build.yml
├── .gitignore
├── LICENSE.md
├── README.md
├── doc/
│ ├── LICENSE.md
│ ├── README.md
│ └── n5-eclipse-style.xml
├── pom.xml
├── scripts/
│ ├── fsLockValidation
│ └── writeLockTest.sh
└── src/
├── main/
│ └── java/
│ └── org/
│ └── janelia/
│ └── saalfeldlab/
│ └── n5/
│ ├── AbstractDataBlock.java
│ ├── BufferedKvaLockedChannel.java
│ ├── ByteArrayDataBlock.java
│ ├── Bzip2Compression.java
│ ├── CachedGsonKeyValueN5Reader.java
│ ├── CachedGsonKeyValueN5Writer.java
│ ├── ChannelLock.java
│ ├── Compression.java
│ ├── CompressionAdapter.java
│ ├── DataBlock.java
│ ├── DataType.java
│ ├── DatasetAttributes.java
│ ├── DoubleArrayDataBlock.java
│ ├── FileKeyLockManager.java
│ ├── FileSystemKeyValueAccess.java
│ ├── FloatArrayDataBlock.java
│ ├── FsIoPolicy.java
│ ├── GsonKeyValueN5Reader.java
│ ├── GsonKeyValueN5Writer.java
│ ├── GsonN5Reader.java
│ ├── GsonN5Writer.java
│ ├── GsonUtils.java
│ ├── GzipCompression.java
│ ├── HttpKeyValueAccess.java
│ ├── IntArrayDataBlock.java
│ ├── IoPolicy.java
│ ├── KeyLockState.java
│ ├── KeyValueAccess.java
│ ├── LinkedAttributePathToken.java
│ ├── LockedChannel.java
│ ├── LockedFileChannel.java
│ ├── LockingPolicy.java
│ ├── LongArrayDataBlock.java
│ ├── Lz4Compression.java
│ ├── N5Exception.java
│ ├── N5FSReader.java
│ ├── N5FSWriter.java
│ ├── N5KeyValueReader.java
│ ├── N5KeyValueWriter.java
│ ├── N5Reader.java
│ ├── N5URI.java
│ ├── N5Writer.java
│ ├── NameConfigAdapter.java
│ ├── RawCompression.java
│ ├── ReflectionUtils.java
│ ├── ShortArrayDataBlock.java
│ ├── StringDataBlock.java
│ ├── XzCompression.java
│ ├── cache/
│ │ ├── N5JsonCache.java
│ │ └── N5JsonCacheableContainer.java
│ ├── codec/
│ │ ├── BlockCodec.java
│ │ ├── BlockCodecInfo.java
│ │ ├── CodecInfo.java
│ │ ├── CodecParser.java
│ │ ├── ConcatenatedDataCodec.java
│ │ ├── ConcatenatedDeterministicSizeDataCodec.java
│ │ ├── DataCodec.java
│ │ ├── DataCodecInfo.java
│ │ ├── DatasetCodec.java
│ │ ├── DatasetCodecInfo.java
│ │ ├── DeterministicSizeCodecInfo.java
│ │ ├── DeterministicSizeDataCodec.java
│ │ ├── FlatArrayCodec.java
│ │ ├── IdentityCodec.java
│ │ ├── IndexCodecAdapter.java
│ │ ├── N5BlockCodecInfo.java
│ │ ├── N5BlockCodecs.java
│ │ ├── RawBlockCodecInfo.java
│ │ ├── RawBlockCodecs.java
│ │ ├── checksum/
│ │ │ ├── ChecksumCodec.java
│ │ │ ├── ChecksumException.java
│ │ │ └── Crc32cChecksumCodec.java
│ │ └── transpose/
│ │ ├── Transpose.java
│ │ ├── TransposeCodec.java
│ │ └── TransposeCodecInfo.java
│ ├── http/
│ │ ├── ApacheListResponseParser.java
│ │ ├── CandidateListResponseParser.java
│ │ ├── ListResponseParser.java
│ │ ├── MicrosoftListResponseParser.java
│ │ ├── PatternListResponseParser.java
│ │ └── PythonListResponseParser.java
│ ├── readdata/
│ │ ├── ByteArrayReadData.java
│ │ ├── InputStreamReadData.java
│ │ ├── LazyGeneratedReadData.java
│ │ ├── LazyRead.java
│ │ ├── LazyReadData.java
│ │ ├── Range.java
│ │ ├── ReadData.java
│ │ ├── VolatileReadData.java
│ │ ├── prefetch/
│ │ │ ├── AggregatingPrefetchLazyRead.java
│ │ │ ├── EnclosingPrefetchLazyRead.java
│ │ │ ├── SliceTrackingLazyRead.java
│ │ │ └── Slices.java
│ │ └── segment/
│ │ ├── ConcatenatedReadData.java
│ │ ├── DefaultSegmentedReadData.java
│ │ ├── Segment.java
│ │ └── SegmentedReadData.java
│ ├── serialization/
│ │ ├── JsonArrayUtils.java
│ │ ├── N5Annotations.java
│ │ └── NameConfig.java
│ ├── shard/
│ │ ├── DatasetAccess.java
│ │ ├── DefaultDatasetAccess.java
│ │ ├── DefaultShardCodecInfo.java
│ │ ├── Nesting.java
│ │ ├── PositionValueAccess.java
│ │ ├── RawShard.java
│ │ ├── RawShardCodec.java
│ │ ├── RawShardDataBlock.java
│ │ ├── Region.java
│ │ ├── ShardCodecInfo.java
│ │ └── ShardIndex.java
│ └── util/
│ ├── FloatValueParser.java
│ ├── MemCopy.java
│ └── SubArrayCopy.java
└── test/
├── java/
│ └── org/
│ └── janelia/
│ └── saalfeldlab/
│ └── n5/
│ ├── AbstractN5Test.java
│ ├── DatasetAttributesTest.java
│ ├── FileKeyLockManagerTest.java
│ ├── FsLockTest.java
│ ├── N5Benchmark.java
│ ├── N5CachedFSTest.java
│ ├── N5FSTest.java
│ ├── N5ReadBenchmark.java
│ ├── N5URITest.java
│ ├── TrackingN5Writer.java
│ ├── UriTest.java
│ ├── WriteLockExp.java
│ ├── backward/
│ │ ├── CompatibilityTest.java
│ │ └── CreateSampleData.java
│ ├── benchmarks/
│ │ ├── N5BlockWriteBenchmarks.java
│ │ └── ReadDataBenchmarks.java
│ ├── cache/
│ │ └── N5CacheTest.java
│ ├── codec/
│ │ ├── BlockCodecTests.java
│ │ ├── BytesCodecTests.java
│ │ ├── ChecksumCodecTests.java
│ │ └── DatasetCodecTests.java
│ ├── compression/
│ │ └── CompressionTypesTest.java
│ ├── demo/
│ │ └── AttributePathDemo.java
│ ├── http/
│ │ ├── HttpKeyValueAccessTest.java
│ │ ├── HttpReaderFsWriter.java
│ │ ├── N5HttpTest.java
│ │ └── RunnerWithHttpServer.java
│ ├── kva/
│ │ ├── AbstractKeyValueAccessTest.java
│ │ ├── DelegateKeyValueAccess.java
│ │ ├── FileSystemKeyValueAccessTest.java
│ │ ├── FsLockingValidation.java
│ │ ├── HttpKeyValueAccessTest.java
│ │ └── TrackingKeyValueAccess.java
│ ├── locking/
│ │ ├── JustFileChannels.java
│ │ └── JustFileChannelsThreaded.java
│ ├── readdata/
│ │ ├── RangeTests.java
│ │ ├── ReadDataTests.java
│ │ ├── prefetch/
│ │ │ ├── SliceTrackingLazyReadTests.java
│ │ │ └── SlicesTest.java
│ │ └── segment/
│ │ ├── ConcatenatedReadDataTest.java
│ │ └── SegmentTest.java
│ ├── serialization/
│ │ └── CodecSerializationTest.java
│ ├── shard/
│ │ ├── DatasetAccessTest.java
│ │ ├── NestedGridTest.java
│ │ ├── ShardTest.java
│ │ ├── TestPositionValueAccess.java
│ │ ├── WriteRegionTest.java
│ │ ├── WriteShardTest.java
│ │ ├── WriteShardTest2.java
│ │ └── WriteShardTestTruncate.java
│ └── url/
│ └── UriAttributeTest.java
└── resources/
├── backward/
│ ├── data-1.5.0.n5/
│ │ ├── attributes.json
│ │ └── raw/
│ │ ├── 0/
│ │ │ ├── 0
│ │ │ └── 1
│ │ ├── 1/
│ │ │ ├── 0
│ │ │ └── 1
│ │ └── attributes.json
│ ├── data-2.5.1.n5/
│ │ ├── attributes.json
│ │ └── raw/
│ │ ├── 0/
│ │ │ ├── 0
│ │ │ └── 1
│ │ ├── 1/
│ │ │ ├── 0
│ │ │ └── 1
│ │ └── attributes.json
│ └── data-3.1.3.n5/
│ ├── attributes.json
│ └── raw/
│ ├── 0/
│ │ ├── 0
│ │ └── 1
│ ├── 1/
│ │ ├── 0
│ │ └── 1
│ └── attributes.json
└── url/
└── urlAttributes.n5/
├── a/
│ ├── aa/
│ │ ├── aaa/
│ │ │ └── attributes.json
│ │ └── attributes.json
│ └── attributes.json
├── attributes.json
└── objs/
└── attributes.json
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/build.sh
================================================
#!/bin/sh
curl -fsLO https://raw.githubusercontent.com/scijava/scijava-scripts/main/ci-build.sh
sh ci-build.sh
================================================
FILE: .github/setup.sh
================================================
#!/bin/sh
curl -fsLO https://raw.githubusercontent.com/scijava/scijava-scripts/main/ci-setup-github-actions.sh
sh ci-setup-github-actions.sh
# Let the Linux build handle artifact deployment.
if [ "$(uname)" != Linux ]
then
echo "No deploy -- non-Linux build"
echo "NO_DEPLOY=1" >> $GITHUB_ENV
fi
================================================
FILE: .github/workflows/build.yml
================================================
name: build
on:
push:
branches:
- master
- development
tags:
- "*-[0-9]+.*"
pull_request:
branches:
- master
- development
jobs:
build:
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.10'
- name: Set up Java
uses: actions/setup-java@v4
with:
java-version: '8'
distribution: 'zulu'
cache: 'maven'
- name: Set up CI environment
run: .github/setup.sh
shell: bash
- name: Execute the build
run: .github/build.sh
shell: bash
env:
GPG_KEY_NAME: ${{ secrets.GPG_KEY_NAME }}
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
MAVEN_USER: ${{ secrets.MAVEN_USER }}
MAVEN_PASS: ${{ secrets.MAVEN_PASS }}
OSSRH_PASS: ${{ secrets.OSSRH_PASS }}
SIGNING_ASC: ${{ secrets.SIGNING_ASC }}
================================================
FILE: .gitignore
================================================
*.class
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.ear
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
/target/
.classpath
.project
.settings
.idea
*.iml
================================================
FILE: LICENSE.md
================================================
## BSD 2-Clause License
Copyright (c) 2017-2026, Stephan Saalfeld
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================
FILE: README.md
================================================
# N5 [](https://github.com/saalfeldlab/n5/actions/workflows/build.yml)
The N5 API specifies the primitive operations needed to store large chunked n-dimensional tensors, and arbitrary meta-data in a hierarchy of groups similar to HDF5.
Other than HDF5, N5 is not bound to a specific backend. This repository includes a simple [file-system backend](#file-system-specification). There are also an [HDF5 backend](https://github.com/saalfeldlab/n5-hdf5), a [Zarr backend](https://github.com/saalfeldlab/n5-zarr), a [Google Cloud backend](https://github.com/saalfeldlab/n5-google-cloud), and an [AWS-S3 backend](https://github.com/saalfeldlab/n5-aws-s3).
At this time, N5 supports:
* arbitrary group hierarchies
* arbitrary meta-data (stored as JSON or HDF5 attributes)
* chunked n-dimensional tensor datasets
* value-datatypes: [u]int8, [u]int16, [u]int32, [u]int64, float32, float64
* compression: raw, gzip, zlib, bzip2, xz, and lz4 are included in this repository, custom compression schemes can be added
Chunked datasets can be sparse, i.e. empty chunks do not need to be stored.
## File-system specification
*version 4.0.0*
N5 group is not a single file but simply a directory on the file system. Meta-data is stored as a JSON file per each group/ directory. Tensor datasets can be chunked and chunks are stored as individual files. This enables parallel reading and writing on a cluster.
1. All directories of the file system are N5 groups.
2. A JSON file `attributes.json` in a directory contains arbitrary attributes. A group without attributes may not have an `attributes.json` file.
3. The version of this specification is 4.0.0 and is stored in the "n5" attribute of the root group "/".
4. A dataset is a group with the mandatory attributes:
* dimensions (e.g. [100, 200, 300]),
* blockSize (e.g. [64, 64, 64]),
* dataType (one of {uint8, uint16, uint32, uint64, int8, int16, int32, int64, float32, float64, object})
* compression as a struct with the mandatory attribute type that specifies the compression scheme, currently available are:
* raw (no parameters),
* bzip2 with parameters
* blockSize ([1-9], default 9)
* gzip with parameters
* level (integer, default -1)
* lz4 with parameters
* blockSize (integer, default 65536)
* xz with parameters
* preset (integer, default 6).
Custom compression schemes with arbitrary parameters can be added using [compression annotations](#extensible-compression-schemes), e.g. [N5 Blosc](https://github.com/saalfeldlab/n5-blosc) and [N5 ZStandard](https://github.com/JaneliaSciComp/n5-zstandard/).
5. Chunks are stored in a directory hierarchy that enumerates their positive integer position in the chunk grid (e.g. `0/4/1/7` for chunk grid position p=(0, 4, 1, 7)).
6. Datasets are sparse, i.e. there is no guarantee that all chunks of a dataset exist.
7. Chunks cannot be larger than 2GB (2<sup>31</sup>Bytes).
8. All chunks of a chunked dataset have the same size except for end-chunks that may be smaller, therefore
9. Chunks are stored in the following binary format:
* mode (uint16 big endian, default = 0x0000, varlength = 0x0001, object = 0x0002)
* number of dimensions (uint16 big endian)
* dimension 1[,...,n] (uint32 big endian)
* [ mode == varlength ? number of elements (uint32 big endian) ]
* compressed data (big endian)
Example:
A 3-dimensional `uint16` datablock of 1×2×3 pixels with raw compression storing the values (1,2,3,4,5,6) starts with:
```hexdump
00000000: 00 00 .. # 0 (default mode)
00000002: 00 03 .. # 3 (number of dimensions)
00000004: 00 00 00 01 .... # 1 (dimensions)
00000008: 00 00 00 02 .... # 2
0000000c: 00 00 00 03 .... # 3
```
followed by data stored as raw or compressed big endian values. For raw:
```hexdump
00000010: 00 01 .. # 1
00000012: 00 02 .. # 2
00000014: 00 03 .. # 3
00000016: 00 04 .. # 4
00000018: 00 05 .. # 5
0000001a: 00 06 .. # 6
```
for bzip2 compression:
```hexdump
00000010: 42 5a 68 39 BZh9
00000014: 31 41 59 26 1AY&
00000018: 53 59 02 3e SY.>
0000001c: 0d d2 00 00 ....
00000020: 00 40 00 7f .@..
00000024: 00 20 00 31 . .1
00000028: 0c 01 0d 31 ...1
0000002c: a8 73 94 33 .s.3
00000030: 7c 5d c9 14 |]..
00000034: e1 42 40 08 .B@.
00000038: f8 37 48 .7H
```
for gzip compression:
```hexdump
00000010: 1f 8b 08 00 ....
00000014: 00 00 00 00 ....
00000018: 00 00 63 60 ..c`
0000001c: 64 60 62 60 d`b`
00000020: 66 60 61 60 f`a`
00000024: 65 60 03 00 e`..
00000028: aa ea 6d bf ..m.
0000002c: 0c 00 00 00 ....
```
for xz compression:
```hexdump
00000010: fd 37 7a 58 .7zX
00000014: 5a 00 00 04 Z...
00000018: e6 d6 b4 46 ...F
0000001c: 02 00 21 01 ..!.
00000020: 16 00 00 00 ....
00000024: 74 2f e5 a3 t/..
00000028: 01 00 0b 00 ....
0000002c: 01 00 02 00 ....
00000030: 03 00 04 00 ....
00000034: 05 00 06 00 ....
00000038: 0d 03 09 ca ....
0000003c: 34 ec 15 a7 4...
00000040: 00 01 24 0c ..$.
00000044: a6 18 d8 d8 ....
00000048: 1f b6 f3 7d ...}
0000004c: 01 00 00 00 ....
00000050: 00 04 59 5a ..YZ
```
## Extensible compression schemes
Custom compression schemes can be implemented using the annotation discovery mechanism of SciJava. Implement the [`BlockReader`](https://github.com/saalfeldlab/n5/blob/master/src/main/java/org/janelia/saalfeldlab/n5/BlockReader.java) and [`BlockWriter`](https://github.com/saalfeldlab/n5/blob/master/src/main/java/org/janelia/saalfeldlab/n5/BlockWriter.java) interfaces for the compression scheme and create a parameter class implementing the [`Compression`](https://github.com/saalfeldlab/n5/blob/master/src/main/java/org/janelia/saalfeldlab/n5/Compression.java) interface that is annotated with the [`CompressionType`](https://github.com/saalfeldlab/n5/blob/master/src/main/java/org/janelia/saalfeldlab/n5/Compression.java#L51) and [`CompressionParameter`](https://github.com/saalfeldlab/n5/blob/master/src/main/java/org/janelia/saalfeldlab/n5/Compression.java#L63) annotations. Typically, all this can happen in a single class such as in [`GzipCompression`](https://github.com/saalfeldlab/n5/blob/master/src/main/java/org/janelia/saalfeldlab/n5/GzipCompression.java).
## Disclaimer
HDF5 is a great format that provides a wealth of conveniences that I do not want to miss. Its inefficiency for parallel writing, however, limits its applicability for handling of very large n-dimensional data.
N5 uses the native filesystem of the target platform and JSON files to specify basic and custom meta-data as attributes. It aims at preserving the convenience of HDF5 where possible but doesn't try too hard to be a full replacement.
================================================
FILE: doc/LICENSE.md
================================================
## BSD 2-Clause License
Copyright (c) @project.inceptionYear@-@current.year@, Stephan Saalfeld
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================
FILE: doc/README.md
================================================
# N5 [](https://github.com/saalfeldlab/n5/actions/workflows/build.yml)
The N5 API specifies the primitive operations needed to store large chunked n-dimensional tensors, and arbitrary meta-data in a hierarchy of groups similar to HDF5.
Other than HDF5, N5 is not bound to a specific backend. This repository includes a simple [file-system backend](#file-system-specification). There are also an [HDF5 backend](https://github.com/saalfeldlab/n5-hdf5), a [Zarr backend](https://github.com/saalfeldlab/n5-zarr), a [Google Cloud backend](https://github.com/saalfeldlab/n5-google-cloud), and an [AWS-S3 backend](https://github.com/saalfeldlab/n5-aws-s3).
At this time, N5 supports:
* arbitrary group hierarchies
* arbitrary meta-data (stored as JSON or HDF5 attributes)
* chunked n-dimensional tensor datasets
* value-datatypes: [u]int8, [u]int16, [u]int32, [u]int64, float32, float64
* compression: raw, gzip, zlib, bzip2, xz, and lz4 are included in this repository, custom compression schemes can be added
Chunked datasets can be sparse, i.e. empty chunks do not need to be stored.
## File-system specification
*version @n5-spec.version@*
N5 group is not a single file but simply a directory on the file system. Meta-data is stored as a JSON file per each group/ directory. Tensor datasets can be chunked and chunks are stored as individual files. This enables parallel reading and writing on a cluster.
1. All directories of the file system are N5 groups.
2. A JSON file `attributes.json` in a directory contains arbitrary attributes. A group without attributes may not have an `attributes.json` file.
3. The version of this specification is @n5-spec.version@ and is stored in the "n5" attribute of the root group "/".
4. A dataset is a group with the mandatory attributes:
* dimensions (e.g. [100, 200, 300]),
* blockSize (e.g. [64, 64, 64]),
* dataType (one of {uint8, uint16, uint32, uint64, int8, int16, int32, int64, float32, float64, object})
* compression as a struct with the mandatory attribute type that specifies the compression scheme, currently available are:
* raw (no parameters),
* bzip2 with parameters
* blockSize ([1-9], default 9)
* gzip with parameters
* level (integer, default -1)
* lz4 with parameters
* blockSize (integer, default 65536)
* xz with parameters
* preset (integer, default 6).
Custom compression schemes with arbitrary parameters can be added using [compression annotations](#extensible-compression-schemes), e.g. [N5 Blosc](https://github.com/saalfeldlab/n5-blosc) and [N5 ZStandard](https://github.com/JaneliaSciComp/n5-zstandard/).
5. Chunks are stored in a directory hierarchy that enumerates their positive integer position in the chunk grid (e.g. `0/4/1/7` for chunk grid position p=(0, 4, 1, 7)).
6. Datasets are sparse, i.e. there is no guarantee that all chunks of a dataset exist.
7. Chunks cannot be larger than 2GB (2<sup>31</sup>Bytes).
8. All chunks of a chunked dataset have the same size except for end-chunks that may be smaller, therefore
9. Chunks are stored in the following binary format:
* mode (uint16 big endian, default = 0x0000, varlength = 0x0001, object = 0x0002)
* number of dimensions (uint16 big endian)
* dimension 1[,...,n] (uint32 big endian)
* [ mode == varlength ? number of elements (uint32 big endian) ]
* compressed data (big endian)
Example:
A 3-dimensional `uint16` datablock of 1×2×3 pixels with raw compression storing the values (1,2,3,4,5,6) starts with:
```hexdump
00000000: 00 00 .. # 0 (default mode)
00000002: 00 03 .. # 3 (number of dimensions)
00000004: 00 00 00 01 .... # 1 (dimensions)
00000008: 00 00 00 02 .... # 2
0000000c: 00 00 00 03 .... # 3
```
followed by data stored as raw or compressed big endian values. For raw:
```hexdump
00000010: 00 01 .. # 1
00000012: 00 02 .. # 2
00000014: 00 03 .. # 3
00000016: 00 04 .. # 4
00000018: 00 05 .. # 5
0000001a: 00 06 .. # 6
```
for bzip2 compression:
```hexdump
00000010: 42 5a 68 39 BZh9
00000014: 31 41 59 26 1AY&
00000018: 53 59 02 3e SY.>
0000001c: 0d d2 00 00 ....
00000020: 00 40 00 7f .@..
00000024: 00 20 00 31 . .1
00000028: 0c 01 0d 31 ...1
0000002c: a8 73 94 33 .s.3
00000030: 7c 5d c9 14 |]..
00000034: e1 42 40 08 .B@.
00000038: f8 37 48 .7H
```
for gzip compression:
```hexdump
00000010: 1f 8b 08 00 ....
00000014: 00 00 00 00 ....
00000018: 00 00 63 60 ..c`
0000001c: 64 60 62 60 d`b`
00000020: 66 60 61 60 f`a`
00000024: 65 60 03 00 e`..
00000028: aa ea 6d bf ..m.
0000002c: 0c 00 00 00 ....
```
for xz compression:
```hexdump
00000010: fd 37 7a 58 .7zX
00000014: 5a 00 00 04 Z...
00000018: e6 d6 b4 46 ...F
0000001c: 02 00 21 01 ..!.
00000020: 16 00 00 00 ....
00000024: 74 2f e5 a3 t/..
00000028: 01 00 0b 00 ....
0000002c: 01 00 02 00 ....
00000030: 03 00 04 00 ....
00000034: 05 00 06 00 ....
00000038: 0d 03 09 ca ....
0000003c: 34 ec 15 a7 4...
00000040: 00 01 24 0c ..$.
00000044: a6 18 d8 d8 ....
00000048: 1f b6 f3 7d ...}
0000004c: 01 00 00 00 ....
00000050: 00 04 59 5a ..YZ
```
## Extensible compression schemes
Custom compression schemes can be implemented using the annotation discovery mechanism of SciJava. Implement the [`BlockReader`](https://github.com/saalfeldlab/n5/blob/master/src/main/java/org/janelia/saalfeldlab/n5/BlockReader.java) and [`BlockWriter`](https://github.com/saalfeldlab/n5/blob/master/src/main/java/org/janelia/saalfeldlab/n5/BlockWriter.java) interfaces for the compression scheme and create a parameter class implementing the [`Compression`](https://github.com/saalfeldlab/n5/blob/master/src/main/java/org/janelia/saalfeldlab/n5/Compression.java) interface that is annotated with the [`CompressionType`](https://github.com/saalfeldlab/n5/blob/master/src/main/java/org/janelia/saalfeldlab/n5/Compression.java#L51) and [`CompressionParameter`](https://github.com/saalfeldlab/n5/blob/master/src/main/java/org/janelia/saalfeldlab/n5/Compression.java#L63) annotations. Typically, all this can happen in a single class such as in [`GzipCompression`](https://github.com/saalfeldlab/n5/blob/master/src/main/java/org/janelia/saalfeldlab/n5/GzipCompression.java).
## Disclaimer
HDF5 is a great format that provides a wealth of conveniences that I do not want to miss. Its inefficiency for parallel writing, however, limits its applicability for handling of very large n-dimensional data.
N5 uses the native filesystem of the target platform and JSON files to specify basic and custom meta-data as attributes. It aims at preserving the convenience of HDF5 where possible but doesn't try too hard to be a full replacement.
================================================
FILE: doc/n5-eclipse-style.xml
================================================
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<profiles version="13">
<profile kind="CodeFormatterProfile" name="n5-eclipse-style" version="13">
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_parameters" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_module_statements" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
<setting id="org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode" value="enabled"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_conditional_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines" value="2147483647"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.compiler.source" value="9"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assignment_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="9"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_arguments" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.compiler.compliance" value="9"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="tab"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="160"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
</profile>
</profiles>
================================================
FILE: pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.scijava</groupId>
<artifactId>pom-scijava</artifactId>
<version>43.0.0</version>
<relativePath />
</parent>
<groupId>org.janelia.saalfeldlab</groupId>
<artifactId>n5</artifactId>
<version>4.0.1-SNAPSHOT</version>
<name>N5</name>
<description>Not HDF5</description>
<url>https://github.com/saalfeldlab/n5</url>
<inceptionYear>2017</inceptionYear>
<organization>
<name>Saalfeld Lab</name>
<url>http://saalfeldlab.janelia.org/</url>
</organization>
<licenses>
<license>
<name>Simplified BSD License</name>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<id>axtimwalde</id>
<name>Stephan Saalfeld</name>
<url>http://imagej.net/User:Saalfeld</url>
<roles>
<role>founder</role>
<role>lead</role>
<role>developer</role>
<role>debugger</role>
<role>reviewer</role>
<role>support</role>
<role>maintainer</role>
</roles>
</developer>
<developer>
<id>bogovicj</id>
<name>John Bogovic</name>
<url>http://imagej.net/User:Bogovic</url>
<roles>
<role>lead</role>
<role>developer</role>
<role>debugger</role>
<role>reviewer</role>
<role>support</role>
<role>maintainer</role>
</roles>
</developer>
<developer>
<name>Caleb Hulbert</name>
<roles>
<role>lead</role>
<role>developer</role>
<role>debugger</role>
<role>reviewer</role>
<role>support</role>
<role>maintainer</role>
</roles>
</developer>
</developers>
<contributors>
<contributor>
<name>Stephan Saalfeld</name>
<properties>
<id>axtimwalde</id>
</properties>
</contributor>
<contributor>
<name>John Bogovic</name>
<properties>
<id>bogovicj</id>
</properties>
</contributor>
<contributor>
<name>Igor Pisarev</name>
<properties>
<id>igorpisarev</id>
</properties>
</contributor>
<contributor>
<name>Neil Thistlethwaite</name>
</contributor>
<contributor>
<name>Andrew Champion</name>
</contributor>
<contributor>
<name>Philipp Hanslovsky</name>
<properties>
<id>hanslovsky</id>
</properties>
</contributor>
<contributor>
<name>Caleb Hulbert</name>
</contributor>
<contributor>
<name>Tobias Pietzsch</name>
<properties>
<id>tpietzsch</id>
</properties>
</contributor>
<contributor>
<name>Mark Kittisopikul</name>
</contributor>
</contributors>
<mailingLists>
<mailingList>
<name>Image.sc Forum</name>
<archive>https://forum.image.sc/tag/n5</archive>
</mailingList>
</mailingLists>
<scm>
<connection>scm:git:git://github.com/saalfeldlab/n5</connection>
<developerConnection>scm:git:git@github.com:saalfeldlab/n5</developerConnection>
<tag>HEAD</tag>
<url>https://github.com/saalfeldlab/n5</url>
</scm>
<issueManagement>
<system>GitHub</system>
<url>https://github.com/saalfedlab/n5/issues</url>
</issueManagement>
<ciManagement>
<system>GitHub Actions</system>
<url>https://github.com/saalfeldlab/n5/actions</url>
</ciManagement>
<properties>
<package-name>org.janelia.saalfeldlab.n5</package-name>
<license.licenseName>bsd_2</license.licenseName>
<license.projectName>Not HDF5</license.projectName>
<license.organizationName>Saalfeld Lab</license.organizationName>
<license.copyrightOwners>Stephan Saalfeld</license.copyrightOwners>
<license.skipUpdateLicense>true</license.skipUpdateLicense>
<license.skipUpdateProjectLicense>true</license.skipUpdateProjectLicense>
<!-- NB: Deploy releases to the SciJava Maven repository. -->
<releaseProfiles>sign,deploy-to-scijava</releaseProfiles>
<n5-spec.version>4.0.0</n5-spec.version>
<!-- Only used for test scope -->
<n5-universe.version>2.4.0-alpha-9</n5-universe.version>
<n5-aws-s3.version>4.4.0-alpha-9</n5-aws-s3.version>
<n5-blosc.version>2.0.0-alpha-4</n5-blosc.version>
<n5-google-cloud.version>5.2.0-alpha-7</n5-google-cloud.version>
<n5-hdf5.version>2.3.0-alpha-7</n5-hdf5.version>
<n5-imglib2.version>7.1.0-alpha-8</n5-imglib2.version>
<n5-zarr.version>2.0.0-alpha-8</n5-zarr.version>
<n5-zstandard.version>2.0.0-alpha-4</n5-zstandard.version>
</properties>
<dependencies>
<dependency>
<groupId>org.tukaani</groupId>
<artifactId>xz</artifactId>
</dependency>
<dependency>
<groupId>org.lz4</groupId>
<artifactId>lz4-java</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>org.scijava</groupId>
<artifactId>scijava-common</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<!-- Test dependencies -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.janelia.saalfeldlab</groupId>
<artifactId>n5-universe</artifactId>
<exclusions>
<exclusion>
<groupId>org.janelia.saalfeldlab</groupId>
<artifactId>n5</artifactId>
</exclusion>
</exclusions>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.imagej</groupId>
<artifactId>ij</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.imglib2</groupId>
<artifactId>imglib2</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.imglib2</groupId>
<artifactId>imglib2-ij</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cisd</groupId>
<artifactId>jhdf5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>${commons-collections4.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>info.picocli</groupId>
<artifactId>picocli</artifactId>
<version>4.3.2</version>
<scope>test</scope>
</dependency>
<!-- JMH -->
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>scijava.public</id>
<url>https://maven.scijava.org/content/groups/public</url>
</repository>
</repositories>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>timestamp-property</id>
<goals>
<goal>timestamp-property</goal>
</goals>
<phase>validate</phase>
<configuration>
<name>current.year</name>
<pattern>yyyy</pattern>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy</id>
<phase>compile</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}</outputDirectory>
<resources>
<resource>
<directory>doc</directory>
<includes>
<include>*.md</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
================================================
FILE: scripts/fsLockValidation
================================================
#!/bin/bash
#
# Run FsLockingValidation N times in parallel.
#
# Usage:
# [N=<processes>] ./fsLockValidation [FsLockingValidation options...]
#
# Example:
# N=4 ./fsLockValidation --file /tmp/shard-test --num-repeats 5000
N=${N:-2}
OWN_DIR="$(readlink -f "$(dirname "${BASH_SOURCE[0]}")")"
POM="$OWN_DIR/../pom.xml"
TARGET="$OWN_DIR/../target"
if [ ! -d "$TARGET/test-classes" ]; then
echo "test-classes not found -- run 'mvn test-compile' in n5/ first" >&2
exit 1
fi
echo "Building classpath..."
CP=$(mvn -q -f "$POM" dependency:build-classpath \
-DincludeScope=test \
-Dmdep.outputFile=/dev/stdout \
2>/dev/null)
CP="$TARGET/test-classes:$TARGET/classes:$CP"
cleanup() {
kill "${pids[@]}" 2>/dev/null
wait "${pids[@]}" 2>/dev/null
}
trap cleanup INT TERM EXIT
echo "Launching $N processes..."
pids=()
for i in $(seq 1 $N); do
java -cp "$CP" org.janelia.saalfeldlab.n5.kva.FsLockingValidation "$@" &
pids+=($!)
done
# Wait for all processes and collect exit codes
all_ok=true
for i in "${!pids[@]}"; do
pid=${pids[$i]}
wait "$pid"
code=$?
if [ $code -ne 0 ]; then
echo "Process $((i+1)) (pid $pid) exited with code $code" >&2
all_ok=false
fi
done
if $all_ok; then
echo "All $N processes completed without errors."
else
echo "One or more processes reported errors." >&2
exit 1
fi
================================================
FILE: scripts/writeLockTest.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
TEST_DIR=/tmp/write-lock-test.zarr
[ -d "$TEST_DIR" ] && rm -r -- "$TEST_DIR"
if [ ! -d "test-classes" ]; then
mvn test-compile
fi
mvn -e -q exec:java \
-Dexec.mainClass=org.janelia.saalfeldlab.n5.WriteLockExp \
-Dexec.classpathScope=test \
-Dexec.args="/tmp/write-lock-test.zarr 0" &
pid1=$!
mvn -e -q exec:java \
-Dexec.mainClass=org.janelia.saalfeldlab.n5.WriteLockExp \
-Dexec.classpathScope=test \
-Dexec.args="/tmp/write-lock-test.zarr 1" &
pid2=$!
trap 'kill "$pid1" "$pid2" 2>/dev/null || true' EXIT INT TERM
wait "$pid1"
wait "$pid2"
================================================
FILE: src/main/java/org/janelia/saalfeldlab/n5/AbstractDataBlock.java
================================================
package org.janelia.saalfeldlab.n5;
import java.util.function.ToIntFunction;
/**
* Abstract base class for {@link DataBlock} implementations.
*
* @param <T>
* the block data type
*
* @author Stephan Saalfeld
*/
public abstract class AbstractDataBlock<T> implements DataBlock<T> {
protected final int[] size;
protected final long[] gridPosition;
protected final T data;
private final ToIntFunction<T> numElements;
public AbstractDataBlock(
final int[] size,
final long[] gridPosition,
final T data,
final ToIntFunction<T> numElements) {
this.size = size;
this.gridPosition = gridPosition;
this.data = data;
this.numElements = numElements;
}
@Override
public int[] getSize() {
return size;
}
@Override
public long[] getGridPosition() {
return gridPosition;
}
@Override
public T getData() {
return data;
}
@Override
public int getNumElements() {
return numElements.applyAsInt(data);
}
}
================================================
FILE: src/main/java/org/janelia/saalfeldlab/n5/BufferedKvaLockedChannel.java
================================================
package org.janelia.saalfeldlab.n5;
import org.apache.commons.io.input.ProxyInputStream;
import org.janelia.saalfeldlab.n5.readdata.ReadData;
import org.janelia.saalfeldlab.n5.readdata.VolatileReadData;
import java.io.*;
class BufferedKvaLockedChannel implements LockedChannel {
private final KeyValueAccess kva;
private final String key;
private ByteArrayOutputStream baos = null;
BufferedKvaLockedChannel(final KeyValueAccess kva, final String key) {
this.kva = kva;
this.key = key;
}
@Override
public Reader newReader() throws N5Exception.N5IOException {
return new InputStreamReader(newInputStream());
}
@Override
public InputStream newInputStream() throws N5Exception.N5IOException {
VolatileReadData volatileReadData = kva.createReadData(key);
return new ProxyInputStream(volatileReadData.inputStream()) {
@Override
public void close() throws IOException {
super.close();
volatileReadData.close();
}
};
}
@Override
public Writer newWriter() throws N5Exception.N5IOException {
return new BufferedWriter(new OutputStreamWriter(newOutputStream()));
}
@Override
public OutputStream newOutputStream() throws N5Exception.N5IOException {
if (baos == null)
baos = new ByteArrayOutputStream();
return baos;
}
@Override
public void close() throws IOException {
if (baos != null && baos.size() > 0)
kva.write(key, ReadData.from(baos.toByteArray()));
}
}
================================================
FILE: src/main/java/org/janelia/saalfeldlab/n5/ByteArrayDataBlock.java
================================================
package org.janelia.saalfeldlab.n5;
public class ByteArrayDataBlock extends AbstractDataBlock<byte[]> {
public ByteArrayDataBlock(final int[] size, final long[] gridPosition, final byte[] data) {
super(size, gridPosition, data, a -> a.length);
}
}
================================================
FILE: src/main/java/org/janelia/saalfeldlab/n5/Bzip2Compression.java
================================================
package org.janelia.saalfeldlab.n5;
import java.io.IOException;
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorOutputStream;
import org.janelia.saalfeldlab.n5.Compression.CompressionType;
import org.janelia.saalfeldlab.n5.N5Exception.N5IOException;
import org.janelia.saalfeldlab.n5.readdata.ReadData;
import org.janelia.saalfeldlab.n5.serialization.NameConfig;
@CompressionType("bzip2")
@NameConfig.Name("bzip2")
public class Bzip2Compression implements Compression {
private static final long serialVersionUID = -4873117458390529118L;
@CompressionParameter
@NameConfig.Parameter
private final int blockSize;
public Bzip2Compression(final int blockSize) {
this.blockSize = blockSize;
}
public Bzip2Compression() {
this(BZip2CompressorOutputStream.MAX_BLOCKSIZE);
}
@Override
public boolean equals(final Object other) {
if (other == null || other.getClass() != Bzip2Compression.class)
return false;
else
return blockSize == ((Bzip2Compression)other).blockSize;
}
@Override
public ReadData decode(final ReadData readData) throws N5IOException {
try {
return ReadData.from(new BZip2CompressorInputStream(readData.inputStream()));
} catch (IOException e) {
throw new N5IOException(e);
}
}
@Override
public ReadData encode(final ReadData readData) {
return readData.encode(out -> new BZip2CompressorOutputStream(out, blockSize));
}
}
================================================
FILE: src/main/java/org/janelia/saalfeldlab/n5/CachedGsonKeyValueN5Reader.java
================================================
package org.janelia.saalfeldlab.n5;
import java.lang.reflect.Type;
import com.google.gson.JsonSyntaxException;
import org.janelia.saalfeldlab.n5.N5Exception.N5IOException;
import org.janelia.saalfeldlab.n5.cache.N5JsonCache;
import org.janelia.saalfeldlab.n5.cache.N5JsonCacheableContainer;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
/**
* {@link N5Reader} implementation through {@link KeyValueAccess} with JSON
* attributes parsed with {@link Gson}.
*
*/
public interface CachedGsonKeyValueN5Reader extends GsonKeyValueN5Reader, N5JsonCacheableContainer {
default N5JsonCache newCache() {
return new N5JsonCache(this);
}
boolean cacheMeta();
N5JsonCache getCache();
@Override
default JsonElement getAttributesFromContainer(final String normalPathName, final String normalCacheKey) {
// this implementation doesn't use cache key, but rather depends on
// attributesPath being implemented
return GsonKeyValueN5Reader.super.getAttributes(normalPathName);
}
@Override
default DatasetAttributes getDatasetAttributes(final String pathName) {
final String normalPath = N5URI.normalizeGroupPath(pathName);
final JsonElement attributes;
if (!datasetExists(pathName))
return null;
if (cacheMeta()) {
attributes = getCache().getAttributes(normalPath, getAttributesKey());
} else {
attributes = GsonKeyValueN5Reader.super.getAttributes(normalPath);
}
return createDatasetAttributes(attributes);
}
default DatasetAttributes normalGetDatasetAttributes(final String pathName) throws N5IOException {
final String normalPath = N5URI.normalizeGroupPath(pathName);
final JsonElement attributes = GsonKeyValueN5Reader.super.getAttributes(normalPath);
return createDatasetAttributes(attributes);
}
@Override
default <T> T getAttribute(
final String pathName,
final String key,
final Class<T> clazz) throws N5Exception {
final String normalPathName = N5URI.normalizeGroupPath(pathName);
final String normalizedAttributePath = N5URI.normalizeAttributePath(key);
final JsonElement attributes;
if (cacheMeta()) {
attributes = getCache().getAttributes(normalPathName, getAttributesKey());
} else {
attributes = GsonKeyValueN5Reader.super.getAttributes(normalPathName);
}
try {
return GsonUtils.readAttribute(attributes, normalizedAttributePath, clazz, getGson());
} catch (JsonSyntaxException | NumberFormatException | ClassCastException e) {
throw new N5Exception.N5ClassCastException(e);
}
}
@Override
default <T> T getAttribute(
final String pathName,
final String key,
final Type type) throws N5Exception {
final String normalPathName = N5URI.normalizeGroupPath(pathName);
final String normalizedAttributePath = N5URI.normalizeAttributePath(key);
JsonElement attributes;
if (cacheMeta()) {
attributes = getCache().getAttributes(normalPathName, getAttributesKey());
} else {
attributes = GsonKeyValueN5Reader.super.getAttributes(normalPathName);
}
try {
return GsonUtils.readAttribute(attributes, normalizedAttributePath, type, getGson());
} catch (JsonSyntaxException | NumberFormatException | ClassCastException e) {
throw new N5Exception.N5ClassCastException(e);
}
}
@Override
default boolean exists(final String pathName) {
final String normalPathName = N5URI.normalizeGroupPath(pathName);
if (cacheMeta())
return getCache().isGroup(normalPathName, getAttributesKey());
else {
return existsFromContainer(normalPathName, null);
}
}
@Override
default boolean existsFromContainer(final String normalPathName, final String normalCacheKey) {
final KeyValueAccess kva = getKeyValueAccess();
if (normalCacheKey == null)
return kva.isDirectory(kva.compose(getURI(), normalPathName));
else
return kva.isFile(kva.compose(getURI(), normalPathName, normalCacheKey));
}
@Override
default boolean groupExists(final String pathName) {
final String normalPathName = N5URI.normalizeGroupPath(pathName);
if (cacheMeta())
return getCache().isGroup(normalPathName, null);
else {
return isGroupFromContainer(normalPathName);
}
}
@Override
default boolean isGroupFromContainer(final String normalPathName) {
return GsonKeyValueN5Reader.super.groupExists(normalPathName);
}
@Override
default boolean isGroupFromAttributes(final String normalCacheKey, final JsonElement attributes) {
return true;
}
@Override
default boolean datasetExists(final String pathName) throws N5IOException {
final String normalPathName = N5URI.normalizeGroupPath(pathName);
if (cacheMeta()) {
return getCache().isDataset(normalPathName, getAttributesKey());
}
return isDatasetFromContainer(normalPathName);
}
@Override
default boolean isDatasetFromContainer(final String normalPathName) throws N5IOException {
return normalGetDatasetAttributes(normalPathName) != null;
}
@Override
default boolean isDatasetFromAttributes(final String normalCacheKey, final JsonElement attributes) {
return isGroupFromAttributes(normalCacheKey, attributes) && createDatasetAttributes(attributes) != null;
}
/**
* Reads or creates the attributes map of a group or dataset.
*
* @param pathName
* group path
* @return the attribute
* @throws N5IOException if an IO error occurs while reading the attribute
*/
@Override
default JsonElement getAttributes(final String pathName) throws N5IOException {
final String groupPath = N5URI.normalizeGroupPath(pathName);
/* If cached, return the cache */
if (cacheMeta()) {
return getCache().getAttributes(groupPath, getAttributesKey());
} else {
return GsonKeyValueN5Reader.super.getAttributes(groupPath);
}
}
@Override
default String[] list(final String pathName) throws N5IOException {
final String normalPath = N5URI.normalizeGroupPath(pathName);
if (cacheMeta()) {
return getCache().list(normalPath);
} else {
return GsonKeyValueN5Reader.super.list(normalPath);
}
}
@Override
default String[] listFromContainer(final String normalPathName) {
// this implementation doesn't use cache key, but rather depends on
return GsonKeyValueN5Reader.super.list(normalPathName);
}
/**
* Check for attributes that are required for a group to be a dataset.
*
* @param attributes
* to check for dataset attributes
* @return if {@link DatasetAttributes#DIMENSIONS_KEY} and
* {@link DatasetAttributes#DATA_TYPE_KEY} are present
*/
static boolean hasDatasetAttributes(final JsonElement attributes) {
if (attributes == null || !attributes.isJsonObject()) {
return false;
}
final JsonObject metadataCache = attributes.getAsJsonObject();
return metadataCache.has(DatasetAttributes.DIMENSIONS_KEY)
&& metadataCache.has(DatasetAttributes.DATA_TYPE_KEY);
}
}
================================================
FILE: src/main/java/org/janelia/saalfeldlab/n5/CachedGsonKeyValueN5Writer.java
================================================
package org.janelia.saalfeldlab.n5;
import org.janelia.saalfeldlab.n5.N5Exception.N5IOException;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
/**
* Cached default implementation of {@link N5Writer} with JSON attributes parsed
* with {@link Gson}.
*/
public interface CachedGsonKeyValueN5Writer extends CachedGsonKeyValueN5Reader, GsonKeyValueN5Writer {
@Override
default void setVersion(final String path) throws N5Exception {
final Version version = getVersion();
if (!VERSION.isCompatible(version))
throw new N5IOException("Incompatible version " + version + " (this is " + VERSION + ").");
if (!VERSION.equals(version))
setAttribute("/", VERSION_KEY, VERSION.toString());;
}
@Override
default void createGroup(final String path) throws N5Exception {
final String normalPath = N5URI.normalizeGroupPath(path);
// 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 (groupExists(normalPath))
return;
else if (datasetExists(normalPath))
throw new N5Exception("Can't make a group on existing dataset.");
getKeyValueAccess().createDirectories(absoluteGroupPath(normalPath));
if (cacheMeta()) {
// check all nodes that are parents of the added node, if they have
// a children set, add the new child to it
getKeyValueAccess().parent(normalPath);
String[] pathParts = getKeyValueAccess().components(normalPath);
String parent = N5URI.normalizeGroupPath("/");
if (pathParts.length == 0) {
pathParts = new String[]{""};
}
for (final String child : pathParts) {
final String childPath = parent.isEmpty() ? child : parent + "/" + child;
getCache().initializeNonemptyCache(childPath, getAttributesKey());
getCache().updateCacheInfo(childPath, getAttributesKey());
// only add if the parent exists and has children cached already
if (parent != null && !child.isEmpty())
getCache().addChildIfPresent(parent, child);
parent = childPath;
}
}
}
@Override
default void writeAttributes(
final String normalGroupPath,
final JsonElement attributes) throws N5Exception {
writeAndCacheAttributes(normalGroupPath, attributes);
}
default void writeAndCacheAttributes(
final String normalGroupPath,
final JsonElement attributes) throws N5Exception {
GsonKeyValueN5Writer.super.writeAttributes(normalGroupPath, attributes);
if (cacheMeta()) {
JsonElement nullRespectingAttributes = attributes;
/*
* Gson only filters out nulls when you write the JsonElement. This
* means it doesn't filter them out when caching.
* To handle this, we explicitly writer the existing JsonElement to
* a new JsonElement.
* The output is identical to the input if:
* - serializeNulls is true
* - no null values are present
* - caching is turned off
*/
if (!getGson().serializeNulls()) {
nullRespectingAttributes = getGson().toJsonTree(attributes);
}
/* Update the cache, and write to the writer */
getCache().updateCacheInfo(normalGroupPath, getAttributesKey(), nullRespectingAttributes);
}
}
@Override
default boolean remove(final String path) throws N5Exception {
// GsonKeyValueN5Writer.super.remove(path)
/*
* 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);
if (getKeyValueAccess().isDirectory(groupPath))
getKeyValueAccess().delete(groupPath);
if (cacheMeta()) {
final String parentPath = getKeyValueAccess().parent(normalPath);
getCache().removeCache(parentPath, normalPath);
}
/* an IOException should have occurred if anything had failed midway */
return true;
}
}
================================================
FILE: src/main/java/org/janelia/saalfeldlab/n5/ChannelLock.java
================================================
package org.janelia.saalfeldlab.n5;
import java.io.Closeable;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.channels.OverlappingFileLockException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
/**
* Holds a channel and system-level file lock (shared for writing, non-shared
* for reading) and keeps it open until this {@code ChannelLock} is {@link
* #close() closed}.
*/
class ChannelLock implements Closeable {
private final FileChannel channel;
/**
* Hold a hard reference to the {@code FileLock} to make sure it is not
* prematurely released.
* <p>
* NB: We do not call {@code lock.release()} in {@link #close}, because at
* this point the channel might be already closed (by an external writer).
* {@code lock.release()} will throw an exception if the channel is already
* closed. Instead, we just close the channel which will automatically
* release the lock.
*/
@SuppressWarnings({"unused", "FieldCanBeLocal"})
private final FileLock lock;
private ChannelLock(final FileChannel channel, final FileLock lock) {
this.channel = channel;
this.lock = lock;
}
public void close() throws IOException {
// NB: We do not call lock.release() here, because it may throw an
// exception if the channel is already closed. Instead, we just close
// the channel. This will automatically release the lock. (And it is ok
// to close an already closed channel.)
channel.close();
}
FileChannel getChannel() {
return channel;
}
/**
* Create a {@link FileChannel} on the given {@code path} and lock it with a
* system-level {@link FileLock}. If there is an existing overlapping file
* lock, this method will block until the existing lock is released and the
* channel could be locked (by us).
* <p>
* The {@code FileLock} is exclusive if the {@code path} is locked {@code
* forWriting}, and shared otherwise.
* <p>
* If the {@code path} is locked {@code forWriting} non-existing file and
* the parent directories are created as needed.
*
* @throws IOException if an error occurs while opening the channel, or if
* the calling thread is interrupted while waiting for the {@code FileLock}.
*/
static ChannelLock lock(final Path path, final boolean forWriting, final LockingPolicy policy) throws IOException {
final FileChannel channel = openFileChannel(path, forWriting);
if (policy == LockingPolicy.UNSAFE) {
return new ChannelLock(channel, null);
}
try {
while (true) {
try {
final FileLock lock = channel.lock(0, Long.MAX_VALUE, !forWriting);
return new ChannelLock(channel, lock);
} catch (final OverlappingFileLockException e) {
try {
Thread.sleep(100);
} catch (final InterruptedException ie) {
Thread.currentThread().interrupt();
throw new IOException("Interrupted while waiting for file lock", ie);
}
}
}
} catch (Exception e) {
if (policy == LockingPolicy.STRICT) {
closeQuietly(channel);
throw e;
} else {
return new ChannelLock(channel, null);
}
}
}
/**
* Opens a file channel. If the channel is opened {@code forWriting},
* then this may create the file and the parent directories as needed.
*
* @throws IOException
* if the channel cannot be opened
*/
private static FileChannel openFileChannel(final Path path, final boolean forWriting) throws IOException {
if (forWriting) {
final Path parent = path.getParent();
if (parent != null) {
Files.createDirectories(parent);
}
return FileChannel.open(path, StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE);
} else {
return FileChannel.open(path, StandardOpenOption.READ);
}
}
private static void closeQuietly(final FileChannel fileChannel) {
if (fileChannel != null) {
try {
fileChannel.close();
} catch (final IOException | UncheckedIOException ignored) {
}
}
}
}
================================================
FILE: src/main/java/org/janelia/saalfeldlab/n5/Compression.java
================================================
package org.janelia.saalfeldlab.n5;
import java.io.Serializable;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.janelia.saalfeldlab.n5.codec.DataCodec;
import org.janelia.saalfeldlab.n5.codec.CodecInfo;
import org.janelia.saalfeldlab.n5.codec.DataCodecInfo;
import org.scijava.annotations.Indexable;
/**
* This interface is used to indicate that a {@link DataCodec} can be
* serialized as a "compression" for the N5 format (using the N5 API).
* <p>
* N5Readers and N5Writers for the N5 format can declare DataCodecs that
* implement this interface so that the {@link CompressionAdapter} is used for
* serialization.
* <p>
* See also: an alternative method for serializing general {@link CodecInfo}s is
* with the {@link NameConfigAdapter}. This interface remains for legacy
* (de)serialization.
*
* @author Stephan Saalfeld
*/
public interface Compression extends Serializable, DataCodec, DataCodecInfo {
/**
* Annotation for runtime discovery of compression schemes.
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Target(ElementType.TYPE)
@Indexable
@interface CompressionType {
String value();
}
/**
* Annotation for runtime discovery of compression schemes.
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Target(ElementType.FIELD)
@interface CompressionParameter {}
default String getType() {
final CompressionType compressionType = getClass().getAnnotation(CompressionType.class);
if (compressionType == null)
return null;
else
return compressionType.value();
}
@Override
default DataCodec create() {
return this;
}
}
================================================
FILE: src/main/java/org/janelia/saalfeldlab/n5/CompressionAdapter.java
================================================
package org.janelia.saalfeldlab.n5;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map.Entry;
import org.janelia.saalfeldlab.n5.Compression.CompressionParameter;
import org.janelia.saalfeldlab.n5.Compression.CompressionType;
import org.scijava.annotations.Index;
import org.scijava.annotations.IndexItem;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
/**
* Compression adapter, auto-discovers annotated compression implementations
* in the classpath.
*
* @author Stephan Saalfeld
*/
public class CompressionAdapter implements JsonDeserializer<Compression>, JsonSerializer<Compression> {
private static CompressionAdapter instance = null;
private final HashMap<String, Constructor<? extends Compression>> compressionConstructors = new HashMap<>();
private final HashMap<String, HashMap<String, Class<?>>> compressionParameters = new HashMap<>();
private static ArrayList<Field> getDeclaredFields(Class<?> clazz) {
final ArrayList<Field> fields = new ArrayList<>();
fields.addAll(Arrays.asList(clazz.getDeclaredFields()));
for (clazz = clazz.getSuperclass(); clazz != null; clazz = clazz.getSuperclass())
fields.addAll(Arrays.asList(clazz.getDeclaredFields()));
return fields;
}
@SuppressWarnings("unchecked")
public static synchronized void update(final boolean override) {
if (override || instance == null) {
final CompressionAdapter newInstance = new CompressionAdapter();
final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
final Index<CompressionType> annotationIndex = Index.load(CompressionType.class, classLoader);
for (final IndexItem<CompressionType> item : annotationIndex) {
Class<? extends Compression> clazz;
try {
clazz = (Class<? extends Compression>)Class.forName(item.className());
final String type = clazz.getAnnotation(CompressionType.class).value();
final Constructor<? extends Compression> constructor = clazz.getDeclaredConstructor();
final HashMap<String, Class<?>> parameters = new HashMap<>();
final ArrayList<Field> fields = getDeclaredFields(clazz);
for (final Field field : fields) {
if (field.getAnnotation(CompressionParameter.class) != null) {
parameters.put(field.getName(), field.getType());
}
}
newInstance.compressionConstructors.put(type, constructor);
newInstance.compressionParameters.put(type, parameters);
} catch (final NoClassDefFoundError | ClassNotFoundException | NoSuchMethodException | ClassCastException
| UnsatisfiedLinkError e) {
System.err.println("Compression '" + item.className() + "' could not be registered");
}
}
instance = newInstance;
}
}
public static void update() {
update(false);
}
@Override
public JsonElement serialize(
final Compression compression,
final Type typeOfSrc,
final JsonSerializationContext context) {
final String type = compression.getType();
final Class<? extends Compression> clazz = compression.getClass();
final JsonObject json = new JsonObject();
json.addProperty("type", type);
final HashMap<String, Class<?>> parameterTypes = compressionParameters.get(type);
try {
for (final Entry<String, Class<?>> parameterType : parameterTypes.entrySet()) {
final String name = parameterType.getKey();
final Field field = clazz.getDeclaredField(name);
final boolean isAccessible = field.isAccessible();
field.setAccessible(true);
final Object value = field.get(compression);
field.setAccessible(isAccessible);
json.add(parameterType.getKey(), context.serialize(value));
}
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace(System.err);
return null;
}
return json;
}
@Override
public Compression deserialize(
final JsonElement json,
final Type typeOfT,
final JsonDeserializationContext context) throws JsonParseException {
final JsonObject jsonObject = json.getAsJsonObject();
final JsonElement jsonType = jsonObject.get("type");
if (jsonType == null)
return null;
final String type = jsonType.getAsString();
final Constructor<? extends Compression> constructor = compressionConstructors.get(type);
final Compression compression;
try {
compression = constructor.newInstance();
final HashMap<String, Class<?>> parameterTypes = compressionParameters.get(type);
for (final Entry<String, Class<?>> parameterType : parameterTypes.entrySet()) {
final String name = parameterType.getKey();
if (jsonObject.has(name)) {
final Object parameter = context.deserialize(jsonObject.get(name), parameterType.getValue());
ReflectionUtils.setFieldValue(compression, name, parameter);
}
}
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
| SecurityException | NoSuchFieldException e) {
e.printStackTrace(System.err);
return null;
}
return compression;
}
public static CompressionAdapter getJsonAdapter() {
if (instance == null)
update();
return instance;
}
}
================================================
FILE: src/main/java/org/janelia/saalfeldlab/n5/DataBlock.java
================================================
package org.janelia.saalfeldlab.n5;
/**
* Interface for data blocks. A data block has data, a position on the block
* grid, and a size.
*
* @param <T> type of the data contained in the DataBlock
*
* @author Stephan Saalfeld
*/
public interface DataBlock<T> {
/**
* Returns the size of this data block.
* <p>
* The size of a data block is expected to be smaller than or equal to the
* spacing of the block grid. The dimensionality of size is expected to be
* equal to the dimensionality of the dataset. Consistency is not enforced.
*
* @return size of the data block
*/
int[] getSize();
/**
* Returns the position of this data block on the block grid relative to dataset.
* <p>
* The dimensionality of the grid position is expected to be equal to the
* dimensionality of the dataset. Consistency is not enforced.
*
* @return position on the block grid
*/
long[] getGridPosition();
/**
* Returns the data object held by this data block.
*
* @return data object
*/
T getData();
/**
* Returns the number of elements in this {@link DataBlock}. This number is
* not necessarily equal {@link #getNumElements(int[])
* getNumElements(getSize())}.
*
* @return the number of elements
*/
int getNumElements();
/**
* Returns the number of elements in a box of given size.
*
* @param size
* the size
* @return the number of elements
*/
static int getNumElements(final int[] size) {
int n = size[0];
for (int i = 1; i < size.length; ++i)
n *= size[i];
return n;
}
/**
* Factory for creating {@code DataBlock<T>}.
*
* @param <T>
* type of the data contained in the DataBlock
*/
interface DataBlockFactory<T> {
/**
* Create a new {@link DataBlock} with the given {@code blockSize}, {@code gridPosition}, and {@code data} content.
*
* @param blockSize
* the block size
* @param gridPosition
* the grid position
* @param data
* the data object
*
* @return a new DataBlock
*/
DataBlock<T> createDataBlock(int[] blockSize, long[] gridPosition, T data);
}
}
================================================
FILE: src/main/java/org/janelia/saalfeldlab/n5/DataType.java
================================================
package org.janelia.saalfeldlab.n5;
import java.lang.reflect.Type;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
/**
* Enumerates available data types.
*
* @author Stephan Saalfeld
*/
public enum DataType {
UINT8(
"uint8",
(blockSize, gridPosition, numElements) -> new ByteArrayDataBlock(
blockSize,
gridPosition,
new byte[numElements])),
UINT16(
"uint16",
(blockSize, gridPosition, numElements) -> new ShortArrayDataBlock(
blockSize,
gridPosition,
new short[numElements])),
UINT32(
"uint32",
(blockSize, gridPosition, numElements) -> new IntArrayDataBlock(
blockSize,
gridPosition,
new int[numElements])),
UINT64(
"uint64",
(blockSize, gridPosition, numElements) -> new LongArrayDataBlock(
blockSize,
gridPosition,
new long[numElements])),
INT8(
"int8",
(blockSize, gridPosition, numElements) -> new ByteArrayDataBlock(
blockSize,
gridPosition,
new byte[numElements])),
INT16(
"int16",
(blockSize, gridPosition, numElements) -> new ShortArrayDataBlock(
blockSize,
gridPosition,
new short[numElements])),
INT32(
"int32",
(blockSize, gridPosition, numElements) -> new IntArrayDataBlock(
blockSize,
gridPosition,
new int[numElements])),
INT64(
"int64",
(blockSize, gridPosition, numElements) -> new LongArrayDataBlock(
blockSize,
gridPosition,
new long[numElements])),
FLOAT32(
"float32",
(blockSize, gridPosition, numElements) -> new FloatArrayDataBlock(
blockSize,
gridPosition,
new float[numElements])),
FLOAT64(
"float64",
(blockSize, gridPosition, numElements) -> new DoubleArrayDataBlock(
blockSize,
gridPosition,
new double[numElements])),
STRING(
"string",
(blockSize, gridPosition, numElements) -> new StringDataBlock(
blockSize,
gridPosition,
new String[numElements])),
OBJECT(
"object",
(blockSize, gridPosition, numElements) -> new ByteArrayDataBlock(
blockSize,
gridPosition,
new byte[numElements]));
private final String label;
private final DataBlockFactory dataBlockFactory;
DataType(final String label, final DataBlockFactory dataBlockFactory) {
this.label = label;
this.dataBlockFactory = dataBlockFactory;
}
@Override
public String toString() {
return label;
}
public static DataType fromString(final String string) {
for (final DataType value : values())
if (value.toString().equals(string))
return value;
return null;
}
/**
* Factory for {@link DataBlock DataBlocks}.
*
* @param blockSize
* the block size
* @param gridPosition
* the grid position
* @param numElements
* the number of elements (not necessarily one element per block
* element)
* @return the data block
*/
public DataBlock<?> createDataBlock(final int[] blockSize, final long[] gridPosition, final int numElements) {
return dataBlockFactory.createDataBlock(blockSize, gridPosition, numElements);
}
/**
* Factory for {@link DataBlock DataBlocks} with one data element for each
* block element (e.g. pixel image).
*
* @param blockSize
* the block size
* @param gridPosition
* the grid position
* @return the data block
*/
public DataBlock<?> createDataBlock(final int[] blockSize, final long[] gridPosition) {
return dataBlockFactory.createDataBlock(blockSize, gridPosition, DataBlock.getNumElements(blockSize));
}
private interface DataBlockFactory {
DataBlock<?> createDataBlock(final int[] blockSize, final long[] gridPosition, final int numElements);
}
static public class JsonAdapter implements JsonDeserializer<DataType>, JsonSerializer<DataType> {
@Override
public DataType deserialize(
final JsonElement json,
final Type typeOfT,
final JsonDeserializationContext context) throws JsonParseException {
return DataType.fromString(json.getAsString());
}
@Override
public JsonElement serialize(
final DataType src,
final Type typeOfSrc,
final JsonSerializationContext context) {
return new JsonPrimitive(src.toString());
}
}
}
================================================
FILE: src/main/java/org/janelia/saalfeldlab/n5/DatasetAttributes.java
================================================
package org.janelia.saalfeldlab.n5;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import org.janelia.saalfeldlab.n5.codec.BlockCodec;
import org.janelia.saalfeldlab.n5.codec.BlockCodecInfo;
import org.janelia.saalfeldlab.n5.codec.CodecInfo;
import org.janelia.saalfeldlab.n5.codec.N5BlockCodecInfo;
import org.janelia.saalfeldlab.n5.shard.DatasetAccess;
import org.janelia.saalfeldlab.n5.shard.DefaultDatasetAccess;
import org.janelia.saalfeldlab.n5.shard.ShardCodecInfo;
import org.janelia.saalfeldlab.n5.shard.Nesting.NestedGrid;
import java.io.Serializable;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.HashMap;
import java.util.stream.Collectors;
import org.janelia.saalfeldlab.n5.codec.DataCodecInfo;
import org.janelia.saalfeldlab.n5.codec.DatasetCodec;
import org.janelia.saalfeldlab.n5.codec.DatasetCodecInfo;
/**
* Mandatory dataset attributes:
*
* <ol>
* <li>long[] : dimensions</li>
* <li>int[] : blockSize</li>
* <li>{@link DataType} : dataType</li>
* <li>{@link CodecInfo}... : encode/decode routines</li>
* </ol>
*
* @author Stephan Saalfeld
*/
public class DatasetAttributes implements Serializable {
private static final long serialVersionUID = -4521467080388947553L;
public static final String DIMENSIONS_KEY = "dimensions";
public static final String BLOCK_SIZE_KEY = "blockSize";
public static final String SHARD_SIZE_KEY = "shardSize";
public static final String DATA_TYPE_KEY = "dataType";
public static final String COMPRESSION_KEY = "compression";
public static final String CODEC_KEY = "codecs";
public static final String[] N5_DATASET_ATTRIBUTES = new String[]{
DIMENSIONS_KEY, BLOCK_SIZE_KEY, DATA_TYPE_KEY, COMPRESSION_KEY, CODEC_KEY
};
/* version 0 */
protected static final String compressionTypeKey = "compressionType";
private final long[] dimensions;
// number of samples per chunk per dimension
private final int[] chunkSize;
// number of samples per block per dimension
// identical to chunkSize for non-sharded datasets
private final int[] blockSize;
private final DataType dataType;
private final JsonElement defaultValue;
private final BlockCodecInfo blockCodecInfo;
private final DataCodecInfo[] dataCodecInfos;
private final DatasetCodecInfo[] datasetCodecInfos;
private transient final DatasetAccess<?> access;
public DatasetAttributes(
final long[] dimensions,
final int[] blockSize,
final DataType dataType,
final JsonElement defaultValue,
final BlockCodecInfo blockCodecInfo,
final DatasetCodecInfo[] datasetCodecInfos,
final DataCodecInfo... dataCodecInfos) {
this.dimensions = dimensions;
this.dataType = dataType;
this.blockSize = blockSize;
this.defaultValue = defaultValue == null ? JsonNull.INSTANCE : defaultValue;
this.blockCodecInfo = blockCodecInfo == null ? defaultBlockCodecInfo() : blockCodecInfo;
this.datasetCodecInfos = datasetCodecInfos;
if (dataCodecInfos == null)
this.dataCodecInfos = new DataCodecInfo[0];
else
this.dataCodecInfos = Arrays.stream(dataCodecInfos)
.filter(it -> it != null && !(it instanceof RawCompression))
.toArray(DataCodecInfo[]::new);
access = createDatasetAccess();
chunkSize = access.getGrid().getBlockSize(0);
}
public DatasetAttributes(
final long[] dimensions,
final int[] outerBlockSize,
final DataType dataType,
final BlockCodecInfo blockCodecInfo,
final DatasetCodecInfo[] datasetCodecInfos,
final DataCodecInfo... dataCodecInfos) {
this(dimensions, outerBlockSize, dataType, JsonNull.INSTANCE,
blockCodecInfo, datasetCodecInfos, dataCodecInfos);
}
public DatasetAttributes(
final long[] dimensions,
final int[] outerBlockSize,
final DataType dataType,
final BlockCodecInfo blockCodecInfo,
final DataCodecInfo... dataCodecInfos) {
this(dimensions, outerBlockSize, dataType, blockCodecInfo, null, dataCodecInfos);
}
/**
* Constructs a DatasetAttributes instance with specified dimensions, block size, data type,
* and single compressor with default codec.
*
* @param dimensions the dimensions of the dataset
* @param blockSize the size of the blocks in the dataset
* @param dataType the data type of the dataset
* @param dataCodecInfos the codecs used encode/decode the data
*/
public DatasetAttributes(
final long[] dimensions,
final int[] blockSize,
final DataType dataType,
final DataCodecInfo... dataCodecInfos) {
this(dimensions, blockSize, dataType, null, dataCodecInfos);
}
/**
* Constructs a DatasetAttributes instance with specified dimensions, block size, data type, and default codecs
*
* @param dimensions the dimensions of the dataset
* @param blockSize the size of the blocks in the dataset
* @param dataType the data type of the dataset
*/
public DatasetAttributes(
final long[] dimensions,
final int[] blockSize,
final DataType dataType) {
this(dimensions, blockSize, dataType, new DataCodecInfo[0]);
}
private DatasetAccess<?> createDatasetAccess() {
final int m = nestingDepth(blockCodecInfo);
// There are m codecs: 1 DataBlock codecs, and m-1 shard codecs.
// The inner-most codec (the DataBlock codec) is at index 0.
final int[][] blockSizes = new int[m][];
// NestedGrid validates block sizes, so instantiate it before creating the blockCodecs
// blockCodecInfo.create below could fail unexpecedly with invalid
// blockSizes so validate first
blockSizes[m - 1] = blockSize;
BlockCodecInfo tmpInfo = blockCodecInfo;
for (int l = m - 1; l > 0; --l) {
final ShardCodecInfo info = (ShardCodecInfo)tmpInfo;
blockSizes[l - 1] = info.getInnerBlockSize();
tmpInfo = info.getInnerBlockCodecInfo();
}
BlockCodecInfo currentBlockCodecInfo = blockCodecInfo;
DataCodecInfo[] currentDataCodecInfos = dataCodecInfos;
DatasetCodecInfo[] datasetCodecInfos = this.datasetCodecInfos;
final NestedGrid grid = new NestedGrid(blockSizes, dimensions);
final BlockCodec<?>[] blockCodecs = new BlockCodec[m];
for (int l = m - 1; l >= 0; --l) {
blockCodecs[l] = currentBlockCodecInfo.create(dataType, blockSizes[l], currentDataCodecInfos);
if (l > 0) {
final ShardCodecInfo info = (ShardCodecInfo) currentBlockCodecInfo;
currentBlockCodecInfo = info.getInnerBlockCodecInfo();
currentDataCodecInfos = info.getInnerDataCodecInfos();
if (info.getInnerDataCodecInfos() != null) {
if (datasetCodecInfos != null && datasetCodecInfos.length > 0) {
throw new N5Exception.N5JsonParseException("Found DatasetCodecs both inside and outside of shards. Not handled");
}
else
datasetCodecInfos = info.getInnerDatasetCodecInfos();
}
}
}
// add dataset codecs
blockCodecs[0] = blockCodecWithDatasetCodecs(this, blockCodecs[0], datasetCodecInfos);
return new DefaultDatasetAccess<>(grid, blockCodecs);
}
@SuppressWarnings("unchecked")
private static BlockCodec<?> blockCodecWithDatasetCodecs(final DatasetAttributes attributes, final BlockCodec<?> blockCodec,
final DatasetCodecInfo[] datasetCodecInfos) {
BlockCodec<?> result = blockCodec;
if (datasetCodecInfos != null) {
for (final DatasetCodecInfo info : datasetCodecInfos) {
result = DatasetCodec.concatenate(info.create(attributes), (BlockCodec)result);
}
}
return result;
}
private static int nestingDepth(BlockCodecInfo info) {
if (info instanceof ShardCodecInfo) {
return 1 + nestingDepth(((ShardCodecInfo)info).getInnerBlockCodecInfo());
} else {
return 1;
}
}
protected BlockCodecInfo defaultBlockCodecInfo() {
return new N5BlockCodecInfo();
}
public long[] getDimensions() {
return dimensions;
}
public int getNumDimensions() {
return dimensions.length;
}
public int[] getChunkSize() {
return chunkSize;
}
public int[] getBlockSize() {
return blockSize;
}
public JsonElement getDefaultValue() {
return defaultValue;
}
public boolean isSharded() {
return blockCodecInfo instanceof ShardCodecInfo;
}
/**
* Only used for deserialization for N5 backwards compatibility.
* {@link Compression} is no longer a special case. Prefer to reference {@link #getDataCodecInfos()}
* Will return {@link RawCompression} if no compression is otherwise provided, for legacy compatibility.
* <p>
* Deprecated in favor of {@link #getDataCodecInfos()}.
*
* @return compression CodecInfo, if one was present, or else RawCompression
*/
@Deprecated
public Compression getCompression() {
return Arrays.stream(dataCodecInfos)
.filter(it -> it instanceof Compression)
.map(it -> (Compression)it)
.findFirst()
.orElse(new RawCompression());
}
public DataType getDataType() {
return dataType;
}
/**
* Get the {@link DatasetAccess} for this dataset.
*
* @return the {@code DatasetAccess} for this dataset
*/
protected <T> DatasetAccess<T> getDatasetAccess() {
return (DatasetAccess<T>) access;
}
/**
* Returns the {@code NestedGrid} for this dataset, from which block and
* shard sizes are accessible.
*
* @return the NestedGrid
*/
public NestedGrid getNestedBlockGrid() {
return getDatasetAccess().getGrid();
}
public BlockCodecInfo getBlockCodecInfo() {
return blockCodecInfo;
}
public DataCodecInfo[] getDataCodecInfos() {
return dataCodecInfos;
}
public DatasetCodecInfo[] getDatasetCodecInfos() {
return datasetCodecInfos;
}
public String relativeBlockPath(long... position) {
return Arrays.stream(position).mapToObj(Long::toString).collect(Collectors.joining("/"));
}
public HashMap<String, Object> asMap() {
final HashMap<String, Object> map = new HashMap<>();
map.put(DIMENSIONS_KEY, dimensions);
map.put(BLOCK_SIZE_KEY, chunkSize);
map.put(DATA_TYPE_KEY, dataType);
map.put(COMPRESSION_KEY, getCompression());
return map;
}
public static Builder builder(final long[] dimensions, final DataType dataType) {
return new Builder(dimensions, dataType);
}
public static Builder builder(final DatasetAttributes attributes) {
return new Builder(attributes);
}
private static final int[] DEFAULT_1D_BLOCK_SIZE = new int[]{65536};
private static final int[] DEFAULT_2D_BLOCK_SIZE = new int[]{512,512};
private static final int[] DEFAULT_3D_BLOCK_SIZE = new int[]{128,128,128};
private static final int DEFAULT_ND_DIM_LEN = 64;
protected static int[] defaultBlockSize(final long[] dimensions) {
final int[] blockSize;
if (dimensions.length == 1)
blockSize = DEFAULT_1D_BLOCK_SIZE.clone();
else if (dimensions.length == 2)
blockSize = DEFAULT_2D_BLOCK_SIZE.clone();
else if (dimensions.length == 3)
blockSize = DEFAULT_3D_BLOCK_SIZE.clone();
else {
blockSize = new int[dimensions.length];
Arrays.fill(blockSize, DEFAULT_ND_DIM_LEN);
}
for (int i = 0; i < blockSize.length; i++)
blockSize[i] = (int)Math.min(blockSize[i], dimensions[i]);
return blockSize;
}
public static class Builder {
private final long[] dimensions;
private final DataType dataType;
private int[] blockSize;
private DataCodecInfo[] dataCodecInfos = new DataCodecInfo[0];
public Builder(final long[] dimensions, final DataType dataType) {
this.dimensions = dimensions.clone();
this.dataType = dataType;
this.blockSize = defaultBlockSize(dimensions);
}
public Builder(final DatasetAttributes attributes) {
this.dimensions = attributes.getDimensions();
this.dataType = attributes.getDataType();
this.blockSize = attributes.getBlockSize();
this.dataCodecInfos = attributes.getDataCodecInfos();
}
public Builder blockSize(final int[] blockSize) {
this.blockSize = blockSize.clone();
return this;
}
/**
* Sets the compression codec. Has no effect if {@code compression} is
* null or {@link RawCompression}.
*
* @param compression the compression to use
* @return this builder
*/
public Builder compression(final Compression compression) {
if (compression != null && !(compression instanceof RawCompression))
this.dataCodecInfos = new DataCodecInfo[]{compression};
return this;
}
public DatasetAttributes build() {
final int[] resolvedBlockSize = blockSize != null ? blockSize : defaultBlockSize(dimensions);
return new DatasetAttributes(dimensions, resolvedBlockSize, dataType, new N5BlockCodecInfo(), null, dataCodecInfos);
}
}
private static DatasetAttributesAdapter adapter = null;
public static DatasetAttributesAdapter getJsonAdapter() {
if (adapter == null) {
adapter = new DatasetAttributesAdapter();
}
return adapter;
}
public static class DatasetAttributesAdapter implements JsonSerializer<DatasetAttributes>, JsonDeserializer<DatasetAttributes> {
@Override public DatasetAttributes deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
if (json == null || !json.isJsonObject())
return null;
final JsonObject obj = json.getAsJsonObject();
final boolean validKeySet = obj.has(DIMENSIONS_KEY)
&& obj.has(BLOCK_SIZE_KEY)
&& obj.has(DATA_TYPE_KEY)
&& (obj.has(CODEC_KEY) || obj.has(COMPRESSION_KEY) || obj.has(compressionTypeKey));
if (!validKeySet)
return null;
final long[] dimensions = context.deserialize(obj.get(DIMENSIONS_KEY), long[].class);
final int[] blockSize = context.deserialize(obj.get(BLOCK_SIZE_KEY), int[].class);
final DataType dataType = context.deserialize(obj.get(DATA_TYPE_KEY), DataType.class);
final BlockCodecInfo blockCodecInfo;
final DataCodecInfo[] dataCodecs;
if (obj.has(CODEC_KEY)) {
final CodecInfo[] codecs = context.deserialize(obj.get(CODEC_KEY), CodecInfo[].class);
blockCodecInfo = (BlockCodecInfo)codecs[0];
dataCodecs = new DataCodecInfo[codecs.length - 1];
for (int i = 1; i < codecs.length; i++) {
dataCodecs[i - 1] = (DataCodecInfo)codecs[i];
}
} else if (obj.has(COMPRESSION_KEY)) {
final Compression compression = CompressionAdapter.getJsonAdapter().deserialize(obj.get(COMPRESSION_KEY), Compression.class, context);
dataCodecs = new DataCodecInfo[]{compression};
blockCodecInfo = new N5BlockCodecInfo();
} else if (obj.has(compressionTypeKey)) {
final Compression compression = getCompressionVersion0(obj.get(compressionTypeKey).getAsString());
dataCodecs = new DataCodecInfo[]{compression};
blockCodecInfo = new N5BlockCodecInfo();
} else {
return null;
}
return new DatasetAttributes(dimensions, blockSize, dataType, blockCodecInfo, dataCodecs);
}
//FIXME
// this implements multi-codec serialization for N5. We probably don't want this now
@Override public JsonElement serialize(DatasetAttributes src, Type typeOfSrc, JsonSerializationContext context) {
final JsonObject obj = new JsonObject();
obj.add(DIMENSIONS_KEY, context.serialize(src.dimensions));
obj.add(BLOCK_SIZE_KEY, context.serialize(src.chunkSize));
obj.add(DATA_TYPE_KEY, context.serialize(src.dataType));
final DataCodecInfo[] codecs = src.dataCodecInfos;
// length > 1 is actually invalid, but this is checked on construction
if (codecs.length == 0)
obj.add(COMPRESSION_KEY, context.serialize(new RawCompression()));
else
obj.add(COMPRESSION_KEY, context.serialize(codecs[0]));
return obj;
}
private static Compression getCompressionVersion0(final String compressionVersion0Name) {
switch (compressionVersion0Name) {
case "raw":
return new RawCompression();
case "gzip":
return new GzipCompression();
case "bzip2":
return new Bzip2Compression();
case "lz4":
return new Lz4Compression();
case "xz":
return new XzCompression();
}
return null;
}
}
}
================================================
FILE: src/main/java/org/janelia/saalfeldlab/n5/DoubleArrayDataBlock.java
================================================
package org.janelia.saalfeldlab.n5;
public class DoubleArrayDataBlock extends AbstractDataBlock<double[]> {
public DoubleArrayDataBlock(final int[] size, final long[] gridPosition, final double[] data) {
super(size, gridPosition, data, a -> a.length);
}
}
================================================
FILE: src/main/java/org/janelia/saalfeldlab/n5/FileKeyLockManager.java
================================================
package org.janelia.saalfeldlab.n5;
import java.io.IOException;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.nio.channels.FileLock;
import java.nio.file.Path;
import java.util.Collections;
import java.util.EnumMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import static org.janelia.saalfeldlab.n5.LockingPolicy.STRICT;
/**
* Provides thread-safe and process-safe read/write locking for filesystem paths.
* Uses thread locks for JVM coordination and file locks for inter-process coordination.
*/
class FileKeyLockManager {
private static final Map<LockingPolicy, FileKeyLockManager> managers = Collections.synchronizedMap(new EnumMap<>(LockingPolicy.class));
static FileKeyLockManager forPolicy(final LockingPolicy policy) {
return managers.computeIfAbsent(policy, FileKeyLockManager::new);
}
/**
* @deprecated use {@link FileKeyLockManager#forPolicy(LockingPolicy)}
*/
@Deprecated
static final FileKeyLockManager FILE_LOCK_MANAGER = forPolicy(STRICT);
private final LockingPolicy policy;
/**
* Create a new {@link FileKeyLockManager} with the specified locking policy.
* <p>
* The given locking {@link LockingPolicy policy} applies to OS-level locking.
* For both the {@code STRICT} and {@code PERMISSIVE} policy, a {@link
* FileLock} is obtained. If this fails, {@code STRICT} will throw an {@code
* IOException}. {@code PERMISSIVE} will proceed without locking. {@code
* UNSAFE} will not attempt OS-level locking, however will still manage
* mutual exclusion of readers and writers in the same JVM. Trying to lock
* the same path with different locking policies will throw an {@code
* IOException}.
*
* @param policy
* the locking policy
*/
private FileKeyLockManager(final LockingPolicy policy) {
this.policy = policy;
}
private final ConcurrentHashMap<String, WeakValue> locks = new ConcurrentHashMap<>();
private final ReferenceQueue<KeyLockState> refQueue = new ReferenceQueue<>();
private static class WeakValue extends WeakReference<KeyLockState> {
final String key;
WeakValue(
final String key,
final KeyLockState value,
final ReferenceQueue<KeyLockState> queue) {
super(value, queue);
this.key = key;
}
}
/**
* Remove entries from the cache whose references have been
* garbage-collected.
*/
private void cleanUp()
{
while (true) {
final WeakValue ref = (WeakValue) refQueue.poll();
if (ref == null)
break;
locks.remove(ref.key, ref);
}
}
private KeyLockState keyLockState(final Path path, final LockingPolicy policy) throws IOException {
final String key = path.toAbsolutePath().toString();
cleanUp();
final WeakValue existingRef = locks.get(key);
KeyLockState state = existingRef == null ? null : existingRef.get();
if (state != null) {
return state;
}
final KeyLockState newState = new KeyLockState(path, policy);
while (state == null) {
final WeakValue ref = locks.compute(key,
(k, v) -> (v != null && v.get() != null)
? v
: new WeakValue(k, newState, refQueue));
state = ref.get();
}
return state;
}
/**
* Acquires a read lock for the specified key. Multiple threads can hold
* read locks for the same key simultaneously.
* <p>
* The first reader will acquire a shared file lock. Subsequent readers
* only acquire the thread-level lock.
*
* @param path
* the key (file path) to lock for reading
*
* @return a {@link LockedChannel} that must be closed when done
*
* @throws IOException
* if acquiring the file lock fails
*/
public LockedFileChannel lockForReading(final Path path) throws IOException {
return keyLockState(path, policy).acquireRead();
}
/**
* Acquires a write lock for the specified key. Only one thread can hold a
* write lock for a key at a time, and no readers can hold locks.
*
* @param path
* the file path to lock for writing
*
* @return a {@link LockedChannel} that must be closed when done
*
* @throws IOException
* if acquiring the file lock fails
*/
public LockedFileChannel lockForWriting(final Path path) throws IOException {
return keyLockState(path, policy).acquireWrite();
}
/**
* Returns the number of keys currently being tracked.
*
* @return the number of keys with associated locks
*/
int size() {
return locks.size();
}
}
================================================
FILE: src/main/java/org/janelia/saalfeldlab/n5/FileSystemKeyValueAccess.java
================================================
package org.janelia.saalfeldlab.n5;
import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.ByteBuffer;
import java.nio.file.DirectoryNotEmptyException;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.FileSystemException;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.FileAttribute;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Iterator;
import java.util.stream.Stream;
import org.janelia.saalfeldlab.n5.N5Exception.N5IOException;
import org.janelia.saalfeldlab.n5.N5Exception.N5NoSuchKeyException;
import org.janelia.saalfeldlab.n5.readdata.LazyRead;
import org.janelia.saalfeldlab.n5.readdata.ReadData;
import org.janelia.saalfeldlab.n5.readdata.VolatileReadData;
/**
* Filesystem {@link KeyValueAccess}.
*
* @author Stephan Saalfeld
* @author Igor Pisarev
* @author Philipp Hanslovsky
*/
public class FileSystemKeyValueAccess implements KeyValueAccess {
private final FileKeyLockManager fileKeyLockManager;
public FileSystemKeyValueAccess() {
final LockingPolicy policy = LockingPolicy.fromString(System.getProperty("n5.ioPolicy", "permissive"));
this.fileKeyLockManager = FileKeyLockManager.forPolicy(policy);
}
private LockedFileChannel lockForReading(final Path path) throws N5IOException {
try {
return fileKeyLockManager.lockForReading(path);
} catch (final NoSuchFileException e) {
throw new N5NoSuchKeyException("No such file", e);
} catch (IOException | UncheckedIOException e) {
throw new N5IOException("Failed to lock file for reading: " + path, e);
}
}
private LockedFileChannel lockForWriting(final Path path) throws N5IOException {
try {
return fileKeyLockManager.lockForWriting(path);
} catch (final NoSuchFileException e) {
throw new N5NoSuchKeyException("No such file", e);
} catch (IOException | UncheckedIOException e) {
throw new N5IOException("Failed to lock file for writing: " + path, e);
}
}
@Override
public VolatileReadData createReadData(final String normalPath) {
return VolatileReadData.from(new FileLazyRead(Paths.get(normalPath)));
}
@Override
public void write(final String normalPath, final ReadData data) throws N5IOException {
final Path path = Paths.get(normalPath);
try (final LockedFileChannel channel = lockForWriting(path)) {
data.writeTo(channel.asOutputStream());
} catch (IOException e) {
throw new N5IOException(e);
}
}
@Override
public boolean isDirectory(final String normalPath) {
final Path path = Paths.get(normalPath);
return Files.isDirectory(path);
}
@Override
public boolean isFile(final String normalPath) {
final Path path = Paths.get(normalPath);
return Files.isRegularFile(path);
}
@Override
public boolean exists(final String normalPath) {
final Path path = Paths.get(normalPath);
return Files.exists(path);
}
@Override
public long size(final String normalPath) {
return size(Paths.get(normalPath));
}
private static long size(final Path path) {
try {
return Files.size(path);
} catch (NoSuchFileException e) {
throw new N5NoSuchKeyException("No such file", e);
} catch (IOException | UncheckedIOException e) {
throw new N5IOException(e);
}
}
@Override
public String[] listDirectories(final String normalPath) throws N5IOException {
final Path path = Paths.get(normalPath);
try (final Stream<Path> pathStream = Files.list(path)) {
return pathStream
.filter(Files::isDirectory)
.map(a -> path.relativize(a).toString())
.toArray(String[]::new);
} catch (NoSuchFileException e) {
throw new N5NoSuchKeyException("No such file", e);
} catch (IOException | UncheckedIOException e) {
throw new N5IOException("Failed to list directories", e);
}
}
@Override
public String[] list(final String normalPath) throws N5IOException {
final Path path = Paths.get(normalPath);
try (final Stream<Path> pathStream = Files.list(path)) {
return pathStream
.map(a -> path.relativize(a).toString())
.toArray(String[]::new);
} catch (NoSuchFileException e) {
throw new N5NoSuchKeyException("No such file", e);
} catch (IOException | UncheckedIOException e) {
throw new N5IOException("Failed to list files", e);
}
}
@Override
public String[] components(final String path) {
final Path fsPath = Paths.get(path);
final Path root = fsPath.getRoot();
final String separator = fsPath.getFileSystem().getSeparator();
final String[] components;
int o;
if (root == null) {
components = new String[fsPath.getNameCount()];
o = 0;
} else {
components = new String[fsPath.getNameCount() + 1];
components[0] = root.toString();
o = 1;
}
for (int i = o; i < components.length; ++i) {
String name = fsPath.getName(i - o).toString();
/* Preserve trailing slash on final component if present*/
if (i == components.length - 1) {
final String trailingSeparator = path.endsWith(separator) ? separator : path.endsWith("/") ? "/" : "";
name += trailingSeparator;
}
components[i] = name;
}
return components;
}
@Override
public String parent(final String path) {
final Path parent = Paths.get(path).getParent();
if (parent == null)
return null;
else
return parent.toString();
}
@Override
public String relativize(final String path, final String base) {
final Path basePath = Paths.get(base);
return basePath.relativize(Paths.get(path)).toString();
}
/**
* Returns a normalized path. It ensures correctness on both Unix and
* Windows,
* otherwise {@code pathName} is treated as UNC path on Windows, and
* {@code Paths.get(pathName, ...)} fails with {@code InvalidPathException}.
*
* @param path the path
* @return the normalized path, without leading slash
*/
@Override
public String normalize(final String path) {
return Paths.get(path).normalize().toString();
}
@Override
public URI uri(final String normalPath) throws URISyntaxException {
// normalize make absolute the scheme specific part only
try {
final URI normalUri = URI.create(normalPath);
if (normalUri.isAbsolute()) return normalUri.normalize();
} catch (final IllegalArgumentException e) {
return new File(normalPath).toURI().normalize();
}
return new File(normalPath).toURI().normalize();
}
@Override
public String compose(final String... components) {
if (components == null || components.length == 0)
return null;
if (components.length == 1)
return Paths.get(components[0]).toString();
return Paths.get(components[0], Arrays.copyOfRange(components, 1, components.length)).normalize().toString();
}
@Override
public String compose(URI uri, String... components) {
Path composedPath;
if (uri.isAbsolute())
composedPath = Paths.get(uri);
else
composedPath = Paths.get(uri.toString());
for (String component : components) {
if (component == null || component.isEmpty())
continue;
composedPath = composedPath.resolve(component);
}
return composedPath.toAbsolutePath().toString();
}
@Override
public void createDirectories(final String normalPath) throws N5IOException {
try {
createDirectories(Paths.get(normalPath));
} catch (NoSuchFileException e) {
throw new N5NoSuchKeyException("No such file", e);
} catch (IOException | UncheckedIOException e) {
throw new N5IOException("Failed to create directories", e);
}
}
@Override
public void delete(final String normalPath) throws N5IOException {
try {
final Path path = Paths.get(normalPath);
if (Files.isRegularFile(path))
try (final LockedFileChannel channel = lockForWriting(path)) {
Files.delete(path);
}
else {
try (final Stream<Path> pathStream = Files.walk(path)) {
for (final Iterator<Path> i = pathStream.sorted(Comparator.reverseOrder()).iterator(); i.hasNext();) {
final Path childPath = i.next();
if (Files.isRegularFile(childPath))
try (final LockedFileChannel channel = lockForWriting(childPath)) {
Files.delete(childPath);
}
else
tryDelete(childPath);
}
}
}
} catch (NoSuchFileException ignore) {
/* It doesn't exist; that's sufficient for us to not complain on a `delete` call */
} catch (IOException | UncheckedIOException e) {
throw new N5IOException("Failed to delete file at " + normalPath, e);
}
}
protected static void tryDelete(final Path path) throws IOException {
try {
Files.delete(path);
} catch (final DirectoryNotEmptyException e) {
/*
* Even though path is expected to be an empty directory, sometimes
* deletion fails on network filesystems when lock files are not
* cleared immediately after the leaves have been removed.
*/
try {
/* wait and reattempt */
Thread.sleep(100);
Files.delete(path);
} catch (final InterruptedException ex) {
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
}
/**
* This is a copy of {@link Files#createDirectories(Path, FileAttribute...)}
* that follows symlinks.
*
* Workaround for https://bugs.openjdk.java.net/browse/JDK-8130464
*
* Creates a directory by creating all nonexistent parent directories first.
* Unlike the {@link Files#createDirectories} method, an exception
* is not thrown if the directory could not be created because it already
* exists.
*
* <p>
* The {@code attrs} parameter is optional {@link FileAttribute
* file-attributes} to set atomically when creating the nonexistent
* directories. Each file attribute is identified by its {@link
* FileAttribute#name name}. If more than one attribute of the same name is
* included in the array then all but the last occurrence is ignored.
*
* <p>
* If this method fails, then it may do so after creating some, but not
* all, of the parent directories.
*
* @param dir
* the directory to create
*
* @param attrs
* an optional list of file attributes to set atomically when
* creating the directory
*
* @return the directory
*
* @throws UnsupportedOperationException
* if the array contains an attribute that cannot be set
* atomically
* when creating the directory
* @throws FileAlreadyExistsException
* if {@code dir} exists but is not a directory <i>(optional
* specific
* exception)</i>
* @throws IOException
* if an I/O error occurs
* @throws SecurityException
* in the case of the default provider, and a security manager
* is
* installed, the {@link SecurityManager#checkWrite(String)
* checkWrite}
* method is invoked prior to attempting to create a directory
* and
* its {@link SecurityManager#checkRead(String) checkRead} is
* invoked for each parent directory that is checked. If {@code
* dir} is not an absolute path then its {@link Path#toAbsolutePath
* toAbsolutePath} may need to be invoked to get its absolute
* path.
* This may invoke the security manager's {@link
* SecurityManager#checkPropertyAccess(String)
* checkPropertyAccess}
* method to check access to the system property
* {@code user.dir}
*/
protected static Path createDirectories(Path dir, final FileAttribute<?>... attrs) throws IOException {
// attempt to create the directory
try {
createAndCheckIsDirectory(dir, attrs);
return dir;
} catch (final FileAlreadyExistsException x) {
// file exists and is not a directory
throw x;
} catch (final IOException x) {
// parent may not exist or other reason
}
SecurityException se = null;
try {
dir = dir.toAbsolutePath();
} catch (final SecurityException x) {
// don't have permission to get absolute path
se = x;
}
// find a descendant that exists
Path parent = dir.getParent();
while (parent != null) {
try {
parent.getFileSystem().provider().checkAccess(parent);
break;
} catch (final NoSuchFileException x) {
// does not exist
}
parent = parent.getParent();
}
if (parent == null) {
// unable to find existing parent
if (se == null) {
throw new FileSystemException(
dir.toString(),
null,
"Unable to determine if root directory exists");
} else {
throw se;
}
}
// create directories
Path child = parent;
for (final Path name : parent.relativize(dir)) {
child = child.resolve(name);
createAndCheckIsDirectory(child, attrs);
}
return dir;
}
/**
* This is a copy of a previous Files#createAndCheckIsDirectory(Path,
* FileAttribute...) method that follows symlinks.
*
* Workaround for https://bugs.openjdk.java.net/browse/JDK-8130464
*
* Used by createDirectories to attempt to create a directory. A no-op if the
* directory already exists.
*
* @param dir directory path
* @param attrs file attributes
* @throws IOException the exception
*/
protected static void createAndCheckIsDirectory(
final Path dir,
final FileAttribute<?>... attrs) throws IOException {
try {
Files.createDirectory(dir, attrs);
} catch (final FileAlreadyExistsException x) {
if (!Files.isDirectory(dir))
throw x;
}
}
/**
* Verify that the range {@code [offset, offset+length)} is fully contained in {@code [0, channelSize)}.
*
* @throws IndexOutOfBoundsException
* if range is not fully contained
*/
private static void validBounds(final long channelSize, final long offset, final long length) throws IndexOutOfBoundsException {
if (offset < 0)
throw new IndexOutOfBoundsException("offset must be > 0, but was: " + offset);
else if (channelSize > 0 && offset >= channelSize) // offset == 0 and channelSize == 0 is okay
throw new IndexOutOfBoundsException("offset (" + offset + ") must be less than channel size (" + channelSize + ")");
else if (length >= 0 && offset + length > channelSize)
throw new IndexOutOfBoundsException("offset + length (" + (offset + length) + ") must be less than channel size (" + channelSize + ")");
}
private class FileLazyRead implements LazyRead {
private final Path path;
private LockedFileChannel lock; // TODO rename
FileLazyRead(final Path path) {
this.path = path;
lock = lockForReading(path);
}
@Override
public long size() throws N5IOException {
if (lock == null) {
throw new N5IOException("FileLazyRead is already closed.");
}
try {
return Files.size(path);
} catch (NoSuchFileException e) {
throw new N5NoSuchKeyException("No such file", e);
} catch (IOException | UncheckedIOException e) {
throw new N5IOException(e);
}
}
@Override
public ReadData materialize(final long offset, final long length) {
if (lock == null) {
throw new N5IOException("FileLazyRead is already closed.");
}
try {
final long channelSize = lock.size();
validBounds(channelSize, offset, length);
final long size = length < 0 ? (channelSize - offset) : length;
if (size > Integer.MAX_VALUE) {
throw new IndexOutOfBoundsException("Attempt to materialize too large data");
}
final byte[] data = new byte[(int) size];
lock.read(ByteBuffer.wrap(data), offset);
return ReadData.from(data);
} catch (IOException | UncheckedIOException e) {
throw new N5Exception.N5IOException(e);
}
}
@Override
public void close() throws IOException {
if (lock != null) {
lock.close();
lock = null;
}
}
}
}
================================================
FILE: src/main/java/org/janelia/saalfeldlab/n5/FloatArrayDataBlock.java
================================================
package org.janelia.saalfeldlab.n5;
public class FloatArrayDataBlock extends AbstractDataBlock<float[]> {
public FloatArrayDataBlock(final int[] size, final long[] gridPosition, final float[] data) {
super(size, gridPosition, data, a -> a.length);
}
}
================================================
FILE: src/main/java/org/janelia/saalfeldlab/n5/FsIoPolicy.java
================================================
package org.janelia.saalfeldlab.n5;
import org.janelia.saalfeldlab.n5.readdata.LazyRead;
import org.janelia.saalfeldlab.n5.readdata.ReadData;
import org.janelia.saalfeldlab.n5.readdata.VolatileReadData;
import java.io.Closeable;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UncheckedIOException;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.file.*;
import static org.janelia.saalfeldlab.n5.FileKeyLockManager.FILE_LOCK_MANAGER;
public class FsIoPolicy {
static final IoPolicy atomicWithFallback = IoPolicy.withFallback(new Atomic(), new Unsafe());
private static boolean validBounds(long channelSize, long offset, long length) {
if (offset < 0)
throw new N5Exception("offset must be > 0, but was: " + offset);
else if (channelSize > 0 && offset >= channelSize) // offset == 0 and channelSize == 0 is okay
throw new N5Exception("offset (" + offset + ") must be less than channel size (" + channelSize + ")");
else if (length >= 0 && offset + length > channelSize)
throw new N5Exception("offset + length (" + (offset + length) + ") must be less than channel size (" + channelSize + ")");
return true;
}
/**
* Opens a file channel. If the channel is opened {@code forWriting},
* then this may create the file and the parent directories as needed.
*
* @throws IOException
* if the channel cannot be opened
*/
static FileChannel openFileChannel(final Path path, final boolean forWriting) throws IOException {
if (forWriting) {
final Path parent = path.getParent();
/* if not null and not directory, it will call `createDirectories` but we expect it to throw an IOException */
if (parent != null && !parent.toFile().isDirectory()) {
Files.createDirectories(parent);
}
return FileChannel.open(path, StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE);
} else {
return FileChannel.open(path, StandardOpenOption.READ);
}
}
/**
* This method is necessary to handle the situtation where writing is successful, but `close` fails on the file channel.
* This has been observed to happen fairly consistently on MacOS when writing to a file mounted over SMB.
*
* @param readData to write to the {@code Path}
* @param path to write to
* @throws IOException if writing failed.
*/
private static void writeToPathIgnoreCloseException(ReadData readData, Path path) throws IOException {
FileChannel channel = openFileChannel(path, true);
OutputStream os = Channels.newOutputStream(channel);
try {
readData.writeTo(os);
os.flush();
channel.force(true);
} catch (Throwable e) {
os.close();
channel.close();
throw e;
}
/* if we get here, the write succeeded, and the os/channel may not be closed yet */
try {
os.close();
channel.close();
} catch (IOException | UncheckedIOException ignore) {
/* Ignore; we know the data was written already. */
}
}
public static class Unsafe implements IoPolicy {
@Override
public void write(String key, ReadData readData) throws IOException {
final Path path = Paths.get(key);
writeToPathIgnoreCloseException(readData, path);
}
@Override
public VolatileReadData read(final String key) throws IOException {
final Path path = Paths.get(key);
FileLazyRead fileLazyRead = new FileLazyRead(path, false);
return VolatileReadData.from(fileLazyRead);
}
@Override
public void delete(final String key) throws IOException {
final Path path = Paths.get(key);
Files.deleteIfExists(path);
}
}
public static class Atomic implements IoPolicy {
@Override
public void write(String key, ReadData readData) throws IOException {
final Path path = Paths.get(key);
try (LockedFileChannel channel = FILE_LOCK_MANAGER.lockForWriting(path)) {
readData.writeTo(channel.asOutputStream());
}
}
@Override
public VolatileReadData read(String key) throws IOException {
final Path path = Paths.get(key);
FileLazyRead fileLazyRead = new FileLazyRead(path, true);
return VolatileReadData.from(fileLazyRead);
}
@Override
public void delete(final String key) throws IOException {
final Path path = Paths.get(key);
if (!Files.isRegularFile(path))
Files.delete(path);
try (LockedFileChannel ignore = FILE_LOCK_MANAGER.lockForWriting(path)) {
Files.delete(path);
}
}
}
static class FileLazyRead implements LazyRead {
private static final Closeable NO_OP = () -> { };
private final Path path;
private Closeable lock;
FileLazyRead(final Path path) throws IOException {
this(path, true);
}
FileLazyRead(final Path path, final boolean requireLock ) throws IOException {
this.path = path;
if (requireLock)
lock = FILE_LOCK_MANAGER.lockForReading(path);
else
lock = NO_OP;
}
@Override
public long size() throws N5Exception.N5IOException {
if (lock == null) {
throw new N5Exception.N5IOException("FileLazyRead is already closed.");
}
try {
return Files.size(path);
} catch (NoSuchFileException e) {
throw new N5Exception.N5NoSuchKeyException("No such file", e);
} catch (IOException | UncheckedIOException e) {
throw new N5Exception.N5IOException(e);
}
}
@Override
public ReadData materialize(final long offset, final long length) {
if (lock == null) {
throw new N5Exception.N5IOException("FileLazyRead is already closed.");
}
ReadData readData = null;
try (final FileChannel channel = FileChannel.open(path, StandardOpenOption.READ)) {
channel.position(offset);
final long channelSize = channel.size();
if (!validBounds(channelSize, offset, length)) {
throw new IndexOutOfBoundsException();
}
final long size = length < 0 ? (channelSize - offset) : length;
if (size > Integer.MAX_VALUE) {
throw new IndexOutOfBoundsException("Attempt to materialize too large data");
}
final byte[] data = new byte[(int) size];
final ByteBuffer buf = ByteBuffer.wrap(data);
channel.read(buf);
readData = ReadData.from(data);
} catch (final NoSuchFileException e) {
throw new N5Exception.N5NoSuchKeyException("No such file", e);
} catch (IOException | UncheckedIOException e) {
/* Occasionally (frequently for some source remote mounted file systems) this can throw exceptions during
* `channel.close()` which is called automatically in the try-with-resources block. In this case, we have
* successfully read the data, and we can return it, and ignore the exception.
* */
if (readData == null)
throw new N5Exception.N5IOException(e);
}
return readData;
}
@Override
public void close() throws IOException {
if (lock != null) {
lock.close();
lock = null;
}
}
}
}
================================================
FILE: src/main/java/org/janelia/saalfeldlab/n5/GsonKeyValueN5Reader.java
================================================
package org.janelia.saalfeldlab.n5;
import java.io.InputStreamReader;
import java.io.UncheckedIOException;
import java.util.List;
import org.janelia.saalfeldlab.n5.N5Exception.N5IOException;
import org.janelia.saalfeldlab.n5.readdata.VolatileReadData;
import org.janelia.saalfeldlab.n5.shard.PositionValueAccess;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
/**
* {@link N5Reader} implementation through {@link KeyValueAccess} with JSON
* attributes parsed with {@link Gson}.
*
*/
public interface GsonKeyValueN5Reader extends GsonN5Reader {
KeyValueAccess getKeyValueAccess();
default boolean groupExists(final String normalPath) {
return getKeyValueAccess().isDirectory(absoluteGroupPath(normalPath));
}
@Override
default boolean exists(final String pathName) {
final String normalPath = N5URI.normalizeGroupPath(pathName);
return groupExists(normalPath) || datasetExists(normalPath);
}
@Override
default boolean datasetExists(final String pathName) throws N5Exception {
// for n5, every dataset must be a group
return getDatasetAttributes(pathName) != null;
}
/**
* Reads or creates the attributes map of a group or dataset.
*
* @param pathName
* group path
* @return the attribute
* @throws N5Exception if the attributes cannot be read
*/
@Override
default JsonElement getAttributes(final String pathName) throws N5Exception {
final String groupPath = N5URI.normalizeGroupPath(pathName);
final String attributesPath = absoluteAttributesPath(groupPath);
try (final VolatileReadData readData = getKeyValueAccess().createReadData(attributesPath);) {
if (readData == null) {
return null;
}
return GsonUtils.readAttributes(new InputStreamReader(readData.inputStream()), getGson());
} catch (final N5Exception.N5NoSuchKeyException e) {
return null;
} catch (final UncheckedIOException | N5IOException e) {
throw new N5IOException("Failed to read attributes from dataset " + pathName, e);
}
}
@Override
default <T> DataBlock<T> readChunk(
final String pathName,
final DatasetAttributes datasetAttributes,
final long... gridPosition) throws N5Exception {
DatasetAttributes convertedDatasetAttributes = getConvertedDatasetAttributes(datasetAttributes);
try {
final PositionValueAccess posKva = PositionValueAccess.fromKva(getKeyValueAccess(), getURI(), N5URI.normalizeGroupPath(pathName),
convertedDatasetAttributes);
return convertedDatasetAttributes.<T> getDatasetAccess().readChunk(posKva, gridPosition);
} catch (N5Exception.N5NoSuchKeyException e) {
return null;
}
}
@Override
default <T> List<DataBlock<T>> readChunks(
final String pathName,
final DatasetAttributes datasetAttributes,
final List<long[]> blockPositions) throws N5Exception {
DatasetAttributes convertedDatasetAttributes = getConvertedDatasetAttributes(datasetAttributes);
final PositionValueAccess posKva = PositionValueAccess.fromKva(getKeyValueAccess(), getURI(), N5URI.normalizeGroupPath(pathName), convertedDatasetAttributes);
return convertedDatasetAttributes.<T> getDatasetAccess().readChunks(posKva, blockPositions);
}
@Override
default <T> DataBlock<T> readBlock(
final String pathName,
final DatasetAttributes datasetAttributes,
final long... gridPosition) throws N5Exception {
final DatasetAttributes convertedDatasetAttributes = getConvertedDatasetAttributes(datasetAttributes);
final int shardLevel = convertedDatasetAttributes.getNestedBlockGrid().numLevels() - 1;
try {
final PositionValueAccess posKva = PositionValueAccess.fromKva(getKeyValueAccess(), getURI(), N5URI.normalizeGroupPath(pathName),
convertedDatasetAttributes);
return convertedDatasetAttributes.<T> getDatasetAccess().readBlock(posKva, gridPosition, shardLevel);
} catch (N5Exception.N5NoSuchKeyException e) {
return null;
}
}
@Override
default String[] list(final String pathName) throws N5Exception {
return getKeyValueAccess().listDirectories(absoluteGroupPath(pathName));
}
/**
* Constructs the absolute path (in terms of this store) for the group or
* dataset.
*
* @param normalGroupPath
* normalized group path without leading slash
* @return the absolute path to the group
*/
default String absoluteGroupPath(final String normalGroupPath) {
return getKeyValueAccess().compose(getURI(), normalGroupPath);
}
/**
* Constructs the absolute path (in terms of this store) for the attributes
* file of a group or dataset.
*
* @param normalPath
* normalized group path without leading slash
* @return the absolute path to the attributes
*/
default String absoluteAttributesPath(final String normalPath) {
return getKeyValueAccess().compose(getURI(), normalPath, getAttributesKey());
}
@Override
default boolean blockExists(
final String pathName,
final DatasetAttributes datasetAttributes,
final long... gridPosition) throws N5Exception {
final String normalPath = N5URI.normalizeGroupPath(pathName);
final String blockPath = getKeyValueAccess().compose(getURI(), normalPath,
datasetAttributes.relativeBlockPath(gridPosition));
return getKeyValueAccess().isFile(blockPath);
}
}
================================================
FILE: src/main/java/org/janelia/saalfeldlab/n5/GsonKeyValueN5Writer.java
================================================
package org.janelia.saalfeldlab.n5;
import java.io.OutputStreamWriter;
import java.io.UncheckedIOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import com.google.gson.JsonSyntaxException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import org.janelia.saalfeldlab.n5.N5Exception.N5IOException;
import org.janelia.saalfeldlab.n5.readdata.ReadData;
import org.janelia.saalfeldlab.n5.shard.PositionValueAccess;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
/**
* Default implementation of {@link N5Writer} with JSON attributes parsed with
* {@link Gson}.
*/
public interface GsonKeyValueN5Writer extends GsonN5Writer, GsonKeyValueN5Reader {
/**
* TODO This overrides the version even if incompatible, check
* if this is the desired behavior or if it is always overridden, e.g. as by
* the caching version. If this is true, delete this implementation.
*
* @param path to the group to write the version into
*/
default void setVersion(final String path) {
if (!VERSION.equals(getVersion()))
setAttribute("/", VERSION_KEY, VERSION.toString());
}
static String initializeContainer(
final KeyValueAccess keyValueAccess,
final String basePath) throws N5IOException {
final String normBasePath = keyValueAccess.normalize(basePath);
keyValueAccess.createDirectories(normBasePath);
return normBasePath;
}
@Override
default void createGroup(final String path) throws N5Exception {
final String normalPath = N5URI.normalizeGroupPath(path);
getKeyValueAccess().createDirectories(absoluteGroupPath(normalPath));
}
/**
* Helper method that writes an attributes tree into the store
* <p>
* TODO This method is not part of the public API and should be protected
* in Java versions greater than 8
*
* @param normalGroupPath
* to write the attributes to
* @param attributes
* to write
* @throws N5Exception
* if unable to write the attributes at {@code normalGroupPath}
*/
default void writeAttributes(
final String normalGroupPath,
final JsonElement attributes) throws N5Exception {
final ReadData newAttributesReadData = ReadData.from(os -> {
final OutputStreamWriter writer = new OutputStreamWriter(os, StandardCharsets.UTF_8);
GsonUtils.writeAttributes(writer, attributes, getGson());
});
try {
getKeyValueAccess().write(absoluteAttributesPath(normalGroupPath), newAttributesReadData);
} catch (UncheckedIOException | N5IOException e) {
throw new N5Exception.N5IOException("Failed to write attributes into " + normalGroupPath, e);
}
}
@Override
default void setAttributes(
final String path,
final JsonElement attributes) throws N5Exception {
final String normalPath = N5URI.normalizeGroupPath(path);
if (!exists(normalPath))
throw new N5IOException("" + normalPath + " is not a group or dataset.");
writeAttributes(normalPath, attributes);
}
/**
* Helper method that reads the existing map of attributes, JSON encodes,
* inserts and overrides the provided attributes, and writes them back into
* the attributes store.
*
* TODO This method is not part of the public API and should be protected
* in Java greater than 8
*
* @param normalGroupPath
* to write the attributes to
* @param attributes
* to write
* @throws N5Exception
* if unable to read or write the attributes at
* {@code normalGroupPath}
*/
default void writeAttributes(
final String normalGroupPath,
final Map<String, ?> attributes) throws N5Exception {
if (attributes != null && !attributes.isEmpty()) {
JsonElement root = getAttributes(normalGroupPath);
root = root != null && root.isJsonObject()
? root.getAsJsonObject()
: new JsonObject();
root = GsonUtils.insertAttributes(root, attributes, getGson());
writeAttributes(normalGroupPath, root);
}
}
@Override
default void setAttributes(
final String path,
final Map<String, ?> attributes) throws N5Exception {
final String normalPath = N5URI.normalizeGroupPath(path);
if (!exists(normalPath))
throw new N5IOException("" + normalPath + " is not a group or dataset.");
writeAttributes(normalPath, attributes);
}
@Override
default boolean removeAttribute(final String groupPath, final String attributePath) throws N5Exception {
final String normalPath = N5URI.normalizeGroupPath(groupPath);
final String absoluteNormalPath = getKeyValueAccess().compose(getURI(), normalPath);
final String normalKey = N5URI.normalizeAttributePath(attributePath);
if (!getKeyValueAccess().isDirectory(absoluteNormalPath))
return false;
if (attributePath.equals("/")) {
setAttributes(normalPath, JsonNull.INSTANCE);
return true;
}
final JsonElement attributes = getAttributes(normalPath);
if (GsonUtils.removeAttribute(attributes, normalKey) != null) {
setAttributes(normalPath, attributes);
return true;
}
return false;
}
@Override
default <T> T removeAttribute(final String pathName, final String key, final Class<T> cls) throws N5Exception {
final String normalPath = N5URI.normalizeGroupPath(pathName);
final String normalKey = N5URI.normalizeAttributePath(key);
final JsonElement attributes = getAttributes(normalPath);
final T obj;
try {
obj = GsonUtils.removeAttribute(attributes, normalKey, cls, getGson());
} catch (JsonSyntaxException | NumberFormatException | ClassCastException e) {
throw new N5Exception.N5ClassCastException(e);
}
if (obj != null) {
setAttributes(normalPath, attributes);
}
return obj;
}
@Override
default boolean removeAttributes(final String pathName, final List<String> attributes) throws N5Exception {
final String normalPath = N5URI.normalizeGroupPath(pathName);
boolean removed = false;
for (final String attribute : attributes) {
final String normalKey = N5URI.normalizeAttributePath(attribute);
removed |= removeAttribute(normalPath, normalKey);
}
return removed;
}
@Override
default <T> void writeRegion(
final String datasetPath,
final DatasetAttributes datasetAttributes,
final long[] min,
final long[] size,
final DataBlockSupplier<T> chunkSupplier,
final boolean writeFully) throws N5Exception {
DatasetAttributes convertedDatasetAttributes = getConvertedDatasetAttributes(datasetAttributes);
try {
final PositionValueAccess posKva = PositionValueAccess.fromKva(getKeyValueAccess(), getURI(), N5URI.normalizeGroupPath(datasetPath), convertedDatasetAttributes);
convertedDatasetAttributes.<T>getDatasetAccess().writeRegion(posKva, min, size, chunkSupplier, writeFully);
} catch (final UncheckedIOException e) {
throw new N5IOException(
"Failed to write blocks into dataset " + datasetPath, e);
}
}
@Override
default <T> void writeRegion(
final String datasetPath,
final DatasetAttributes datasetAttributes,
final long[] min,
final long[] size,
final DataBlockSupplier<T> chunkSupplier,
final boolean writeFully,
final ExecutorService exec) throws N5Exception, InterruptedException, ExecutionException {
DatasetAttributes convertedDatasetAttributes = getConvertedDatasetAttributes(datasetAttributes);
try {
final PositionValueAccess posKva = PositionValueAccess.fromKva(getKeyValueAccess(), getURI(), N5URI.normalizeGroupPath(datasetPath), convertedDatasetAttributes);
convertedDatasetAttributes.<T>getDatasetAccess().writeRegion(posKva, min, size, chunkSupplier, writeFully, exec);
} catch (final UncheckedIOException e) {
throw new N5IOException(
"Failed to write blocks into dataset " + datasetPath, e);
}
}
@Override
default <T> void writeChunks(
final String datasetPath,
final DatasetAttributes datasetAttributes,
final DataBlock<T>... chunks) throws N5Exception {
DatasetAttributes convertedDatasetAttributes = getConvertedDatasetAttributes(datasetAttributes);
try {
final PositionValueAccess posKva = PositionValueAccess.fromKva(getKeyValueAccess(), getURI(), N5URI.normalizeGroupPath(datasetPath), convertedDatasetAttributes);
convertedDatasetAttributes.<T>getDatasetAccess().writeChunks(posKva, Arrays.asList(chunks));
} catch (final UncheckedIOException e) {
throw new N5IOException(
"Failed to write chunks into dataset " + datasetPath, e);
}
}
@Override
default <T> void writeChunk(
final String path,
final DatasetAttributes datasetAttributes,
final DataBlock<T> chunk) throws N5Exception {
DatasetAttributes convertedDatasetAttributes = getConvertedDatasetAttributes(datasetAttributes);
try {
final PositionValueAccess posKva = PositionValueAccess.fromKva(getKeyValueAccess(), getURI(), N5URI.normalizeGroupPath(path), convertedDatasetAttributes);
convertedDatasetAttributes.<T> getDatasetAccess().writeChunk(posKva, chunk);
} catch (final UncheckedIOException e) {
throw new N5IOException(
"Failed to write chunk " + Arrays.toString(chunk.getGridPosition()) + " into dataset " + path,
e);
}
}
@Override
default <T> void writeBlock(
final String path,
final DatasetAttributes datasetAttributes,
final DataBlock<T> dataBlock) throws N5Exception {
final DatasetAttributes convertedDatasetAttributes = getConvertedDatasetAttributes(datasetAttributes);
final int shardLevel = convertedDatasetAttributes.getNestedBlockGrid().numLevels() - 1;
try {
final PositionValueAccess posKva = PositionValueAccess.fromKva(getKeyValueAccess(), getURI(), N5URI.normalizeGroupPath(path), convertedDatasetAttributes);
convertedDatasetAttributes.<T> getDatasetAccess().writeBlock(posKva, dataBlock, shardLevel);
} catch (final UncheckedIOException e) {
throw new N5IOException(
"Failed to write block " + Arrays.toString(dataBlock.getGridPosition()) + " into dataset " + path,
e);
}
}
@Override
default boolean remove(final String path) throws N5Exception {
final String normalPath = N5URI.normalizeGroupPath(path);
final String groupPath = absoluteGroupPath(normalPath);
if (getKeyValueAccess().isDirectory(groupPath))
getKeyValueAccess().delete(groupPath);
/* an IOException should have occurred if anything had failed midway */
return true;
}
@Override
default boolean deleteBlock(
final String path,
final DatasetAttributes datasetAttributes,
final long... gridPosition) throws N5Exception {
final PositionValueAccess posKva = PositionValueAccess.fromKva(getKeyValueAccess(), getURI(), N5URI.normalizeGroupPath(path), datasetAttributes);
return posKva.remove(gridPosition);
}
@Override
default boolean deleteChunk(
final String path,
final DatasetAttributes datasetAttributes,
final long... gridPosition) throws N5Exception {
final PositionValueAccess posKva = PositionValueAccess.fromKva(getKeyValueAccess(), getURI(), N5URI.normalizeGroupPath(path), datasetAttributes);
return datasetAttributes.getDatasetAccess().deleteChunk(posKva, gridPosition);
}
@Override
default boolean deleteChunks(
final String path,
final DatasetAttributes datasetAttributes,
final List<long[]> gridPositions) throws N5Exception {
final PositionValueAccess posKva = PositionValueAccess.fromKva(getKeyValueAccess(), getURI(), N5URI.normalizeGroupPath(path), datasetAttributes);
return datasetAttributes.getDatasetAccess().deleteChunks(posKva, gridPositions);
}
}
================================================
FILE: src/main/java/org/janelia/saalfeldlab/n5/GsonN5Reader.java
================================================
package org.janelia.saalfeldlab.n5;
import java.lang.reflect.Type;
import java.util.Map;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonParseException;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonSyntaxException;
/**
* {@link N5Reader} with JSON attributes parsed with {@link Gson}.
*
*/
public interface GsonN5Reader extends N5Reader {
Gson getGson();
/**
* Get the key for the {@link KeyValueAccess}, that is used for storing attributes.
* The N5 format uses "attributes.json".
*
* @return the attributes key
*/
String getAttributesKey();
@Override
default Map<String, Class<?>> listAttributes(final String pathName) throws N5Exception {
return GsonUtils.listAttributes(getAttributes(pathName));
}
@Override
default DatasetAttributes getDatasetAttributes(final String pathName) throws N5Exception {
final String normalPath = N5URI.normalizeGroupPath(pathName);
final JsonElement attributes = getAttributes(normalPath);
return createDatasetAttributes(attributes);
}
default DatasetAttributes createDatasetAttributes(final JsonElement attributes) {
final JsonDeserializationContext context = new JsonDeserializationContext() {
@Override public <T> T deserialize(JsonElement json, Type typeOfT) throws JsonParseException {
return getGson().fromJson(json, typeOfT);
}
};
return DatasetAttributes.getJsonAdapter().deserialize(attributes, DatasetAttributes.class, context);
}
@Override
default <T> T getAttribute(final String pathName, final String key, final Class<T> clazz) throws N5Exception {
final String normalPathName = N5URI.normalizeGroupPath(pathName);
final String normalizedAttributePath = N5URI.normalizeAttributePath(key);
final JsonElement attributes = getAttributes(normalPathName);
try {
return GsonUtils.readAttribute(attributes, normalizedAttributePath, clazz, getGson());
} catch (JsonSyntaxException | NumberFormatException | ClassCastException e) {
throw new N5Exception.N5ClassCastException(e);
}
}
@Override
default <T> T getAttribute(final String pathName, final String key, final Type type) throws N5Exception {
final String normalPathName = N5URI.normalizeGroupPath(pathName);
final String normalizedAttributePath = N5URI.normalizeAttributePath(key);
final JsonElement attributes = getAttributes(normalPathName);
try {
return GsonUtils.readAttribute(attributes, normalizedAttributePath, type, getGson());
} catch (JsonSyntaxException | NumberFormatException | ClassCastException e) {
throw new N5Exception.N5ClassCastException(e);
}
}
/**
* Reads or the attributes of a group or dataset.
*
* @param pathName
* group path
* @return the attributes identified by pathName
* @throws N5Exception if the attribute cannot be returned
*/
JsonElement getAttributes(final String pathName) throws N5Exception;
}
================================================
FILE: src/main/java/org/janelia/saalfeldlab/n5/GsonN5Writer.java
================================================
package org.janelia.saalfeldlab.n5;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
/**
* {@link N5Writer} with JSON attributes parsed with {@link Gson}.
*
*/
public interface GsonN5Writer extends GsonN5Reader, N5Writer {
/**
* Set the attributes of a group. This result of this method is equivalent
* with {@link N5Writer#setAttribute(String, String, Object) N5Writer#setAttribute(groupPath, "/", attributes)}.
*
* @param groupPath
* to write the attributes to
* @param attributes
* to write
* @throws N5Exception if the attributes cannot be set
*/
void setAttributes(
final String groupPath,
final JsonElement attributes) throws N5Exception;
}
================================================
FILE: src/main/java/org/janelia/saalfeldlab/n5/GsonUtils.java
================================================
package org.janelia.saalfeldlab.n5;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.lang.reflect.Array;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;
import org.janelia.saalfeldlab.n5.N5Exception.N5JsonParseException;
/**
* Utility class for working with JSON.
*
* @author Stephan Saalfeld
*/
public interface GsonUtils {
/**
* Reads the attributes json from a given {@link Reader}.
*
* @param reader
* the reader
* @param gson
* to parse Json from the {@code reader}
* @return the root {@link JsonObject} of the attributes
*/
static JsonElement readAttributes(final Reader reader, final Gson gson) {
return gson.fromJson(reader, JsonElement.class);
}
static <T> T readAttribute(
final JsonElement root,
final String normalizedAttributePath,
final Class<T> cls,
final Gson gson) throws JsonSyntaxException, NumberFormatException, ClassCastException {
return readAttribute(root, normalizedAttributePath, TypeToken.get(cls).getType(), gson);
}
static <T> T readAttribute(
final JsonElement root,
final String normalizedAttributePath,
final Type type,
final Gson gson) throws JsonSyntaxException, NumberFormatException, ClassCastException {
final JsonElement attribute = getAttribute(root, normalizedAttributePath);
return parseAttributeElement(attribute, gson, type);
}
/**
* Deserialize the {@code attribute} as {@link Type type} {@code T}.
*
* @param attribute
* to deserialize as {@link Type type}
* @param gson
* used to deserialize {@code attribute}
* @param type
* to deserialize {@code attribute} as
* @param <T>
* return type represented by {@link Type type}
* @return the deserialized attribute object, or {@code null} if
* {@code attribute} cannot deserialize to {@code T}
*/
@SuppressWarnings("unchecked")
static <T> T parseAttributeElement(final JsonElement attribute, final Gson gson, final Type type) throws JsonSyntaxException, NumberFormatException, ClassCastException {
if (attribute == null)
return null;
final Class<?> clazz = (type instanceof Class<?>) ? ((Class<?>)type) : null;
if (clazz != null && clazz.isAssignableFrom(HashMap.class)) {
final Type mapType = new TypeToken<Map<String, Object>>() {
}.getType();
final Map<String, Object> retMap = gson.fromJson(attribute, mapType);
// noinspection unchecked
return (T)retMap;
}
if (attribute instanceof JsonArray) {
final JsonArray array = attribute.getAsJsonArray();
try {
final T retArray = GsonUtils.getJsonAsArray(gson, array, type);
if (retArray != null)
return retArray;
} catch (final JsonSyntaxException e) {
if (type == String.class)
//noinspection unchecked
return (T)gson.toJson(attribute);
}
}
try {
final T parsedResult = gson.fromJson(attribute, type);
if (parsedResult == null)
throw new ClassCastException("Cannot parse json as type " + type.getTypeName());
return parsedResult;
} catch (final JsonSyntaxException e) {
if (type == String.class)
//noinspection unchecked
return (T)gson.toJson(attribute);
throw e;
}
}
/**
* Return the attribute at {@code normalizedAttributePath} as a
* {@link JsonElement}. Does not attempt to parse the attribute.
* to search for the {@link JsonElement} at location
* {@code normalizedAttributePath}
*
* @param root
* containing an attribute at normalizedAttributePath
* @param normalizedAttributePath
* to the attribute
* @return the attribute as a {@link JsonElement}.
*/
static JsonElement getAttribute(JsonElement root, final String normalizedAttributePath) {
final String[] pathParts = normalizedAttributePath.split("(?<!\\\\)/");
for (int i = 0; i < pathParts.length; i++) {
final String pathPart = pathParts[i];
if (pathPart.isEmpty())
continue;
final String pathPartWithoutEscapeCharacters = pathPart
.replaceAll("\\\\/", "/")
.replaceAll("\\\\\\[", "[");
if (root instanceof JsonObject && root.getAsJsonObject().get(pathPartWithoutEscapeCharacters) != null) {
final JsonObject jsonObject = root.getAsJsonObject();
root = jsonObject.get(pathPartWithoutEscapeCharacters);
} else {
final Matcher matcher = N5URI.ARRAY_INDEX.matcher(pathPart);
if (root != null && root.isJsonArray() && matcher.matches()) {
final int index = Integer.parseInt(matcher.group().replace("[", "").replace("]", ""));
final JsonArray jsonArray = root.getAsJsonArray();
if (index >= jsonArray.size()) {
return null;
}
root = jsonArray.get(index);
} else {
return null;
}
}
}
return root;
}
/**
* Best effort implementation of {@link N5Reader#listAttributes(String)}
* with limited type resolution. Possible return types are
* <ul>
* <li>null</li>
* <li>boolean</li>
* <li>double</li>
* <li>String</li>
* <li>Object</li>
* <li>boolean[]</li>
* <li>double[]</li>
* <li>String[]</li>
* <li>Object[]</li>
* </ul>
*
* @param root
* the json element
* @return the attribute map
*/
static Map<String, Class<?>> listAttributes(final JsonElement root) throws N5JsonParseException {
if (root == null) {
return new HashMap<>();
}
if (!root.isJsonObject()) {
throw new N5JsonParseException("JsonElement found, but was not JsonObject");
}
final HashMap<String, Class<?>> attributes = new HashMap<>();
root.getAsJsonObject().entrySet().forEach(entry -> {
final Class<?> clazz;
final String key = entry.getKey();
final JsonElement jsonElement = entry.getValue();
if (jsonElement.isJsonNull())
clazz = null;
else if (jsonElement.isJsonPrimitive())
clazz = classForJsonPrimitive((JsonPrimitive)jsonElement);
else if (jsonElement.isJsonArray()) {
final JsonArray jsonArray = (JsonArray)jsonElement;
Class<?> arrayElementClass = Object.class;
if (jsonArray.size() > 0) {
final JsonElement firstElement = jsonArray.get(0);
if (firstElement.isJsonPrimitive()) {
arrayElementClass = classForJsonPrimitive(firstElement.getAsJsonPrimitive());
for (int i = 1; i < jsonArray.size() && arrayElementClass != Object.class; ++i) {
final JsonElement element = jsonArray.get(i);
if (element.isJsonPrimitive()) {
final Class<?> nextArrayElementClass = classForJsonPrimitive(
element.getAsJsonPrimitive());
if (nextArrayElementClass != arrayElementClass)
if (nextArrayElementClass == double.class && arrayElementClass == long.class)
arrayElementClass = double.class;
else {
arrayElementClass = Object.class;
break;
}
} else {
arrayElementClass = Object.class;
break;
}
}
}
clazz = Array.newInstance(arrayElementClass, 0).getClass();
} else
clazz = Object[].class;
} else
clazz = Object.class;
attributes.put(key, clazz);
});
return attributes;
}
static <T> T getJsonAsArray(final Gson gson, final JsonArray array, final Class<T> cls) {
return getJsonAsArray(gson, array, TypeToken.get(cls).getType());
}
@SuppressWarnings("unchecked")
static <T> T getJsonAsArray(final Gson gson, final JsonArray array, final Type type) {
final Class<?> clazz = (type instanceof Class<?>) ? ((Class<?>)type) : null;
if (type == boolean[].class) {
final boolean[] retArray = new boolean[array.size()];
for (int i = 0; i < array.size(); i++) {
final Boolean value = gson.fromJson(array.get(i), boolean.class);
retArray[i] = value;
}
return (T)retArray;
} else if (type == double[].class) {
final double[] retArray = new double[array.size()];
for (int i = 0; i < array.size(); i++) {
final double value = gson.fromJson(array.get(i), double.class);
retArray[i] = value;
}
return (T)retArray;
} else if (type == float[].class) {
final float[] retArray = new float[array.size()];
for (int i = 0; i < array.size(); i++) {
final float value = gson.fromJson(array.get(i), float.class);
retArray[i] = value;
}
return (T)retArray;
} else if (type == long[].class) {
final long[] retArray = new long[array.size()];
for (int i = 0; i < array.size(); i++) {
final long value = gson.fromJson(array.get(i), long.class);
retArray[i] = value;
}
return (T)retArray;
} else if (type == short[].class) {
final short[] retArray = new short[array.size()];
for (int i = 0; i < array.size(); i++) {
final short value = gson.fromJson(array.get(i), short.class);
retArray[i] = value;
}
return (T)retArray;
} else if (type == int[].class) {
final int[] retArray = new int[array.size()];
for (int i = 0; i < array.size(); i++) {
final int value = gson.fromJson(array.get(i), int.class);
retArray[i] = value;
}
return (T)retArray;
} else if (type == byte[].class) {
final byte[] retArray = new byte[array.size()];
for (int i = 0; i < array.size(); i++) {
final byte value = gson.fromJson(array.get(i), byte.class);
retArray[i] = value;
}
return (T)retArray;
} else if (type == char[].class) {
final char[] retArray = new char[array.size()];
for (int i = 0; i < array.size(); i++) {
final char value = gson.fromJson(array.get(i), char.class);
retArray[i] = value;
}
return (T)retArray;
} else if (clazz != null && clazz.isArray()) {
final Class<?> componentCls = clazz.getComponentType();
final Object[] clsArray = (Object[])Array.newInstance(componentCls, array.size());
for (int i = 0; i < array.size(); i++) {
clsArray[i] = gson.fromJson(array.get(i), componentCls);
}
// noinspection unchecked
return (T)clsArray;
}
return null;
}
/**
* Return a reasonable class for a {@link JsonPrimitive}. Possible return
* types are
* <ul>
* <li>boolean</li>
* <li>double</li>
* <li>String</li>
* <li>Object</li>
* </ul>
*
* @param jsonPrimitive
* the json primitive
* @return the class
*/
static Class<?> classForJsonPrimitive(final JsonPrimitive jsonPrimitive) {
if (jsonPrimitive.isBoolean())
return boolean.class;
else if (jsonPrimitive.isNumber()) {
final Number number = jsonPrimitive.getAsNumber();
if (number.longValue() == number.doubleValue())
return long.class;
else
return double.class;
} else if (jsonPrimitive.isString())
return String.class;
else
return Object.class;
}
/**
* If there is an attribute in {@code root} such that it can be parsed and
* deserialized as {@code T},
* then remove it from {@code root}, write {@code root} to the
* {@code writer}, and return the removed attribute.
* <p>
* If there is an attribute at the location specified by
* {@code normalizedAttributePath} but it cannot be deserialized to
* {@code T}, then it is not removed.
* <p>
* If nothing is removed, then {@code root} is not written to the
* {@code writer}.
* to write the modified {@code root} to after removal of the attribute to
* remove the attribute from
*
*
* @param <T> the type of the attribute to be removed
* @param writer to write the modified JsonElement, which no longer contains the removed attribute
* @param root element to remove the attribute from
* @param normalizedAttributePath
* to the attribute location of the attribute to remove to
* deserialize the attribute with of the removed attribute
* @param cls of the type of the attribute to be removed
* @param gson used to deserialize the JsonElement as {@code T}
* @return the removed attribute, or null if nothing removed
* @throws IOException
* if unable to write to the {@code writer}
*/
static <T> T removeAttribute(
final Writer writer,
final JsonElement root,
final String normalizedAttributePath,
final Class<T> cls,
final Gson gson) throws JsonSyntaxException, NumberFormatException, ClassCastException, IOException {
final T removed = removeAttribute(root, normalizedAttributePath, cls, gson);
if (removed != null) {
writeAttributes(writer, root, gson);
}
return removed;
}
/**
* If there is an attribute in {@code root} at location
* {@code normalizedAttributePath} then remove it from {@code root}..
* to write the modified {@code root} to after removal of the attribute to
* remove the attribute from
*
* @param writer to write the modified JsonElement, which no longer contains the removed attribute
* @param root to remove the attribute from
* @param normalizedAttributePath
* to the attribute location to deserialize the attribute with
* @param gson to write the attribute to the {@code writer}
* @return if the attribute was removed or not
* @throws IOException if an error occurs while writing to the {@code writer}
*/
static boolean removeAttribute(
final Writer writer,
final JsonElement root,
final String normalizedAttributePath,
final Gson gson) throws JsonSyntaxException, NumberFormatException, ClassCastException, IOException {
final JsonElement removed = removeAttribute(root, normalizedAttributePath, JsonElement.class, gson);
if (removed != null) {
writeAttributes(writer, root, gson);
return true;
}
return false;
}
/**
* If there is an attribute in {@code root} such that it can be parsed and
* desrialized as {@code T},
* then remove it from {@code root} and return the removed attribute.
* <p>
* If there is an attribute at the location specified by
* {@code normalizedAttributePath} but it cannot be deserialized to
* {@code T}, then it is not removed.
* to remove the attribute from
*
* @param <T> the type of the attribute to be removed
* @param root element to remove the attribute from
* @param normalizedAttributePath
* to the attribute location of the attribute to remove to
* deserialize the attribute with of the removed attribute
* @param cls of the type of the attribute to be removed
* @param gson used to deserialize the JsonElement as {@code T}
* @return the removed attribute, or null if nothing removed
* @throws JsonSyntaxException if the attribute is not valid json
* @throws NumberFormatException if {@code T} is a {@link Number} but the attribute cannot be parsed as {@code T}
* @throws ClassCastException if an attribute exists at this path, but is not of type {@code T}
*/
static <T> T removeAttribute(
final JsonElement root,
final String normalizedAttributePath,
final Class<T> cls,
final Gson gson) throws JsonSyntaxException, NumberFormatException, ClassCastException {
final T attribute = GsonUtils.readAttribute(root, normalizedAttributePath, cls, gson);
if (attribute != null) {
removeAttribute(root, normalizedAttributePath);
}
return attribute;
}
/**
* Remove and return the attribute at {@code normalizedAttributePath} as a
* {@link JsonElement}. Does not attempt to parse the attribute. to search
* for the {@link JsonElement} at location {@code normalizedAttributePath}
*
* @param root
* the root JsonElement
* @param normalizedAttributePath
* to the attribute
* @return the attribute as a {@link JsonElement}.
*/
static JsonElement removeAttribute(JsonElement root, final String normalizedAttributePath) {
final String[] pathParts = normalizedAttributePath.split("(?<!\\\\)/");
for (int i = 0; i < pathParts.length; i++) {
final String pathPart = pathParts[i];
if (pathPart.isEmpty())
continue;
final String pathPartWithoutEscapeCharacters = pathPart
.replaceAll("\\\\/", "/")
.replaceAll("\\\\\\[", "[");
if (root instanceof JsonObject && root.getAsJsonObject().get(pathPartWithoutEscapeCharacters) != null) {
final JsonObject jsonObject = root.getAsJsonObject();
root = jsonObject.get(pathPartWithoutEscapeCharacters);
if (i == pathParts.length - 1) {
jsonObject.remove(pathPartWithoutEscapeCharacters);
}
} else {
final Matcher matcher = N5URI.ARRAY_INDEX.matcher(pathPart);
if (root != null && root.isJsonArray() && matcher.matches()) {
final int index = Integer.parseInt(matcher.group().replace("[", "").replace("]", ""));
final JsonArray jsonArray = root.getAsJsonArray();
if (index >= jsonArray.size()) {
return null;
}
root = jsonArray.get(index);
if (i == pathParts.length - 1) {
jsonArray.remove(index);
}
} else {
return null;
}
}
}
return root;
}
/**
* Inserts {@code attribute} into {@code root} at location
* {@code normalizedAttributePath} and write the resulting {@code root}.
* <p>
* If {@code root} is not a {@link JsonObject}, then it is overwritten with
* an object containing {@code "normalizedAttributePath": attribute }
*
* @param writer
* the writer
* @param root
* the root json element
* @param normalizedAttributePath
* the attribute path
* @param attribute
* the attribute
* @param gson
* the gson
* @param <T>
* the attribute type
* @throws IOException
* the exception
*/
static <T> void writeAttribute(
final Writer writer,
JsonElement root,
final String normalizedAttributePath,
final T attribute,
final Gson gson) throws IOException {
root = insertAttribute(root, normalizedAttributePath, attribute, gson);
writeAttributes(writer, root, gson);
}
/**
* Writes the attributes JsonElement to a given {@link Writer}.
* This will overwrite any existing attributes.
*
* @param writer
* the writer
* @param root
* the root json element
* @param gson
* the gson
* @param <T>
* the attribute type
* @throws IOException
* the exception
*/
static <T> void writeAttributes(
final Writer writer,
final JsonElement root,
final Gson gson) throws IOException {
gson.toJson(root, writer);
writer.flush();
}
static JsonElement insertAttributes(JsonElement root, final Map<String, ?> attributes, final Gson gson) {
for (final Map.Entry<String, ?> attribute : attributes.entrySet()) {
root = insertAttribute(root, N5URI.normalizeAttributePath(attribute.getKey()), attribute.getValue(), gson);
}
return root;
}
static <T> JsonElement insertAttribute(
JsonElement root,
final String normalizedAttributePath,
final T attribute,
final Gson gson) {
LinkedAttributePathToken<?> pathToken = N5URI.getAttributePathTokens(normalizedAttributePath);
/* No path to traverse or build; just return the value */
if (pathToken == null)
return gson.toJsonTree(attribute);
JsonElement json = root;
while (pathToken != null) {
final JsonElement parent = pathToken.setAndCreateParentElement(json);
/*
* We may need to create or override the existing root if it is
* non-existent or incompatible.
*/
final boolean rootOverriden = json == root && parent != json;
if (root == null || rootOverriden) {
root = parent;
}
json = pathToken.writeChild(gson, attribute);
pathToken = pathToken.next();
}
return root;
}
}
================================================
FILE: src/main/java/org/janelia/saalfeldlab/n5/GzipCompression.java
================================================
package org.janelia.saalfeldlab.n5;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.InflaterInputStream;
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
import org.apache.commons.compress.compressors.gzip.GzipParameters;
import org.janelia.saalfeldlab.n5.Compression.CompressionType;
import org.janelia.saalfeldlab.n5.N5Exception.N5IOException;
import org.janelia.saalfeldlab.n5.readdata.ReadData;
import org.janelia.saalfeldlab.n5.serialization.NameConfig;
@CompressionType("gzip")
@NameConfig.Name("gzip")
public class GzipCompression implements Compression {
private static final long serialVersionUID = 8630847239813334263L;
/**
* Explicit equivalent of {@link java.util.zip.Deflater#DEFAULT_COMPRESSION}: zlib defines
* level 6 as "a default compromise between speed and compression." An explicit value is used
* instead of {@code DEFAULT_COMPRESSION} (-1) because -1 is not a valid level for Zarr codecs.
*
* @see <a href="https://www.zlib.net/manual.html">zlib Manual</a>
*/
private static final int N5_DEFAULT_GZIP_LEVEL = 6;
@CompressionParameter
@NameConfig.Parameter
private final int level;
/**
* This is not a NameConfig.Parameter because this parameter must not be
* serialized for zarr
*/
@CompressionParameter
private final boolean useZlib;
private final transient GzipParameters parameters = new GzipParameters();
public GzipCompression() {
this(N5_DEFAULT_GZIP_LEVEL);
}
public GzipCompression(final int level) {
this(level, false);
}
public GzipCompression(final int level, final boolean useZlib) {
this.level = level;
this.useZlib = useZlib;
}
@Override
public boolean equals(final Object other) {
if (other == null || other.getClass() != GzipCompression.class)
return false;
else {
final GzipCompression gz = ((GzipCompression)other);
return useZlib == gz.useZlib && level == gz.level;
}
}
private InputStream decode(final InputStream in) throws IOException {
if (useZlib) {
return new InflaterInputStream(in);
} else {
return GzipCompressorInputStream.builder()
.setInputStream(in)
.setDecompressConcatenated(true)
.get();
}
}
@Override
public ReadData decode(final ReadData readData) throws N5IOException {
try {
return ReadData.from(decode(readData.inputStream()));
} catch (IOException e) {
throw new N5IOException(e);
}
}
@Override
public ReadData encode(final ReadData readData) {
if (useZlib) {
return readData.encode(out -> new DeflaterOutputStream(out, new Deflater(level)));
} else {
return readData.encode(out -> {
parameters.setCompressionLevel(level);
return new GzipCompressorOutputStream(out, parameters);
});
}
}
}
================================================
FILE: src/main/java/org/janelia/saalfeldlab/n5/HttpKeyValueAccess.java
================================================
package org.janelia.saalfeldlab.n5;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.function.TriFunction;
import org.janelia.saalfeldlab.n5.N5Exception.N5IOException;
import org.janelia.saalfeldlab.n5.http.ListResponseParser;
import org.janelia.saalfeldlab.n5.readdata.ReadData;
import java.io.Closeable;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.channels.NonWritableChannelException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import org.janelia.saalfeldlab.n5.readdata.LazyRead;
import org.janelia.saalfeldlab.n5.readdata.VolatileReadData;
/**
* A read-only {@link KeyValueAccess} implementation using HTTP. As a result, calling <code>lockForWriting</code>, <code>createDirectories</code>, or <code>delete</code> will throw an {@link N5Exception}.
* <p>
* The behavior of <code>list</code>, <code>listDirectories</code>, and <code>isDirectory</code> will depend on the server configuration. See the documentation of those methods for details.
* <p>
* Methods that take a "normalPath" as an argument expect absolute URIs.
*/
public class HttpKeyValueAccess implements KeyValueAccess {
public static final String HEAD = "HEAD";
public static final String GET = "GET";
public static final String RANGE = "Range";
public static final String ACCEPT_RANGE = "Accept-Range";
public static final String BYTES = "bytes";
private int readTimeoutMilliseconds;
private int connectionTimeoutMilliseconds;
private ListResponseParser listResponseParser = ListResponseParser.defaultListParser();
private ListResponseParser listDirectoryResponseParser = ListResponseParser.defaultDirectoryListParser();
/**
* Opens an {@link HttpKeyValueAccess}
*
* @throws N5IOException if the access could not be created
*/
public HttpKeyValueAccess() {
readTimeoutMilliseconds = 5000;
connectionTimeoutMilliseconds = 5000;
}
public void setReadTimeout(int readTimeoutMilliseconds) {
this.readTimeoutMilliseconds = readTimeoutMilliseconds;
}
public void setConnectionTimeout(int connectionTimeoutMilliseconds) {
this.connectionTimeoutMilliseconds = connectionTimeoutMilliseconds;
}
public void setListParser(final ListResponseParser parser) {
listResponseParser = parser;
}
public void setListDirectoryParser(final ListResponseParser parser) {
listDirectoryResponseParser = parser;
}
@Override
public String normalize(final String path) {
return N5URI.normalizeGroupPath(path);
}
@Override
public URI uri(final String normalPath) throws URISyntaxException {
return new URI(normalPath);
}
/**
* Test whether the {@code normalPath} exists.
* <p>
* Removes leading slash from {@code normalPath}, and then checks whether
* either {@code path} or {@code path + "/"} is a key.
*
* @param normalPath is expected to be in normalized form, no further efforts are
* made to normalize it.
* @return {@code true} if {@code path} exists, {@code false} otherwise
*/
@Override
public boolean exists(final String normalPath) {
try {
requireValidHttpResponse(normalPath, "HEAD", "Error checking existence: " + normalPath, true);
return true;
} catch (N5Exception.N5NoSuchKeyException e) {
return false;
}
}
@Override public long size(String normalPath) {
final HttpURLConnection head = requireValidHttpResponse(normalPath, "HEAD", "Error checking existence: " + normalPath, true);
return head.getContentLengthLong();
}
/**
* Test whether the path is a directory.
* <p>
* Appends trailing "/" to {@code normalPath} if there is none, removes
* leading "/", and then checks whether resulting {@code path} is a key.
*
* @param normalPath is expected to be in normalized form, no further efforts are
* made to normalize it.
* @return {@code true} if {@code path} (with trailing "/") exists as a key,
* {@code false} otherwise
*/
@Override
public boolean isDirectory(final String normalPath) {
try {
requireValidHttpResponse(getDirectoryPath(normalPath), HEAD, false, (code, msg,http) -> {
final N5Exception cause = validExistsResponse(code, "Error checking directory: " + normalPath, msg, true);
if (code >= 300 && code < 400) {
final String redirectLocation = http.getHeaderField("Location");
if (!(redirectLocation.endsWith("/") || redirectLocation.endsWith("index.html")))
return new N5Exception.N5NoSuchKeyException("Found File at " + normalPath + " but was not directory");
return null;
}
return cause;
});
return true;
} catch (N5Exception e) {
return false;
}
}
private static String getDirectoryPath(String normalPath) {
final String directoryNormalPath;
if (normalPath.endsWith("/"))
directoryNormalPath = normalPath;
else
directoryNormalPath = normalPath + "/";
return directoryNormalPath;
}
/**
* Test whether the path is a file.
* <p>
* Checks whether {@code normalPath} has no trailing "/", then removes
* leading "/" and checks whether the resulting {@code path} is a key.
*
* @param normalPath is expected to be in normalized form, no further efforts are
* made to normalize it.
* @return {@code true} if {@code path} exists as a key and has no trailing
* slash, {@code false} otherwise
*/
@Override
public boolean isFile(final String normalPath) {
/* Files must not end in `/` And Don't accept a redirect to a location ending in `/` */
try {
requireValidHttpResponse(getFilePath(normalPath), HEAD, false, (code, msg, http) -> {
final N5Exception cause = validExistsResponse(code, "Error accessing file: " + normalPath, msg, true);
if (code >= 300 && code < 400) {
final String redirectLocation = http.getHeaderField("Location");
if (redirectLocation.endsWith("/") || redirectLocation.endsWith("index.html"))
return new N5Exception.N5NoSuchKeyException("Found key at " + normalPath + " but was directory");
}
return cause;
});
return true;
} catch (N5Exception e) {
return false;
}
}
private static String getFilePath(String normalPath) {
final String fileNormalPath = normalPath.replaceAll("/+$", "");
return fileNormalPath;
}
private HttpURLConnection httpRequest(String normalPath, String method) throws IOException {
final URL url = URI.create(normalPath).toURL();
final HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setReadTimeout(readTimeoutMilliseconds);
connection.setConnectTimeout(connectionTimeoutMilliseconds);
connection.setRequestMethod(method);
return connection;
}
@Override
public VolatileReadData createReadData(final String normalPath) {
return VolatileReadData.from(new HttpLazyRead(normalPath));
}
public LockedChannel lockForReading(final String normalPath) throws N5IOException {
//TODO Caleb: Maybe check exists lazily when attempting to read
try {
if (!exists(normalPath))
throw new N5Exception.N5NoSuchKeyException("Key does not exist: " + normalPath);
return new HttpObjectChannel(uri(normalPath), 0, -1);
} catch (URISyntaxException e) {
throw new N5Exception("Invalid URI Syntax", e);
}
}
@Override
public LockedChannel lockForWriting(final String normalPath) throws N5IOException {
throw new N5Exception("HttpKeyValueAccess is read-only");
}
@Override
public void write(final String normalPath, final ReadData data) throws N5IOException {
throw new N5Exception("HttpKeyValueAccess is read-only");
}
/**
* List all 'directory'-like children of a path.
* <p>
* Will throw an N5IOException both if a connection to the server can not be established, or the server does not allow listing.
*
* @param normalPath
* is expected to be in normalized form, no further
* efforts are made to normalize it.
* @return the directories
* @throws N5IOException
* if an error occurs during listing
*/
@Override
public String[] listDirectories(final String normalPath) throws N5IOException {
return queryListEntries(normalPath, listDirectoryResponseParser, true);
}
/**
* List all children of a path.
* <p>
* Will throw an N5IOException both if a connection to the server can not be
* established, or the server does not allow listing.
*
* @param normalPath
* is expected to be in normalized form, no further efforts are
* made to normalize it.
* @return the the child paths
* @throws N5IOException
* if an error occurs during listing
*/
@Override
public String[] list(final String normalPath) throws N5IOException {
return queryListEntries(normalPath, listResponseParser, true);
}
private String[] queryListEntries(String normalPath, ListResponseParser parser, boolean allowRedirect) throws N5IOException{
final HttpURLConnection http = requireValidHttpResponse(normalPath, GET, "Error listing directory at " + normalPath, allowRedirect);
try {
final String listResponse = responseToString(http.getInputStream());
return parser.parseListResponse(listResponse);
} catch (IOException e) {
throw new N5IOException("Error listing directory at " + normalPath, e);
}
}
private static N5Exception validExistsResponse(int code, String responseMsg, String message, boolean allowRedirect) {
if (code >= 200 && code < (allowRedirect ? 400 : 300)) return null;
final RuntimeException cause = new RuntimeException(message + "( "+ responseMsg + ")(" + code + ")");
if (code == 404 | code == 410)
return new N5Exception.N5NoSuchKeyException(message, cause);
return new N5Exception(message, cause);
}
private HttpURLConnection requireValidHttpResponse(String uri, String method, String message, boolean allowRedirect) throws N5Exception {
return requireValidHttpResponse(uri, method, (code, msg, http) -> validExistsResponse(code, msg, message, allowRedirect));
}
private HttpURLConnection requireValidHttpResponse(String uri, String method, TriFunction<Integer, String, HttpURLConnection, N5Exception> filterCode) throws N5Exception {
return requireValidHttpResponse(uri, method, true, filterCode);
}
private HttpURLConnection requireValidHttpResponse(String uri, String method, boolean followRedirects, TriFunction<Integer, String, HttpURLConnection, N5Exception> filterCode) throws N5Exception {
final int code;
final HttpURLConnection http;
final String responseMsg;
try {
http = httpRequest(uri, method);
http.setInstanceFollowRedirects(followRedirects);
code = http.getResponseCode();
responseMsg = http.getResponseMessage();
} catch (IOException e) {
throw new N5IOException("Could not validate HTTP Response", e);
}
final N5Exception cause = filterCode.apply(code, responseMsg, http);
if (cause != null) throw cause;
return http;
}
private String responseToString(InputStream inputStream) throws IOException {
return IOUtils.toString(inputStream, StandardCharsets.UTF_8.name());
}
@Override
public void createDirectories(final String normalPath) {
throw new N5Exception("HttpKeyValueAccess is read-only");
}
@Override
public void delete(final String norma
gitextract_yquuu4ly/
├── .github/
│ ├── build.sh
│ ├── setup.sh
│ └── workflows/
│ └── build.yml
├── .gitignore
├── LICENSE.md
├── README.md
├── doc/
│ ├── LICENSE.md
│ ├── README.md
│ └── n5-eclipse-style.xml
├── pom.xml
├── scripts/
│ ├── fsLockValidation
│ └── writeLockTest.sh
└── src/
├── main/
│ └── java/
│ └── org/
│ └── janelia/
│ └── saalfeldlab/
│ └── n5/
│ ├── AbstractDataBlock.java
│ ├── BufferedKvaLockedChannel.java
│ ├── ByteArrayDataBlock.java
│ ├── Bzip2Compression.java
│ ├── CachedGsonKeyValueN5Reader.java
│ ├── CachedGsonKeyValueN5Writer.java
│ ├── ChannelLock.java
│ ├── Compression.java
│ ├── CompressionAdapter.java
│ ├── DataBlock.java
│ ├── DataType.java
│ ├── DatasetAttributes.java
│ ├── DoubleArrayDataBlock.java
│ ├── FileKeyLockManager.java
│ ├── FileSystemKeyValueAccess.java
│ ├── FloatArrayDataBlock.java
│ ├── FsIoPolicy.java
│ ├── GsonKeyValueN5Reader.java
│ ├── GsonKeyValueN5Writer.java
│ ├── GsonN5Reader.java
│ ├── GsonN5Writer.java
│ ├── GsonUtils.java
│ ├── GzipCompression.java
│ ├── HttpKeyValueAccess.java
│ ├── IntArrayDataBlock.java
│ ├── IoPolicy.java
│ ├── KeyLockState.java
│ ├── KeyValueAccess.java
│ ├── LinkedAttributePathToken.java
│ ├── LockedChannel.java
│ ├── LockedFileChannel.java
│ ├── LockingPolicy.java
│ ├── LongArrayDataBlock.java
│ ├── Lz4Compression.java
│ ├── N5Exception.java
│ ├── N5FSReader.java
│ ├── N5FSWriter.java
│ ├── N5KeyValueReader.java
│ ├── N5KeyValueWriter.java
│ ├── N5Reader.java
│ ├── N5URI.java
│ ├── N5Writer.java
│ ├── NameConfigAdapter.java
│ ├── RawCompression.java
│ ├── ReflectionUtils.java
│ ├── ShortArrayDataBlock.java
│ ├── StringDataBlock.java
│ ├── XzCompression.java
│ ├── cache/
│ │ ├── N5JsonCache.java
│ │ └── N5JsonCacheableContainer.java
│ ├── codec/
│ │ ├── BlockCodec.java
│ │ ├── BlockCodecInfo.java
│ │ ├── CodecInfo.java
│ │ ├── CodecParser.java
│ │ ├── ConcatenatedDataCodec.java
│ │ ├── ConcatenatedDeterministicSizeDataCodec.java
│ │ ├── DataCodec.java
│ │ ├── DataCodecInfo.java
│ │ ├── DatasetCodec.java
│ │ ├── DatasetCodecInfo.java
│ │ ├── DeterministicSizeCodecInfo.java
│ │ ├── DeterministicSizeDataCodec.java
│ │ ├── FlatArrayCodec.java
│ │ ├── IdentityCodec.java
│ │ ├── IndexCodecAdapter.java
│ │ ├── N5BlockCodecInfo.java
│ │ ├── N5BlockCodecs.java
│ │ ├── RawBlockCodecInfo.java
│ │ ├── RawBlockCodecs.java
│ │ ├── checksum/
│ │ │ ├── ChecksumCodec.java
│ │ │ ├── ChecksumException.java
│ │ │ └── Crc32cChecksumCodec.java
│ │ └── transpose/
│ │ ├── Transpose.java
│ │ ├── TransposeCodec.java
│ │ └── TransposeCodecInfo.java
│ ├── http/
│ │ ├── ApacheListResponseParser.java
│ │ ├── CandidateListResponseParser.java
│ │ ├── ListResponseParser.java
│ │ ├── MicrosoftListResponseParser.java
│ │ ├── PatternListResponseParser.java
│ │ └── PythonListResponseParser.java
│ ├── readdata/
│ │ ├── ByteArrayReadData.java
│ │ ├── InputStreamReadData.java
│ │ ├── LazyGeneratedReadData.java
│ │ ├── LazyRead.java
│ │ ├── LazyReadData.java
│ │ ├── Range.java
│ │ ├── ReadData.java
│ │ ├── VolatileReadData.java
│ │ ├── prefetch/
│ │ │ ├── AggregatingPrefetchLazyRead.java
│ │ │ ├── EnclosingPrefetchLazyRead.java
│ │ │ ├── SliceTrackingLazyRead.java
│ │ │ └── Slices.java
│ │ └── segment/
│ │ ├── ConcatenatedReadData.java
│ │ ├── DefaultSegmentedReadData.java
│ │ ├── Segment.java
│ │ └── SegmentedReadData.java
│ ├── serialization/
│ │ ├── JsonArrayUtils.java
│ │ ├── N5Annotations.java
│ │ └── NameConfig.java
│ ├── shard/
│ │ ├── DatasetAccess.java
│ │ ├── DefaultDatasetAccess.java
│ │ ├── DefaultShardCodecInfo.java
│ │ ├── Nesting.java
│ │ ├── PositionValueAccess.java
│ │ ├── RawShard.java
│ │ ├── RawShardCodec.java
│ │ ├── RawShardDataBlock.java
│ │ ├── Region.java
│ │ ├── ShardCodecInfo.java
│ │ └── ShardIndex.java
│ └── util/
│ ├── FloatValueParser.java
│ ├── MemCopy.java
│ └── SubArrayCopy.java
└── test/
├── java/
│ └── org/
│ └── janelia/
│ └── saalfeldlab/
│ └── n5/
│ ├── AbstractN5Test.java
│ ├── DatasetAttributesTest.java
│ ├── FileKeyLockManagerTest.java
│ ├── FsLockTest.java
│ ├── N5Benchmark.java
│ ├── N5CachedFSTest.java
│ ├── N5FSTest.java
│ ├── N5ReadBenchmark.java
│ ├── N5URITest.java
│ ├── TrackingN5Writer.java
│ ├── UriTest.java
│ ├── WriteLockExp.java
│ ├── backward/
│ │ ├── CompatibilityTest.java
│ │ └── CreateSampleData.java
│ ├── benchmarks/
│ │ ├── N5BlockWriteBenchmarks.java
│ │ └── ReadDataBenchmarks.java
│ ├── cache/
│ │ └── N5CacheTest.java
│ ├── codec/
│ │ ├── BlockCodecTests.java
│ │ ├── BytesCodecTests.java
│ │ ├── ChecksumCodecTests.java
│ │ └── DatasetCodecTests.java
│ ├── compression/
│ │ └── CompressionTypesTest.java
│ ├── demo/
│ │ └── AttributePathDemo.java
│ ├── http/
│ │ ├── HttpKeyValueAccessTest.java
│ │ ├── HttpReaderFsWriter.java
│ │ ├── N5HttpTest.java
│ │ └── RunnerWithHttpServer.java
│ ├── kva/
│ │ ├── AbstractKeyValueAccessTest.java
│ │ ├── DelegateKeyValueAccess.java
│ │ ├── FileSystemKeyValueAccessTest.java
│ │ ├── FsLockingValidation.java
│ │ ├── HttpKeyValueAccessTest.java
│ │ └── TrackingKeyValueAccess.java
│ ├── locking/
│ │ ├── JustFileChannels.java
│ │ └── JustFileChannelsThreaded.java
│ ├── readdata/
│ │ ├── RangeTests.java
│ │ ├── ReadDataTests.java
│ │ ├── prefetch/
│ │ │ ├── SliceTrackingLazyReadTests.java
│ │ │ └── SlicesTest.java
│ │ └── segment/
│ │ ├── ConcatenatedReadDataTest.java
│ │ └── SegmentTest.java
│ ├── serialization/
│ │ └── CodecSerializationTest.java
│ ├── shard/
│ │ ├── DatasetAccessTest.java
│ │ ├── NestedGridTest.java
│ │ ├── ShardTest.java
│ │ ├── TestPositionValueAccess.java
│ │ ├── WriteRegionTest.java
│ │ ├── WriteShardTest.java
│ │ ├── WriteShardTest2.java
│ │ └── WriteShardTestTruncate.java
│ └── url/
│ └── UriAttributeTest.java
└── resources/
├── backward/
│ ├── data-1.5.0.n5/
│ │ ├── attributes.json
│ │ └── raw/
│ │ ├── 0/
│ │ │ ├── 0
│ │ │ └── 1
│ │ ├── 1/
│ │ │ ├── 0
│ │ │ └── 1
│ │ └── attributes.json
│ ├── data-2.5.1.n5/
│ │ ├── attributes.json
│ │ └── raw/
│ │ ├── 0/
│ │ │ ├── 0
│ │ │ └── 1
│ │ ├── 1/
│ │ │ ├── 0
│ │ │ └── 1
│ │ └── attributes.json
│ └── data-3.1.3.n5/
│ ├── attributes.json
│ └── raw/
│ ├── 0/
│ │ ├── 0
│ │ └── 1
│ ├── 1/
│ │ ├── 0
│ │ └── 1
│ └── attributes.json
└── url/
└── urlAttributes.n5/
├── a/
│ ├── aa/
│ │ ├── aaa/
│ │ │ └── attributes.json
│ │ └── attributes.json
│ └── attributes.json
├── attributes.json
└── objs/
└── attributes.json
SYMBOL INDEX (1847 symbols across 165 files)
FILE: src/main/java/org/janelia/saalfeldlab/n5/AbstractDataBlock.java
class AbstractDataBlock (line 13) | public abstract class AbstractDataBlock<T> implements DataBlock<T> {
method AbstractDataBlock (line 20) | public AbstractDataBlock(
method getSize (line 32) | @Override
method getGridPosition (line 38) | @Override
method getData (line 44) | @Override
method getNumElements (line 50) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/BufferedKvaLockedChannel.java
class BufferedKvaLockedChannel (line 9) | class BufferedKvaLockedChannel implements LockedChannel {
method BufferedKvaLockedChannel (line 15) | BufferedKvaLockedChannel(final KeyValueAccess kva, final String key) {
method newReader (line 20) | @Override
method newInputStream (line 26) | @Override
method newWriter (line 39) | @Override
method newOutputStream (line 45) | @Override
method close (line 52) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/ByteArrayDataBlock.java
class ByteArrayDataBlock (line 3) | public class ByteArrayDataBlock extends AbstractDataBlock<byte[]> {
method ByteArrayDataBlock (line 5) | public ByteArrayDataBlock(final int[] size, final long[] gridPosition,...
FILE: src/main/java/org/janelia/saalfeldlab/n5/Bzip2Compression.java
class Bzip2Compression (line 12) | @CompressionType("bzip2")
method Bzip2Compression (line 22) | public Bzip2Compression(final int blockSize) {
method Bzip2Compression (line 27) | public Bzip2Compression() {
method equals (line 32) | @Override
method decode (line 41) | @Override
method encode (line 50) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/CachedGsonKeyValueN5Reader.java
type CachedGsonKeyValueN5Reader (line 19) | public interface CachedGsonKeyValueN5Reader extends GsonKeyValueN5Reader...
method newCache (line 21) | default N5JsonCache newCache() {
method cacheMeta (line 26) | boolean cacheMeta();
method getCache (line 28) | N5JsonCache getCache();
method getAttributesFromContainer (line 30) | @Override
method getDatasetAttributes (line 38) | @Override
method normalGetDatasetAttributes (line 56) | default DatasetAttributes normalGetDatasetAttributes(final String path...
method getAttribute (line 63) | @Override
method getAttribute (line 85) | @Override
method exists (line 106) | @Override
method existsFromContainer (line 117) | @Override
method groupExists (line 127) | @Override
method isGroupFromContainer (line 138) | @Override
method isGroupFromAttributes (line 144) | @Override
method datasetExists (line 150) | @Override
method isDatasetFromContainer (line 160) | @Override
method isDatasetFromAttributes (line 166) | @Override
method getAttributes (line 180) | @Override
method list (line 193) | @Override
method listFromContainer (line 204) | @Override
method hasDatasetAttributes (line 219) | static boolean hasDatasetAttributes(final JsonElement attributes) {
FILE: src/main/java/org/janelia/saalfeldlab/n5/CachedGsonKeyValueN5Writer.java
type CachedGsonKeyValueN5Writer (line 12) | public interface CachedGsonKeyValueN5Writer extends CachedGsonKeyValueN5...
method setVersion (line 14) | @Override
method createGroup (line 25) | @Override
method writeAttributes (line 63) | @Override
method writeAndCacheAttributes (line 71) | default void writeAndCacheAttributes(
method remove (line 97) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/ChannelLock.java
class ChannelLock (line 18) | class ChannelLock implements Closeable {
method ChannelLock (line 35) | private ChannelLock(final FileChannel channel, final FileLock lock) {
method close (line 40) | public void close() throws IOException {
method getChannel (line 50) | FileChannel getChannel() {
method lock (line 69) | static ChannelLock lock(final Path path, final boolean forWriting, fin...
method openFileChannel (line 106) | private static FileChannel openFileChannel(final Path path, final bool...
method closeQuietly (line 119) | private static void closeQuietly(final FileChannel fileChannel) {
FILE: src/main/java/org/janelia/saalfeldlab/n5/Compression.java
type Compression (line 29) | public interface Compression extends Serializable, DataCodec, DataCodecI...
method getType (line 53) | default String getType() {
method create (line 62) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/CompressionAdapter.java
class CompressionAdapter (line 31) | public class CompressionAdapter implements JsonDeserializer<Compression>...
method getDeclaredFields (line 38) | private static ArrayList<Field> getDeclaredFields(Class<?> clazz) {
method update (line 47) | @SuppressWarnings("unchecked")
method update (line 84) | public static void update() {
method serialize (line 89) | @Override
method deserialize (line 120) | @Override
method getJsonAdapter (line 153) | public static CompressionAdapter getJsonAdapter() {
FILE: src/main/java/org/janelia/saalfeldlab/n5/DataBlock.java
type DataBlock (line 11) | public interface DataBlock<T> {
method getSize (line 22) | int[] getSize();
method getGridPosition (line 32) | long[] getGridPosition();
method getData (line 39) | T getData();
method getNumElements (line 48) | int getNumElements();
method getNumElements (line 57) | static int getNumElements(final int[] size) {
type DataBlockFactory (line 71) | interface DataBlockFactory<T> {
method createDataBlock (line 85) | DataBlock<T> createDataBlock(int[] blockSize, long[] gridPosition, T...
FILE: src/main/java/org/janelia/saalfeldlab/n5/DataType.java
type DataType (line 18) | public enum DataType {
method DataType (line 97) | DataType(final String label, final DataBlockFactory dataBlockFactory) {
method toString (line 103) | @Override
method fromString (line 109) | public static DataType fromString(final String string) {
method createDataBlock (line 129) | public DataBlock<?> createDataBlock(final int[] blockSize, final long[...
method createDataBlock (line 144) | public DataBlock<?> createDataBlock(final int[] blockSize, final long[...
type DataBlockFactory (line 149) | private interface DataBlockFactory {
method createDataBlock (line 151) | DataBlock<?> createDataBlock(final int[] blockSize, final long[] gri...
class JsonAdapter (line 154) | static public class JsonAdapter implements JsonDeserializer<DataType>,...
method deserialize (line 156) | @Override
method serialize (line 165) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/DatasetAttributes.java
class DatasetAttributes (line 44) | public class DatasetAttributes implements Serializable {
method DatasetAttributes (line 81) | public DatasetAttributes(
method DatasetAttributes (line 109) | public DatasetAttributes(
method DatasetAttributes (line 121) | public DatasetAttributes(
method DatasetAttributes (line 140) | public DatasetAttributes(
method DatasetAttributes (line 156) | public DatasetAttributes(
method createDatasetAccess (line 164) | private DatasetAccess<?> createDatasetAccess() {
method blockCodecWithDatasetCodecs (line 212) | @SuppressWarnings("unchecked")
method nestingDepth (line 225) | private static int nestingDepth(BlockCodecInfo info) {
method defaultBlockCodecInfo (line 234) | protected BlockCodecInfo defaultBlockCodecInfo() {
method getDimensions (line 239) | public long[] getDimensions() {
method getNumDimensions (line 244) | public int getNumDimensions() {
method getChunkSize (line 249) | public int[] getChunkSize() {
method getBlockSize (line 254) | public int[] getBlockSize() {
method getDefaultValue (line 259) | public JsonElement getDefaultValue() {
method isSharded (line 264) | public boolean isSharded() {
method getCompression (line 278) | @Deprecated
method getDataType (line 288) | public DataType getDataType() {
method getDatasetAccess (line 298) | protected <T> DatasetAccess<T> getDatasetAccess() {
method getNestedBlockGrid (line 309) | public NestedGrid getNestedBlockGrid() {
method getBlockCodecInfo (line 314) | public BlockCodecInfo getBlockCodecInfo() {
method getDataCodecInfos (line 319) | public DataCodecInfo[] getDataCodecInfos() {
method getDatasetCodecInfos (line 324) | public DatasetCodecInfo[] getDatasetCodecInfos() {
method relativeBlockPath (line 329) | public String relativeBlockPath(long... position) {
method asMap (line 334) | public HashMap<String, Object> asMap() {
method builder (line 344) | public static Builder builder(final long[] dimensions, final DataType ...
method builder (line 349) | public static Builder builder(final DatasetAttributes attributes) {
method defaultBlockSize (line 359) | protected static int[] defaultBlockSize(final long[] dimensions) {
class Builder (line 377) | public static class Builder {
method Builder (line 385) | public Builder(final long[] dimensions, final DataType dataType) {
method Builder (line 392) | public Builder(final DatasetAttributes attributes) {
method blockSize (line 400) | public Builder blockSize(final int[] blockSize) {
method compression (line 413) | public Builder compression(final Compression compression) {
method build (line 420) | public DatasetAttributes build() {
method getJsonAdapter (line 428) | public static DatasetAttributesAdapter getJsonAdapter() {
class DatasetAttributesAdapter (line 436) | public static class DatasetAttributesAdapter implements JsonSerializer...
method deserialize (line 438) | @Override public DatasetAttributes deserialize(JsonElement json, Typ...
method serialize (line 482) | @Override public JsonElement serialize(DatasetAttributes src, Type t...
method getCompressionVersion0 (line 499) | private static Compression getCompressionVersion0(final String compr...
FILE: src/main/java/org/janelia/saalfeldlab/n5/DoubleArrayDataBlock.java
class DoubleArrayDataBlock (line 3) | public class DoubleArrayDataBlock extends AbstractDataBlock<double[]> {
method DoubleArrayDataBlock (line 5) | public DoubleArrayDataBlock(final int[] size, final long[] gridPositio...
FILE: src/main/java/org/janelia/saalfeldlab/n5/FileKeyLockManager.java
class FileKeyLockManager (line 19) | class FileKeyLockManager {
method forPolicy (line 23) | static FileKeyLockManager forPolicy(final LockingPolicy policy) {
method FileKeyLockManager (line 50) | private FileKeyLockManager(final LockingPolicy policy) {
class WeakValue (line 58) | private static class WeakValue extends WeakReference<KeyLockState> {
method WeakValue (line 62) | WeakValue(
method cleanUp (line 76) | private void cleanUp()
method keyLockState (line 86) | private KeyLockState keyLockState(final Path path, final LockingPolicy...
method lockForReading (line 124) | public LockedFileChannel lockForReading(final Path path) throws IOExce...
method lockForWriting (line 141) | public LockedFileChannel lockForWriting(final Path path) throws IOExce...
method size (line 151) | int size() {
FILE: src/main/java/org/janelia/saalfeldlab/n5/FileSystemKeyValueAccess.java
class FileSystemKeyValueAccess (line 34) | public class FileSystemKeyValueAccess implements KeyValueAccess {
method FileSystemKeyValueAccess (line 38) | public FileSystemKeyValueAccess() {
method lockForReading (line 43) | private LockedFileChannel lockForReading(final Path path) throws N5IOE...
method lockForWriting (line 54) | private LockedFileChannel lockForWriting(final Path path) throws N5IOE...
method createReadData (line 65) | @Override
method write (line 70) | @Override
method isDirectory (line 80) | @Override
method isFile (line 87) | @Override
method exists (line 94) | @Override
method size (line 101) | @Override
method size (line 107) | private static long size(final Path path) {
method listDirectories (line 118) | @Override
method list (line 134) | @Override
method components (line 149) | @Override
method parent (line 178) | @Override
method relativize (line 188) | @Override
method normalize (line 204) | @Override
method uri (line 210) | @Override
method compose (line 224) | @Override
method compose (line 234) | @Override
method createDirectories (line 251) | @Override
method delete (line 263) | @Override
method tryDelete (line 293) | protected static void tryDelete(final Path path) throws IOException {
method createDirectories (line 373) | protected static Path createDirectories(Path dir, final FileAttribute<...
method createAndCheckIsDirectory (line 437) | protected static void createAndCheckIsDirectory(
method validBounds (line 455) | private static void validBounds(final long channelSize, final long off...
class FileLazyRead (line 465) | private class FileLazyRead implements LazyRead {
method FileLazyRead (line 470) | FileLazyRead(final Path path) {
method size (line 475) | @Override
method materialize (line 491) | @Override
method close (line 515) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/FloatArrayDataBlock.java
class FloatArrayDataBlock (line 3) | public class FloatArrayDataBlock extends AbstractDataBlock<float[]> {
method FloatArrayDataBlock (line 5) | public FloatArrayDataBlock(final int[] size, final long[] gridPosition...
FILE: src/main/java/org/janelia/saalfeldlab/n5/FsIoPolicy.java
class FsIoPolicy (line 18) | public class FsIoPolicy {
method validBounds (line 22) | private static boolean validBounds(long channelSize, long offset, long...
method openFileChannel (line 41) | static FileChannel openFileChannel(final Path path, final boolean forW...
method writeToPathIgnoreCloseException (line 64) | private static void writeToPathIgnoreCloseException(ReadData readData,...
class Unsafe (line 88) | public static class Unsafe implements IoPolicy {
method write (line 89) | @Override
method read (line 95) | @Override
method delete (line 102) | @Override
class Atomic (line 109) | public static class Atomic implements IoPolicy {
method write (line 110) | @Override
method read (line 118) | @Override
method delete (line 125) | @Override
class FileLazyRead (line 136) | static class FileLazyRead implements LazyRead {
method FileLazyRead (line 143) | FileLazyRead(final Path path) throws IOException {
method FileLazyRead (line 147) | FileLazyRead(final Path path, final boolean requireLock ) throws IOE...
method size (line 155) | @Override
method materialize (line 171) | @Override
method close (line 211) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/GsonKeyValueN5Reader.java
type GsonKeyValueN5Reader (line 19) | public interface GsonKeyValueN5Reader extends GsonN5Reader {
method getKeyValueAccess (line 21) | KeyValueAccess getKeyValueAccess();
method groupExists (line 23) | default boolean groupExists(final String normalPath) {
method exists (line 28) | @Override
method datasetExists (line 35) | @Override
method getAttributes (line 50) | @Override
method readChunk (line 68) | @Override
method readChunks (line 85) | @Override
method readBlock (line 96) | @Override
method list (line 114) | @Override
method absoluteGroupPath (line 128) | default String absoluteGroupPath(final String normalGroupPath) {
method absoluteAttributesPath (line 141) | default String absoluteAttributesPath(final String normalPath) {
method blockExists (line 146) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/GsonKeyValueN5Writer.java
type GsonKeyValueN5Writer (line 26) | public interface GsonKeyValueN5Writer extends GsonN5Writer, GsonKeyValue...
method setVersion (line 35) | default void setVersion(final String path) {
method initializeContainer (line 41) | static String initializeContainer(
method createGroup (line 50) | @Override
method writeAttributes (line 70) | default void writeAttributes(
method setAttributes (line 86) | @Override
method writeAttributes (line 114) | default void writeAttributes(
method setAttributes (line 128) | @Override
method removeAttribute (line 140) | @Override
method removeAttribute (line 163) | @Override
method removeAttributes (line 182) | @Override
method writeRegion (line 194) | @Override
method writeRegion (line 212) | @Override
method writeChunks (line 231) | @Override
method writeChunk (line 247) | @Override
method writeBlock (line 264) | @Override
method remove (line 282) | @Override
method deleteBlock (line 294) | @Override
method deleteChunk (line 304) | @Override
method deleteChunks (line 314) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/GsonN5Reader.java
type GsonN5Reader (line 17) | public interface GsonN5Reader extends N5Reader {
method getGson (line 19) | Gson getGson();
method getAttributesKey (line 27) | String getAttributesKey();
method listAttributes (line 29) | @Override
method getDatasetAttributes (line 35) | @Override
method createDatasetAttributes (line 43) | default DatasetAttributes createDatasetAttributes(final JsonElement at...
method getAttribute (line 56) | @Override
method getAttribute (line 70) | @Override
method getAttributes (line 91) | JsonElement getAttributes(final String pathName) throws N5Exception;
FILE: src/main/java/org/janelia/saalfeldlab/n5/GsonN5Writer.java
type GsonN5Writer (line 10) | public interface GsonN5Writer extends GsonN5Reader, N5Writer {
method setAttributes (line 22) | void setAttributes(
FILE: src/main/java/org/janelia/saalfeldlab/n5/GsonUtils.java
type GsonUtils (line 26) | public interface GsonUtils {
method readAttributes (line 37) | static JsonElement readAttributes(final Reader reader, final Gson gson) {
method readAttribute (line 42) | static <T> T readAttribute(
method readAttribute (line 51) | static <T> T readAttribute(
method parseAttributeElement (line 75) | @SuppressWarnings("unchecked")
method getAttribute (line 127) | static JsonElement getAttribute(JsonElement root, final String normali...
method listAttributes (line 176) | static Map<String, Class<?>> listAttributes(final JsonElement root) th...
method getJsonAsArray (line 229) | static <T> T getJsonAsArray(final Gson gson, final JsonArray array, fi...
method getJsonAsArray (line 234) | @SuppressWarnings("unchecked")
method classForJsonPrimitive (line 321) | static Class<?> classForJsonPrimitive(final JsonPrimitive jsonPrimitiv...
method removeAttribute (line 365) | static <T> T removeAttribute(
method removeAttribute (line 393) | static boolean removeAttribute(
method removeAttribute (line 429) | static <T> T removeAttribute(
method removeAttribute (line 453) | static JsonElement removeAttribute(JsonElement root, final String norm...
method writeAttribute (line 511) | static <T> void writeAttribute(
method writeAttributes (line 537) | static <T> void writeAttributes(
method insertAttributes (line 546) | static JsonElement insertAttributes(JsonElement root, final Map<String...
method insertAttribute (line 554) | static <T> JsonElement insertAttribute(
FILE: src/main/java/org/janelia/saalfeldlab/n5/GzipCompression.java
class GzipCompression (line 16) | @CompressionType("gzip")
method GzipCompression (line 44) | public GzipCompression() {
method GzipCompression (line 49) | public GzipCompression(final int level) {
method GzipCompression (line 54) | public GzipCompression(final int level, final boolean useZlib) {
method equals (line 60) | @Override
method decode (line 71) | private InputStream decode(final InputStream in) throws IOException {
method decode (line 82) | @Override
method encode (line 92) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/HttpKeyValueAccess.java
class HttpKeyValueAccess (line 35) | public class HttpKeyValueAccess implements KeyValueAccess {
method HttpKeyValueAccess (line 55) | public HttpKeyValueAccess() {
method setReadTimeout (line 61) | public void setReadTimeout(int readTimeoutMilliseconds) {
method setConnectionTimeout (line 66) | public void setConnectionTimeout(int connectionTimeoutMilliseconds) {
method setListParser (line 71) | public void setListParser(final ListResponseParser parser) {
method setListDirectoryParser (line 76) | public void setListDirectoryParser(final ListResponseParser parser) {
method normalize (line 81) | @Override
method uri (line 87) | @Override
method exists (line 103) | @Override
method size (line 114) | @Override public long size(String normalPath) {
method isDirectory (line 131) | @Override
method getDirectoryPath (line 151) | private static String getDirectoryPath(String normalPath) {
method isFile (line 172) | @Override
method getFilePath (line 192) | private static String getFilePath(String normalPath) {
method httpRequest (line 198) | private HttpURLConnection httpRequest(String normalPath, String method...
method createReadData (line 208) | @Override
method lockForReading (line 213) | public LockedChannel lockForReading(final String normalPath) throws N5...
method lockForWriting (line 224) | @Override
method write (line 230) | @Override
method listDirectories (line 248) | @Override
method list (line 267) | @Override
method queryListEntries (line 273) | private String[] queryListEntries(String normalPath, ListResponseParse...
method validExistsResponse (line 284) | private static N5Exception validExistsResponse(int code, String respon...
method requireValidHttpResponse (line 294) | private HttpURLConnection requireValidHttpResponse(String uri, String ...
method requireValidHttpResponse (line 298) | private HttpURLConnection requireValidHttpResponse(String uri, String ...
method requireValidHttpResponse (line 302) | private HttpURLConnection requireValidHttpResponse(String uri, String ...
method responseToString (line 321) | private String responseToString(InputStream inputStream) throws IOExce...
method createDirectories (line 326) | @Override
method delete (line 332) | @Override
class HttpObjectChannel (line 338) | private class HttpObjectChannel implements LockedChannel {
method HttpObjectChannel (line 345) | protected HttpObjectChannel(final URI uri, long startByte, long size) {
method isPartialRead (line 352) | private boolean isPartialRead() {
method newInputStream (line 356) | @Override
method rangeString (line 379) | private String rangeString() {
method newReader (line 385) | @Override
method newOutputStream (line 395) | @Override
method newWriter (line 401) | @Override
method close (line 407) | @Override
class HttpLazyRead (line 419) | private class HttpLazyRead implements LazyRead {
method HttpLazyRead (line 423) | HttpLazyRead(String normalKey) {
method size (line 427) | @Override
method materialize (line 432) | @Override
method close (line 443) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/IntArrayDataBlock.java
class IntArrayDataBlock (line 3) | public class IntArrayDataBlock extends AbstractDataBlock<int[]> {
method IntArrayDataBlock (line 5) | public IntArrayDataBlock(final int[] size, final long[] gridPosition, ...
FILE: src/main/java/org/janelia/saalfeldlab/n5/IoPolicy.java
type IoPolicy (line 8) | public interface IoPolicy {
method write (line 10) | void write(String key, ReadData readData) throws IOException;
method read (line 12) | VolatileReadData read(String key) throws IOException;
method delete (line 14) | void delete(String key) throws IOException;
method withFallback (line 16) | static IoPolicy withFallback(IoPolicy primary, IoPolicy fallback) {
FILE: src/main/java/org/janelia/saalfeldlab/n5/KeyLockState.java
class KeyLockState (line 12) | class KeyLockState {
method KeyLockState (line 18) | public KeyLockState(final Path path, LockingPolicy policy) {
method acquireRead (line 45) | LockedFileChannel acquireRead() throws IOException {
method releaseRead (line 78) | void releaseRead() throws IOException {
method releaseChannelLock (line 96) | private void releaseChannelLock() throws IOException {
method acquireWrite (line 105) | LockedFileChannel acquireWrite() throws IOException {
method releaseWrite (line 127) | void releaseWrite() throws IOException {
FILE: src/main/java/org/janelia/saalfeldlab/n5/KeyValueAccess.java
type KeyValueAccess (line 22) | public interface KeyValueAccess {
method components (line 31) | default String[] components( final String path ) {
method compose (line 59) | default String compose( final URI uri, final String... components ) {
method compose (line 97) | @Deprecated
method parent (line 115) | default String parent( final String path ) {
method relativize (line 129) | default String relativize( final String path, final String base ) {
method normalize (line 155) | String normalize( final String path );
method uri (line 166) | default URI uri(final String uriString) throws URISyntaxException {
method exists (line 181) | boolean exists( final String normalPath );
method size (line 192) | long size( final String normalPath ) throws N5Exception.N5NoSuchKeyExc...
method isDirectory (line 202) | boolean isDirectory( String normalPath );
method isFile (line 212) | boolean isFile( String normalPath );
method createReadData (line 237) | VolatileReadData createReadData(final String normalPath) throws N5IOEx...
method write (line 252) | void write(String normalPath, ReadData data) throws N5IOException;
method lockForReading (line 271) | @Deprecated
method lockForWriting (line 294) | @Deprecated
method listDirectories (line 309) | String[] listDirectories( final String normalPath ) throws N5IOException;
method list (line 320) | String[] list( final String normalPath ) throws N5IOException;
method createDirectories (line 334) | void createDirectories( final String normalPath ) throws N5IOException;
method delete (line 345) | void delete( final String normalPath ) throws N5IOException;
FILE: src/main/java/org/janelia/saalfeldlab/n5/LinkedAttributePathToken.java
class LinkedAttributePathToken (line 12) | public abstract class LinkedAttributePathToken<T extends JsonElement> im...
method getJsonType (line 27) | public abstract T getJsonType();
method getOrCreateChildElement (line 42) | public abstract JsonElement getOrCreateChildElement();
method writeChild (line 62) | public JsonElement writeChild(final Gson gson, final Object value) {
method jsonCompatible (line 90) | @SuppressWarnings("BooleanMethodIsAlwaysInverted")
method writeValue (line 107) | protected abstract void writeValue(Gson gson, Object value);
method writeChildElement (line 113) | protected abstract void writeChildElement();
method getChildElement (line 119) | protected abstract JsonElement getChildElement();
method setAndCreateParentElement (line 133) | @SuppressWarnings("unchecked")
method hasNext (line 149) | @Override
method next (line 158) | @Override
class ObjectAttributeToken (line 164) | public static class ObjectAttributeToken extends LinkedAttributePathTo...
method ObjectAttributeToken (line 170) | public ObjectAttributeToken(final String key) {
method getKey (line 179) | public String getKey() {
method toString (line 184) | @Override
method getJsonType (line 190) | @Override
method getOrCreateChildElement (line 196) | @Override
method getChildElement (line 206) | @Override
method writeValue (line 212) | @Override
method writeChildElement (line 218) | @Override
class ArrayAttributeToken (line 228) | public static class ArrayAttributeToken extends LinkedAttributePathTok...
method ArrayAttributeToken (line 234) | public ArrayAttributeToken(final int index) {
method getIndex (line 243) | public int getIndex() {
method toString (line 248) | @Override
method getJsonType (line 254) | @Override
method getOrCreateChildElement (line 260) | @Override
method writeChildElement (line 269) | @Override
method getChildElement (line 278) | @Override
method writeValue (line 284) | @Override
method fillArrayToIndex (line 303) | private static void fillArrayToIndex(final JsonArray array, final in...
method valueRepresentsANumber (line 330) | private static boolean valueRepresentsANumber(final Object value) {
FILE: src/main/java/org/janelia/saalfeldlab/n5/LockedChannel.java
type LockedChannel (line 17) | public interface LockedChannel extends Closeable {
method newReader (line 26) | Reader newReader() throws N5IOException;
method newInputStream (line 35) | InputStream newInputStream() throws N5IOException;
method newWriter (line 44) | Writer newWriter() throws N5IOException;
method newOutputStream (line 53) | OutputStream newOutputStream() throws N5IOException;
FILE: src/main/java/org/janelia/saalfeldlab/n5/LockedFileChannel.java
class LockedFileChannel (line 20) | class LockedFileChannel implements Closeable {
type ReleaseLock (line 30) | @FunctionalInterface
method release (line 33) | void release() throws IOException;
method LockedFileChannel (line 36) | LockedFileChannel(final FileChannel channel, final ReleaseLock release...
method size (line 47) | public long size() throws IOException {
method read (line 57) | public int read(final ByteBuffer dst, final long position) throws IOEx...
method asOutputStream (line 65) | public OutputStream asOutputStream() {
class ClosingChannelWrapper (line 71) | private class ClosingChannelWrapper implements WritableByteChannel {
method write (line 73) | @Override
method isOpen (line 86) | @Override
method close (line 91) | @Override
method close (line 98) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/LockingPolicy.java
type LockingPolicy (line 24) | public enum LockingPolicy {
method fromString (line 44) | static LockingPolicy fromString(final String s) {
FILE: src/main/java/org/janelia/saalfeldlab/n5/LongArrayDataBlock.java
class LongArrayDataBlock (line 3) | public class LongArrayDataBlock extends AbstractDataBlock<long[]> {
method LongArrayDataBlock (line 5) | public LongArrayDataBlock(final int[] size, final long[] gridPosition,...
FILE: src/main/java/org/janelia/saalfeldlab/n5/Lz4Compression.java
class Lz4Compression (line 9) | @CompressionType("lz4")
method Lz4Compression (line 19) | public Lz4Compression(final int blockSize) {
method Lz4Compression (line 24) | public Lz4Compression() {
method equals (line 29) | @Override
method decode (line 38) | @Override
method encode (line 44) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/N5Exception.java
class N5Exception (line 3) | public class N5Exception extends RuntimeException {
method N5Exception (line 5) | public N5Exception() {
method N5Exception (line 10) | public N5Exception(final String message) {
method N5Exception (line 15) | public N5Exception(final String message, final Throwable cause) {
method N5Exception (line 20) | public N5Exception(final Throwable cause) {
method N5Exception (line 25) | protected N5Exception(
class N5IOException (line 34) | public static class N5IOException extends N5Exception{
method N5IOException (line 36) | public N5IOException(final String message) {
method N5IOException (line 41) | public N5IOException(final String message, final Throwable cause) {
method N5IOException (line 46) | public N5IOException(final Throwable cause) {
method N5IOException (line 51) | protected N5IOException(
class N5ClassCastException (line 65) | public static class N5ClassCastException extends N5Exception {
method N5ClassCastException (line 68) | public N5ClassCastException(final Class<?> cls) {
method N5ClassCastException (line 73) | public N5ClassCastException(final String message) {
method N5ClassCastException (line 78) | public N5ClassCastException(final String message, final Throwable ca...
method N5ClassCastException (line 83) | public N5ClassCastException(final Throwable cause) {
method N5ClassCastException (line 88) | protected N5ClassCastException(
class N5NoSuchKeyException (line 98) | public static class N5NoSuchKeyException extends N5IOException {
method N5NoSuchKeyException (line 100) | public N5NoSuchKeyException(final String message) {
method N5NoSuchKeyException (line 105) | public N5NoSuchKeyException(final String message, final Throwable ca...
method N5NoSuchKeyException (line 110) | public N5NoSuchKeyException(final Throwable cause) {
method N5NoSuchKeyException (line 115) | protected N5NoSuchKeyException(
class N5JsonParseException (line 128) | public static class N5JsonParseException extends N5Exception {
method N5JsonParseException (line 129) | public N5JsonParseException(final String message) {
method N5JsonParseException (line 134) | public N5JsonParseException(final String message, final Throwable ca...
method N5JsonParseException (line 139) | public N5JsonParseException(final Throwable cause) {
method N5JsonParseException (line 144) | protected N5JsonParseException(
class N5ConcurrentModificationException (line 155) | public static class N5ConcurrentModificationException extends N5IOExce...
method N5ConcurrentModificationException (line 157) | public N5ConcurrentModificationException(final String message) {
method N5ConcurrentModificationException (line 162) | public N5ConcurrentModificationException(final String message, final...
method N5ConcurrentModificationException (line 167) | public N5ConcurrentModificationException(final Throwable cause) {
method N5ConcurrentModificationException (line 172) | protected N5ConcurrentModificationException(
FILE: src/main/java/org/janelia/saalfeldlab/n5/N5FSReader.java
class N5FSReader (line 17) | public class N5FSReader extends N5KeyValueReader {
method N5FSReader (line 40) | public N5FSReader(final String basePath, final GsonBuilder gsonBuilder...
method N5FSReader (line 71) | public N5FSReader(final String basePath, final boolean cacheMeta) thro...
method N5FSReader (line 89) | public N5FSReader(final String basePath, final GsonBuilder gsonBuilder...
method N5FSReader (line 104) | public N5FSReader(final String basePath) throws N5Exception {
FILE: src/main/java/org/janelia/saalfeldlab/n5/N5FSWriter.java
class N5FSWriter (line 12) | public class N5FSWriter extends N5KeyValueWriter {
method N5FSWriter (line 41) | public N5FSWriter(final String basePath, final GsonBuilder gsonBuilder...
method N5FSWriter (line 75) | public N5FSWriter(final String basePath, final boolean cacheAttributes...
method N5FSWriter (line 102) | public N5FSWriter(final String basePath, final GsonBuilder gsonBuilder...
method N5FSWriter (line 126) | public N5FSWriter(final String basePath) throws N5Exception {
FILE: src/main/java/org/janelia/saalfeldlab/n5/N5KeyValueReader.java
class N5KeyValueReader (line 20) | public class N5KeyValueReader implements CachedGsonKeyValueN5Reader {
method N5KeyValueReader (line 55) | public N5KeyValueReader(
method N5KeyValueReader (line 92) | protected N5KeyValueReader(
method inferExistence (line 132) | private boolean inferExistence(String path) {
method registerGson (line 138) | protected GsonBuilder registerGson(final GsonBuilder gsonBuilder) {
method getAttributesKey (line 147) | @Override
method getGson (line 153) | @Override
method getKeyValueAccess (line 159) | @Override
method getURI (line 165) | @Override
method cacheMeta (line 171) | @Override
method getCache (line 177) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/N5KeyValueWriter.java
class N5KeyValueWriter (line 10) | public class N5KeyValueWriter extends N5KeyValueReader implements Cached...
method N5KeyValueWriter (line 39) | public N5KeyValueWriter(
FILE: src/main/java/org/janelia/saalfeldlab/n5/N5Reader.java
type N5Reader (line 29) | public interface N5Reader extends AutoCloseable {
class Version (line 31) | class Version {
method Version (line 38) | public Version(
method Version (line 50) | public Version(
method Version (line 68) | public Version(final String versionString) {
method getMajor (line 101) | public final int getMajor() {
method getMinor (line 106) | public final int getMinor() {
method getPatch (line 111) | public final int getPatch() {
method getSuffix (line 116) | public final String getSuffix() {
method toString (line 121) | @Override
method equals (line 135) | @Override
method isCompatible (line 159) | public boolean isCompatible(final Version version) {
method getVersion (line 193) | default Version getVersion() throws N5Exception {
method getURI (line 203) | URI getURI();
method getAttribute (line 220) | <T> T getAttribute(
method getAttribute (line 240) | <T> T getAttribute(
method getDatasetAttributes (line 255) | DatasetAttributes getDatasetAttributes(String pathName) throws N5Excep...
method getConvertedDatasetAttributes (line 268) | default DatasetAttributes getConvertedDatasetAttributes(final DatasetA...
method readChunk (line 288) | <T> DataBlock<T> readChunk(
method readChunks (line 311) | default <T> List<DataBlock<T>> readChunks(
method readBlock (line 344) | <T> DataBlock<T> readBlock(
method blockExists (line 370) | boolean blockExists(
method readSerializedBlock (line 394) | default <T> T readSerializedBlock(
method exists (line 419) | boolean exists(String pathName);
method datasetExists (line 430) | default boolean datasetExists(final String pathName) throws N5Exception {
method list (line 444) | String[] list(String pathName) throws N5Exception;
method deepList (line 460) | default String[] deepList(
method deepList (line 487) | default String[] deepList(final String pathName) throws N5Exception {
method deepListDatasets (line 523) | default String[] deepListDatasets(
method deepListDatasets (line 572) | default String[] deepListDatasets(final String pathName) throws N5Exce...
method deepList (line 592) | static ArrayList<String> deepList(
method deepList (line 636) | default String[] deepList(
method deepList (line 672) | default String[] deepList(
method deepListDatasets (line 722) | default String[] deepListDatasets(
method deepListDatasets (line 781) | default String[] deepListDatasets(
method deepListHelper (line 808) | static void deepListHelper(
method listAttributes (line 848) | Map<String, Class<?>> listAttributes(String pathName) throws N5Exception;
method getGroupSeparator (line 855) | default String getGroupSeparator() {
method groupPath (line 868) | default String groupPath(final String... nodes) {
method close (line 889) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/N5URI.java
class N5URI (line 27) | public class N5URI {
method N5URI (line 37) | public N5URI(final String uri) throws URISyntaxException {
method N5URI (line 42) | public N5URI(final URI uri) {
method getContainerPath (line 59) | public String getContainerPath() {
method getURI (line 64) | public URI getURI() {
method getGroupPath (line 71) | public String getGroupPath() {
method normalizeGroupPath (line 79) | public String normalizeGroupPath() {
method getAttributePath (line 87) | public String getAttributePath() {
method normalizeAttributePath (line 95) | public String normalizeAttributePath() {
method getAttributePathTokens (line 106) | public LinkedAttributePathToken<?> getAttributePathTokens() {
method getAttributePathTokens (line 123) | public static LinkedAttributePathToken<?> getAttributePathTokens(final...
method getSchemePart (line 159) | private String getSchemePart() {
method getContainerPart (line 164) | private String getContainerPart() {
method getGroupPart (line 169) | private String getGroupPart() {
method getAttributePart (line 174) | private String getAttributePart() {
method toString (line 179) | @Override
method getSchemeSpecificPartWithoutQuery (line 185) | private String getSchemeSpecificPartWithoutQuery() {
method isAbsolute (line 198) | public boolean isAbsolute() {
method resolve (line 222) | public N5URI resolve(final N5URI relativeN5Url) throws URISyntaxExcept...
method resolve (line 303) | public N5URI resolve(final URI relativeUri) throws URISyntaxException {
method resolve (line 320) | public N5URI resolve(final String relativeString) throws URISyntaxExce...
method normalizePath (line 337) | private static String normalizePath(String path) {
method normalizeGroupPath (line 415) | public static String normalizeGroupPath(final String path) {
type N5UriPattern (line 430) | private enum N5UriPattern {
method N5UriPattern (line 475) | N5UriPattern(Pattern pattern) {
method matches (line 479) | boolean matches(final String input) {
method replaceAll (line 483) | String replaceAll(final String input, final String replacement) {
method appendSlashAfterArrayStart (line 487) | static String appendSlashAfterArrayStart(final String input) {
method addSlashAroundArrayExceptStart (line 491) | static String addSlashAroundArrayExceptStart(final String input) {
method removeRelativePathParts (line 495) | static String removeRelativePathParts(final String path) {
method normalizeAttributePath (line 549) | public static String normalizeAttributePath(final String attributePath) {
method getAsUri (line 577) | public static URI getAsUri(final String uri) throws N5Exception {
method encodeAsUriPath (line 590) | public static URI encodeAsUriPath(final String path) {
method encodeAsUri (line 608) | public static URI encodeAsUri(final String uri) throws URISyntaxExcept...
method from (line 663) | public static N5URI from(
method decode (line 679) | @SuppressWarnings("JavadocReference")
method decode (line 697) | @SuppressWarnings("JavadocReference")
method decodeFragment (line 720) | @SuppressWarnings("JavadocReference")
FILE: src/main/java/org/janelia/saalfeldlab/n5/N5Writer.java
type N5Writer (line 23) | public interface N5Writer extends N5Reader {
method setAttribute (line 34) | default <T> void setAttribute(
method setAttributes (line 52) | void setAttributes(
method removeAttribute (line 64) | boolean removeAttribute(String groupPath, String attributePath) throws...
method removeAttribute (line 81) | <T> T removeAttribute(String groupPath, String attributePath, Class<T>...
method removeAttributes (line 96) | default boolean removeAttributes(final String groupPath, final List<St...
method setDatasetAttributes (line 113) | default void setDatasetAttributes(
method setVersion (line 128) | default void setVersion() throws N5Exception {
method createGroup (line 140) | void createGroup(String groupPath) throws N5Exception;
method remove (line 158) | boolean remove(String groupPath) throws N5Exception;
method remove (line 166) | default boolean remove() throws N5Exception {
method createDataset (line 182) | default DatasetAttributes createDataset(
method createDataset (line 206) | default DatasetAttributes createDataset(
method writeChunk (line 225) | <T> void writeChunk(
method writeChunks (line 239) | default <T> void writeChunks(
method writeBlock (line 267) | <T> void writeBlock(
type DataBlockSupplier (line 272) | @FunctionalInterface
method get (line 283) | DataBlock<T> get(long[] gridPos, DataBlock<T> existingDataBlock);
method writeRegion (line 295) | <T> void writeRegion(
method writeRegion (line 313) | <T> void writeRegion(
method deleteBlock (line 338) | default boolean deleteBlock(
method deleteBlock (line 362) | boolean deleteBlock(
method deleteChunk (line 378) | default boolean deleteChunk(
method deleteChunk (line 397) | boolean deleteChunk(
method deleteChunks (line 412) | default boolean deleteChunks(
method writeSerializedBlock (line 433) | default void writeSerializedBlock(
FILE: src/main/java/org/janelia/saalfeldlab/n5/NameConfigAdapter.java
class NameConfigAdapter (line 33) | public class NameConfigAdapter<T> implements JsonDeserializer<T>, JsonSe...
method registerAdapter (line 37) | private static <V> void registerAdapter(Class<V> cls) {
method getDeclaredFields (line 46) | private static ArrayList<Field> getDeclaredFields(Class<?> clazz) {
method update (line 55) | @SuppressWarnings("unchecked")
method NameConfigAdapter (line 108) | public NameConfigAdapter(Class<T> cls) {
method serialize (line 112) | @Override
method deserialize (line 156) | @Override
method reverseJsonArray (line 216) | private static JsonArray reverseJsonArray(JsonElement paramJson) {
method getJsonAdapter (line 225) | public static <T> NameConfigAdapter<T> getJsonAdapter(Class<T> cls) {
FILE: src/main/java/org/janelia/saalfeldlab/n5/RawCompression.java
class RawCompression (line 8) | @CompressionType("raw")
method equals (line 14) | @Override
method encode (line 20) | @Override
method decode (line 25) | @Override
method encodedSize (line 30) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/ReflectionUtils.java
class ReflectionUtils (line 6) | class ReflectionUtils {
method setFieldValue (line 8) | static <T> void setFieldValue(
FILE: src/main/java/org/janelia/saalfeldlab/n5/ShortArrayDataBlock.java
class ShortArrayDataBlock (line 3) | public class ShortArrayDataBlock extends AbstractDataBlock<short[]> {
method ShortArrayDataBlock (line 5) | public ShortArrayDataBlock(final int[] size, final long[] gridPosition...
FILE: src/main/java/org/janelia/saalfeldlab/n5/StringDataBlock.java
class StringDataBlock (line 7) | public class StringDataBlock extends AbstractDataBlock<String[]> {
method StringDataBlock (line 14) | public StringDataBlock(final int[] size, final long[] gridPosition, fi...
method StringDataBlock (line 19) | public StringDataBlock(final int[] size, final long[] gridPosition, fi...
method readData (line 24) | public void readData(final ByteBuffer buffer) {
method serialize (line 34) | protected byte[] serialize(String[] strings) {
method deserialize (line 39) | protected String[] deserialize(byte[] rawBytes) {
method getNumElements (line 44) | @Override
method getData (line 51) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/XzCompression.java
class XzCompression (line 11) | @CompressionType("xz")
method XzCompression (line 21) | public XzCompression(final int preset) {
method XzCompression (line 26) | public XzCompression() {
method equals (line 31) | @Override
method decode (line 40) | @Override
method encode (line 50) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/cache/N5JsonCache.java
class N5JsonCache (line 18) | public class N5JsonCache {
class N5CacheInfo (line 30) | protected static class N5CacheInfo {
method getCache (line 37) | public JsonElement getCache(final String normalCacheKey) {
method containsKey (line 45) | public boolean containsKey(final String normalCacheKey) {
method isDataset (line 53) | public boolean isDataset() {
method isGroup (line 58) | public boolean isGroup() {
class EmptyJson (line 64) | @SuppressWarnings("deprecation")
method deepCopy (line 67) | @Override
method N5JsonCache (line 77) | public N5JsonCache(final N5JsonCacheableContainer container) {
method getAttributes (line 82) | public JsonElement getAttributes(final String normalPathKey, final Str...
method isDataset (line 102) | public boolean isDataset(final String normalPathKey, final String norm...
method isGroup (line 112) | public boolean isGroup(final String normalPathKey, final String cacheK...
method exists (line 131) | public boolean exists(final String normalPathKey, final String normalC...
method list (line 141) | public String[] list(final String normalPathKey) {
method addNewCacheInfo (line 163) | public N5CacheInfo addNewCacheInfo(
method addNewCacheInfo (line 201) | private N5CacheInfo addNewCacheInfo(final String normalPathKey) {
method addChild (line 206) | private void addChild(final N5CacheInfo cacheInfo, final String normal...
method getOrMakeCacheInfo (line 215) | protected N5CacheInfo getOrMakeCacheInfo(final String normalPathKey) {
method updateCacheInfo (line 237) | public void updateCacheInfo(final String normalPathKey, final String n...
method updateCacheInfo (line 256) | public void updateCacheInfo(
method initializeNonemptyCache (line 277) | public void initializeNonemptyCache(final String normalPathKey, final ...
method setAttributes (line 289) | public void setAttributes(final String normalPathKey, final String nor...
method addChildIfPresent (line 317) | public void addChildIfPresent(final String parent, final String child) {
method addChild (line 336) | public void addChild(final String parent, final String child) {
method removeCache (line 348) | public void removeCache(final String normalParentPathKey, final String...
method getCacheInfo (line 367) | protected N5CacheInfo getCacheInfo(final String pathKey) {
method newCacheInfo (line 374) | protected N5CacheInfo newCacheInfo() {
method updateCache (line 379) | protected void updateCache(final String normalPathKey, final N5CacheIn...
method updateCacheAttributes (line 386) | protected void updateCacheAttributes(
method updateCacheIsGroup (line 396) | protected void updateCacheIsGroup(final N5CacheInfo cacheInfo, final b...
method updateCacheIsDataset (line 401) | protected void updateCacheIsDataset(final N5CacheInfo cacheInfo, final...
FILE: src/main/java/org/janelia/saalfeldlab/n5/cache/N5JsonCacheableContainer.java
type N5JsonCacheableContainer (line 17) | public interface N5JsonCacheableContainer {
method getAttributesFromContainer (line 30) | JsonElement getAttributesFromContainer(final String normalPathName, fi...
method existsFromContainer (line 41) | boolean existsFromContainer(final String normalPathName, final String ...
method isGroupFromContainer (line 50) | boolean isGroupFromContainer(final String normalPathName);
method isDatasetFromContainer (line 60) | boolean isDatasetFromContainer(final String normalPathName);
method isGroupFromAttributes (line 75) | boolean isGroupFromAttributes(final String normalCacheKey, final JsonE...
method isDatasetFromAttributes (line 89) | boolean isDatasetFromAttributes(final String normalCacheKey, final Jso...
method listFromContainer (line 99) | String[] listFromContainer(final String normalPathName);
FILE: src/main/java/org/janelia/saalfeldlab/n5/codec/BlockCodec.java
type BlockCodec (line 13) | public interface BlockCodec<T> {
method encode (line 33) | ReadData encode(DataBlock<T> dataBlock) throws N5IOException;
method decode (line 54) | DataBlock<T> decode(ReadData readData, long[] gridPosition) throws N5I...
method encodedSize (line 73) | default long encodedSize(int[] blockSize) throws UnsupportedOperationE...
FILE: src/main/java/org/janelia/saalfeldlab/n5/codec/BlockCodecInfo.java
type BlockCodecInfo (line 14) | public interface BlockCodecInfo extends CodecInfo, DeterministicSizeCode...
method getKeyPositionForBlock (line 16) | default long[] getKeyPositionForBlock(final DatasetAttributes attribut...
method getKeyPositionForBlock (line 21) | default long[] getKeyPositionForBlock(final DatasetAttributes attribut...
method encodedSize (line 26) | @Override default long encodedSize(long size) {
method decodedSize (line 31) | @Override default long decodedSize(long size) {
method create (line 36) | <T> BlockCodec<T> create(DataType dataType, int[] blockSize, DataCodec...
method create (line 38) | default <T> BlockCodec<T> create(final DatasetAttributes attributes, f...
FILE: src/main/java/org/janelia/saalfeldlab/n5/codec/CodecInfo.java
type CodecInfo (line 12) | @NameConfig.Prefix("codec")
method getType (line 15) | String getType();
FILE: src/main/java/org/janelia/saalfeldlab/n5/codec/CodecParser.java
class CodecParser (line 8) | public class CodecParser {
method CodecParser (line 14) | public CodecParser(CodecInfo[] codecs) {
method parse (line 19) | private void parse(CodecInfo[] codecs) {
method concatenateCodecs (line 54) | private static CodecInfo[] concatenateCodecs(DatasetAttributes attribu...
FILE: src/main/java/org/janelia/saalfeldlab/n5/codec/ConcatenatedDataCodec.java
class ConcatenatedDataCodec (line 5) | class ConcatenatedDataCodec implements DataCodec {
method ConcatenatedDataCodec (line 9) | ConcatenatedDataCodec(final DataCodec[] codecs) {
method encode (line 17) | @Override
method decode (line 26) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/codec/ConcatenatedDeterministicSizeDataCodec.java
class ConcatenatedDeterministicSizeDataCodec (line 3) | class ConcatenatedDeterministicSizeDataCodec extends ConcatenatedDataCod...
method ConcatenatedDeterministicSizeDataCodec (line 7) | ConcatenatedDeterministicSizeDataCodec(final DeterministicSizeDataCode...
method encodedSize (line 13) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/codec/DataCodec.java
type DataCodec (line 11) | public interface DataCodec {
method decode (line 28) | ReadData decode(ReadData readData) throws N5IOException;
method encode (line 44) | ReadData encode(ReadData readData) throws N5IOException;
method concatenate (line 57) | static DataCodec concatenate(final DataCodec... codecs) {
method create (line 71) | static DataCodec create(final DataCodecInfo... codecInfos) {
FILE: src/main/java/org/janelia/saalfeldlab/n5/codec/DataCodecInfo.java
type DataCodecInfo (line 10) | @NameConfig.Prefix("data-codec")
method create (line 13) | DataCodec create();
FILE: src/main/java/org/janelia/saalfeldlab/n5/codec/DatasetCodec.java
type DatasetCodec (line 15) | public interface DatasetCodec<S, T> {
method encode (line 21) | DataBlock<T> encode(DataBlock<S> block) throws N5IOException;
method decode (line 23) | DataBlock<S> decode(DataBlock<T> dataBlock) throws N5IOException;
method concatenate (line 40) | static <S, T> BlockCodec<S> concatenate(final DatasetCodec<S, T> datas...
FILE: src/main/java/org/janelia/saalfeldlab/n5/codec/DatasetCodecInfo.java
type DatasetCodecInfo (line 12) | @NameConfig.Prefix("data-codec") // TODO: is this Prefix correct?
method create (line 15) | DatasetCodec<?, ?> create(final DatasetAttributes attributes);
FILE: src/main/java/org/janelia/saalfeldlab/n5/codec/DeterministicSizeCodecInfo.java
type DeterministicSizeCodecInfo (line 8) | public interface DeterministicSizeCodecInfo extends CodecInfo {
method encodedSize (line 10) | long encodedSize(long size);
method decodedSize (line 12) | long decodedSize(long size);
FILE: src/main/java/org/janelia/saalfeldlab/n5/codec/DeterministicSizeDataCodec.java
type DeterministicSizeDataCodec (line 7) | public interface DeterministicSizeDataCodec extends DataCodec {
method encodedSize (line 16) | long encodedSize(long size);
method concatenate (line 27) | static DeterministicSizeDataCodec concatenate(final DeterministicSizeD...
FILE: src/main/java/org/janelia/saalfeldlab/n5/codec/FlatArrayCodec.java
class FlatArrayCodec (line 28) | public abstract class FlatArrayCodec<T> {
method encode (line 30) | public abstract ReadData encode(T data) throws N5IOException;
method decode (line 32) | public abstract T decode(ReadData readData, int numElements) throws N5...
method bytesPerElement (line 34) | public int bytesPerElement() {
method newArray (line 38) | public T newArray(final int numElements) {
method SHORT (line 62) | public static FlatArrayCodec<short[]> SHORT(ByteOrder order) {
method INT (line 66) | public static FlatArrayCodec<int[]> INT(ByteOrder order) {
method LONG (line 70) | public static FlatArrayCodec<long[]> LONG(ByteOrder order) {
method FLOAT (line 74) | public static FlatArrayCodec<float[]> FLOAT(ByteOrder order) {
method DOUBLE (line 78) | public static FlatArrayCodec<double[]> DOUBLE(ByteOrder order) {
method FlatArrayCodec (line 88) | private FlatArrayCodec(int bytesPerElement, IntFunction<T> dataFactory) {
class ByteArrayCodec (line 93) | private static final class ByteArrayCodec extends FlatArrayCodec<byte[...
method ByteArrayCodec (line 95) | private ByteArrayCodec() {
method encode (line 99) | @Override
method decode (line 104) | @Override
class ShortArrayCodec (line 116) | private static final class ShortArrayCodec extends FlatArrayCodec<shor...
method ShortArrayCodec (line 120) | ShortArrayCodec(ByteOrder order) {
method encode (line 125) | @Override
method decode (line 132) | @Override
class IntArrayCodec (line 140) | private static final class IntArrayCodec extends FlatArrayCodec<int[]> {
method IntArrayCodec (line 144) | IntArrayCodec(ByteOrder order) {
method encode (line 149) | @Override
method decode (line 156) | @Override
class LongArrayCodec (line 166) | private static final class LongArrayCodec extends FlatArrayCodec<long[...
method LongArrayCodec (line 170) | LongArrayCodec(ByteOrder order) {
method encode (line 175) | @Override
method decode (line 182) | @Override
class FloatArrayCodec (line 190) | private static final class FloatArrayCodec extends FlatArrayCodec<floa...
method FloatArrayCodec (line 194) | FloatArrayCodec(ByteOrder order) {
method encode (line 199) | @Override
method decode (line 206) | @Override
class DoubleArrayCodec (line 214) | private static final class DoubleArrayCodec extends FlatArrayCodec<dou...
method DoubleArrayCodec (line 218) | DoubleArrayCodec(ByteOrder order) {
method encode (line 223) | @Override
method decode (line 230) | @Override
class N5StringArrayCodec (line 238) | private static final class N5StringArrayCodec extends FlatArrayCodec<S...
method N5StringArrayCodec (line 243) | N5StringArrayCodec() {
method encode (line 247) | @Override
method decode (line 253) | @Override
class ZarrStringArrayCodec (line 261) | private static final class ZarrStringArrayCodec extends FlatArrayCodec...
method ZarrStringArrayCodec (line 265) | ZarrStringArrayCodec() {
method encode (line 269) | @Override
method decode (line 285) | @Override
class ObjectArrayCodec (line 309) | private static final class ObjectArrayCodec extends FlatArrayCodec<byt...
method ObjectArrayCodec (line 311) | ObjectArrayCodec() {
method encode (line 315) | @Override
method decode (line 320) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/codec/IdentityCodec.java
class IdentityCodec (line 6) | @NameConfig.Name(IdentityCodec.TYPE)
method getType (line 13) | @Override
method decode (line 19) | @Override
method encode (line 25) | @Override
method create (line 31) | @Override public DataCodec create() {
method encodedSize (line 36) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/codec/IndexCodecAdapter.java
class IndexCodecAdapter (line 3) | public class IndexCodecAdapter {
method IndexCodecAdapter (line 8) | public IndexCodecAdapter(final BlockCodecInfo blockCodecInfo, final De...
method getBlockCodecInfo (line 14) | public BlockCodecInfo getBlockCodecInfo() {
method getDataCodecs (line 19) | public DataCodecInfo[] getDataCodecs() {
method encodedSize (line 26) | public long encodedSize(long initialSize) {
method create (line 34) | public static IndexCodecAdapter create(final CodecInfo... codecs) {
FILE: src/main/java/org/janelia/saalfeldlab/n5/codec/N5BlockCodecInfo.java
class N5BlockCodecInfo (line 8) | @NameConfig.Name(value = N5BlockCodecInfo.TYPE)
method getKeyPositionForBlock (line 17) | @Override public long[] getKeyPositionForBlock(DatasetAttributes attri...
method getKeyPositionForBlock (line 22) | @Override public long[] getKeyPositionForBlock(DatasetAttributes attri...
method encodedSize (line 27) | @Override public long encodedSize(long size) {
method getType (line 34) | @Override
method create (line 40) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/codec/N5BlockCodecs.java
class N5BlockCodecs (line 28) | public class N5BlockCodecs {
method N5BlockCodecs (line 39) | private N5BlockCodecs() {}
method create (line 41) | public static <T> BlockCodec<T> create(
type BlockCodecFactory (line 83) | private interface BlockCodecFactory<T> {
method create (line 91) | BlockCodec<T> create(DataCodec dataCodec);
class N5AbstractBlockCodec (line 94) | abstract static class N5AbstractBlockCodec<T> implements BlockCodec<T> {
method N5AbstractBlockCodec (line 100) | N5AbstractBlockCodec(FlatArrayCodec<T> dataCodec, DataBlockFactory<T...
method createBlockHeader (line 106) | abstract BlockHeader createBlockHeader(final DataBlock<T> dataBlock,...
method encode (line 108) | @Override
method decodeBlockHeader (line 120) | abstract BlockHeader decodeBlockHeader(final InputStream in) throws ...
method decode (line 122) | @Override
class DefaultBlockCodec (line 150) | private static class DefaultBlockCodec<T> extends N5AbstractBlockCodec...
method DefaultBlockCodec (line 152) | DefaultBlockCodec(
method createBlockHeader (line 160) | @Override
method decodeBlockHeader (line 166) | @Override
method encodedSize (line 172) | @Override
class StringBlockCodec (line 188) | private static class StringBlockCodec extends N5AbstractBlockCodec<Str...
method StringBlockCodec (line 190) | StringBlockCodec(final DataCodec codec) {
method createBlockHeader (line 195) | @Override
method decodeBlockHeader (line 201) | @Override
class ObjectBlockCodec (line 211) | private static class ObjectBlockCodec extends N5AbstractBlockCodec<byt...
method ObjectBlockCodec (line 213) | ObjectBlockCodec(final DataCodec codec) {
method createBlockHeader (line 218) | @Override
method decodeBlockHeader (line 224) | @Override
class BlockHeader (line 231) | static class BlockHeader {
method BlockHeader (line 241) | BlockHeader(final short mode, final int[] blockSize, final int numEl...
method BlockHeader (line 248) | BlockHeader(final int[] blockSize, final int numElements) {
method getSize (line 261) | public int getSize() {
method blockSize (line 266) | public int[] blockSize() {
method numElements (line 271) | public int numElements() {
method readBlockSize (line 276) | private static int[] readBlockSize(final DataInputStream dis) throws...
method writeBlockSize (line 289) | private static void writeBlockSize(final int[] blockSize, final Data...
method headerSizeInBytes (line 300) | static int headerSizeInBytes(final short mode, final int numDimensio...
method writeTo (line 319) | void writeTo(final OutputStream out) throws N5IOException {
method readFrom (line 345) | static BlockHeader readFrom(final InputStream in, short... allowedMo...
FILE: src/main/java/org/janelia/saalfeldlab/n5/codec/RawBlockCodecInfo.java
class RawBlockCodecInfo (line 15) | @NameConfig.Name(value = RawBlockCodecInfo.TYPE)
method RawBlockCodecInfo (line 25) | public RawBlockCodecInfo() {
method RawBlockCodecInfo (line 30) | public RawBlockCodecInfo(final ByteOrder byteOrder) {
method getType (line 35) | @Override
method getByteOrder (line 41) | public ByteOrder getByteOrder() {
method create (line 45) | @Override
method ensureValidByteOrder (line 51) | public static void ensureValidByteOrder(final DataType dataType, final...
class ByteOrderAdapter (line 67) | public static class ByteOrderAdapter implements JsonDeserializer<ByteO...
method serialize (line 69) | @Override
method deserialize (line 79) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/codec/RawBlockCodecs.java
class RawBlockCodecs (line 16) | public class RawBlockCodecs {
method RawBlockCodecs (line 27) | private RawBlockCodecs() {}
method create (line 29) | public static <T> BlockCodec<T> create(
type BlockCodecFactory (line 69) | private interface BlockCodecFactory<T> {
method create (line 78) | BlockCodec<T> create(ByteOrder byteOrder, int[] blockSize, DataCodec...
class RawBlockCodec (line 81) | private static class RawBlockCodec<T> implements BlockCodec<T> {
method RawBlockCodec (line 89) | RawBlockCodec(
method encode (line 102) | @Override
method decode (line 111) | @Override
method encodedSize (line 119) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/codec/checksum/ChecksumCodec.java
class ChecksumCodec (line 29) | public abstract class ChecksumCodec implements DataCodec, DataCodecInfo,...
method ChecksumCodec (line 37) | public ChecksumCodec(Supplier<Checksum> checksumSupplier, int numCheck...
method getChecksum (line 48) | public Checksum getChecksum() {
method numChecksumBytes (line 53) | public int numChecksumBytes() {
method createStream (line 58) | private CheckedOutputStream createStream(OutputStream out) {
method encode (line 74) | @Override public ReadData encode(ReadData readData) {
method decode (line 79) | @Override public ReadData decode(ReadData readData) throws N5IOExcepti...
method encodedSize (line 97) | @Override
method readChecksum (line 103) | protected long readChecksum(ReadData checksumData) {
method computeChecksum (line 115) | protected long computeChecksum(ReadData data) {
method getChecksumValue (line 126) | public abstract ByteBuffer getChecksumValue(Checksum checksum);
method writeChecksum (line 128) | protected void writeChecksum(Checksum checksum, OutputStream out) thro...
FILE: src/main/java/org/janelia/saalfeldlab/n5/codec/checksum/ChecksumException.java
class ChecksumException (line 3) | public class ChecksumException extends Exception {
method ChecksumException (line 7) | public ChecksumException(final String message) {
FILE: src/main/java/org/janelia/saalfeldlab/n5/codec/checksum/Crc32cChecksumCodec.java
class Crc32cChecksumCodec (line 11) | @NameConfig.Name(Crc32cChecksumCodec.TYPE)
method Crc32cChecksumCodec (line 18) | public Crc32cChecksumCodec() {
method getChecksumValue (line 23) | @Override
method getType (line 31) | @Override
method create (line 37) | @Override public DataCodec create() {
FILE: src/main/java/org/janelia/saalfeldlab/n5/codec/transpose/Transpose.java
class Transpose (line 6) | class Transpose<T> {
method encode (line 11) | public static int[] encode(final int[] decodedPos, final int[] order) {
method decode (line 17) | public static int[] decode(final int[] encodedPos, final int[] order) {
method encode (line 23) | public static void encode(int[] decodedPos, int[] order, int[] encoded...
method decode (line 28) | public static void decode(int[] encodedPos, int[] order, int[] decoded...
method of (line 33) | @SuppressWarnings("unchecked")
method Transpose (line 46) | Transpose(final MemCopy<T> memCopy, final int n) {
method encode (line 55) | public void encode(final T decoded, final T encoded, final int[] decod...
method decode (line 78) | public void decode(final T encoded, final T decoded, final int[] decod...
method copyRecursively (line 98) | private void copyRecursively(final T src, final int srcPos, final T de...
method newInstance (line 112) | Transpose<T> newInstance() {
FILE: src/main/java/org/janelia/saalfeldlab/n5/codec/transpose/TransposeCodec.java
class TransposeCodec (line 7) | public class TransposeCodec<T> implements DatasetCodec<T, T> {
method TransposeCodec (line 14) | public TransposeCodec(final DataType dataType, final int[] order) {
method encode (line 21) | @Override
method decode (line 29) | @Override
method isIdentity (line 37) | public static boolean isIdentity(final int[] permutation) {
method isReversal (line 46) | public static boolean isReversal(final int[] permutation) {
method invertPermutation (line 55) | public static int[] invertPermutation(final int[] p) {
method concatenatePermutations (line 73) | public static int[] concatenatePermutations(final int[] first, final i...
method conjugateWithReverse (line 91) | public static int[] conjugateWithReverse(final int[] p) {
FILE: src/main/java/org/janelia/saalfeldlab/n5/codec/transpose/TransposeCodecInfo.java
class TransposeCodecInfo (line 24) | @NameConfig.Name(value = TransposeCodecInfo.TYPE)
method TransposeCodecInfo (line 32) | public TransposeCodecInfo() {
method TransposeCodecInfo (line 36) | public TransposeCodecInfo(int[] order) {
method getType (line 41) | @Override
method getOrder (line 47) | public int[] getOrder() {
method create (line 52) | @Override
method equals (line 59) | @Override
method validate (line 68) | private void validate() {
method concatenate (line 80) | public static TransposeCodecInfo concatenate(TransposeCodecInfo[] info...
FILE: src/main/java/org/janelia/saalfeldlab/n5/http/ApacheListResponseParser.java
class ApacheListResponseParser (line 8) | abstract class ApacheListResponseParser extends PatternListResponseParser {
method ApacheListResponseParser (line 14) | ApacheListResponseParser(Pattern pattern) {
class ListDirectories (line 19) | static class ListDirectories extends ApacheListResponseParser {
method ListDirectories (line 21) | public ListDirectories() {
class ListAll (line 27) | static class ListAll extends ApacheListResponseParser {
method ListAll (line 29) | public ListAll() {
method directoryParser (line 35) | public static ListResponseParser directoryParser() {
method parser (line 40) | public static ListResponseParser parser() {
FILE: src/main/java/org/janelia/saalfeldlab/n5/http/CandidateListResponseParser.java
class CandidateListResponseParser (line 3) | class CandidateListResponseParser implements ListResponseParser {
method CandidateListResponseParser (line 9) | CandidateListResponseParser(ListResponseParser[] candidateParsers) {
method parseListResponse (line 14) | @Override
method successfulParser (line 33) | public ListResponseParser successfulParser() {
FILE: src/main/java/org/janelia/saalfeldlab/n5/http/ListResponseParser.java
type ListResponseParser (line 3) | public interface ListResponseParser {
method parseListResponse (line 13) | String[] parseListResponse(final String response);
method defaultListParser (line 15) | public static ListResponseParser defaultListParser() {
method defaultDirectoryListParser (line 25) | public static ListResponseParser defaultDirectoryListParser() {
FILE: src/main/java/org/janelia/saalfeldlab/n5/http/MicrosoftListResponseParser.java
class MicrosoftListResponseParser (line 8) | abstract class MicrosoftListResponseParser extends PatternListResponsePa...
method MicrosoftListResponseParser (line 14) | MicrosoftListResponseParser(Pattern pattern) {
class ListDirectories (line 19) | static class ListDirectories extends MicrosoftListResponseParser {
method ListDirectories (line 21) | public ListDirectories() {
class ListAll (line 27) | static class ListAll extends MicrosoftListResponseParser {
method ListAll (line 29) | public ListAll() {
method directoryParser (line 35) | public static ListResponseParser directoryParser() {
method parser (line 40) | public static ListResponseParser parser() {
FILE: src/main/java/org/janelia/saalfeldlab/n5/http/PatternListResponseParser.java
class PatternListResponseParser (line 14) | class PatternListResponseParser implements ListResponseParser {
method PatternListResponseParser (line 18) | public PatternListResponseParser(Pattern pattern) {
method parseListResponse (line 23) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/http/PythonListResponseParser.java
class PythonListResponseParser (line 8) | abstract class PythonListResponseParser extends PatternListResponseParser {
method PythonListResponseParser (line 14) | PythonListResponseParser(Pattern pattern) {
class ListDirectories (line 19) | static class ListDirectories extends PythonListResponseParser {
method ListDirectories (line 21) | public ListDirectories() {
class ListAll (line 27) | static class ListAll extends PythonListResponseParser {
method ListAll (line 29) | public ListAll() {
method directoryParser (line 35) | public static ListResponseParser directoryParser() {
method parser (line 40) | public static ListResponseParser parser() {
FILE: src/main/java/org/janelia/saalfeldlab/n5/readdata/ByteArrayReadData.java
class ByteArrayReadData (line 7) | class ByteArrayReadData implements ReadData {
method ByteArrayReadData (line 15) | ByteArrayReadData(final byte[] data) {
method ByteArrayReadData (line 20) | ByteArrayReadData(final byte[] data, final int offset, final int lengt...
method length (line 35) | @Override
method requireLength (line 40) | @Override
method inputStream (line 45) | @Override
method allBytes (line 51) | @Override
method materialize (line 61) | @Override
method slice (line 66) | @Override
method validBounds (line 73) | private static boolean validBounds(int arrayLength, int offset, int le...
FILE: src/main/java/org/janelia/saalfeldlab/n5/readdata/InputStreamReadData.java
class InputStreamReadData (line 10) | class InputStreamReadData implements ReadData {
method InputStreamReadData (line 15) | InputStreamReadData(final InputStream inputStream, final int length) {
method length (line 20) | @Override
method requireLength (line 25) | @Override
method slice (line 35) | @Override
method limit (line 41) | @Override
method inputStream (line 48) | @Override
method allBytes (line 60) | @Override
method materialize (line 68) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/readdata/LazyGeneratedReadData.java
class LazyGeneratedReadData (line 11) | class LazyGeneratedReadData implements ReadData {
method LazyGeneratedReadData (line 13) | LazyGeneratedReadData(final ReadData.Generator generator) {
method LazyGeneratedReadData (line 26) | LazyGeneratedReadData(final ReadData data, final OutputStreamOperator ...
method materialize (line 40) | @Override
method length (line 54) | @Override
method requireLength (line 59) | @Override
method slice (line 69) | @Override
method inputStream (line 75) | @Override
method allBytes (line 81) | @Override
method writeTo (line 87) | @Override
method close (line 108) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/readdata/LazyRead.java
type LazyRead (line 15) | public interface LazyRead extends Closeable {
method materialize (line 37) | ReadData materialize(long offset, long length) throws N5IOException;
method size (line 47) | long size() throws N5IOException;
method prefetch (line 60) | default void prefetch(final Collection<? extends Range> ranges) throws...
FILE: src/main/java/org/janelia/saalfeldlab/n5/readdata/LazyReadData.java
class LazyReadData (line 13) | class LazyReadData implements VolatileReadData {
method LazyReadData (line 20) | LazyReadData(final LazyRead lazyRead) {
method LazyReadData (line 24) | private LazyReadData(final LazyRead lazyRead, final long offset, final...
method materialize (line 30) | @Override
method slice (line 51) | @Override
method inputStream (line 70) | @Override
method allBytes (line 76) | @Override
method length (line 82) | @Override
method requireLength (line 87) | @Override
method prefetch (line 95) | @Override
method close (line 100) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/readdata/Range.java
type Range (line 10) | public interface Range {
method offset (line 23) | long offset();
method length (line 28) | long length();
method end (line 33) | default long end() {
method equals (line 37) | static boolean equals(final Range r0, final Range r1) {
method at (line 47) | static Range at(final long offset, final long length) {
method aggregate (line 109) | static Collection<? extends Range> aggregate(final Collection<? extend...
FILE: src/main/java/org/janelia/saalfeldlab/n5/readdata/ReadData.java
type ReadData (line 30) | public interface ReadData {
method length (line 38) | default long length() {
method requireLength (line 53) | long requireLength() throws N5IOException;
method limit (line 64) | default ReadData limit(final long length) throws N5IOException {
method slice (line 77) | default ReadData slice(final long offset, final long length) throws N5...
method slice (line 89) | default ReadData slice(final Range range) throws N5IOException {
method inputStream (line 109) | InputStream inputStream() throws N5IOException, IllegalStateException;
method allBytes (line 128) | byte[] allBytes() throws N5IOException, IllegalStateException;
method toByteBuffer (line 148) | default ByteBuffer toByteBuffer() throws N5IOException, IllegalStateEx...
method materialize (line 170) | ReadData materialize() throws N5IOException;
method writeTo (line 190) | default void writeTo(OutputStream outputStream) throws N5IOException, ...
method prefetch (line 209) | default void prefetch(final Collection<? extends Range> ranges) throws...
method encode (line 224) | default ReadData encode(OutputStreamOperator encoder) {
type OutputStreamOperator (line 236) | @FunctionalInterface
method apply (line 239) | OutputStream apply(OutputStream o) throws IOException;
method from (line 260) | static ReadData from(final InputStream inputStream, final int length) {
method from (line 273) | static ReadData from(final InputStream inputStream) {
method from (line 290) | static ReadData from(final byte[] data, final int offset, final int le...
method from (line 302) | static ReadData from(final byte[] data) {
method from (line 314) | static ReadData from(final ByteBuffer data) {
type Generator (line 329) | @FunctionalInterface
method writeTo (line 331) | void writeTo(OutputStream outputStream) throws IOException, IllegalS...
method from (line 342) | static ReadData from(Generator generator) {
method empty (line 351) | static ReadData empty() {
FILE: src/main/java/org/janelia/saalfeldlab/n5/readdata/VolatileReadData.java
type VolatileReadData (line 16) | public interface VolatileReadData extends ReadData, AutoCloseable {
method close (line 18) | @Override
method from (line 31) | static VolatileReadData from(final LazyRead lazyRead) {
FILE: src/main/java/org/janelia/saalfeldlab/n5/readdata/prefetch/AggregatingPrefetchLazyRead.java
class AggregatingPrefetchLazyRead (line 16) | public class AggregatingPrefetchLazyRead extends SliceTrackingLazyRead {
method AggregatingPrefetchLazyRead (line 18) | public AggregatingPrefetchLazyRead(final LazyRead delegate) {
method prefetch (line 33) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/readdata/prefetch/EnclosingPrefetchLazyRead.java
class EnclosingPrefetchLazyRead (line 12) | public class EnclosingPrefetchLazyRead extends SliceTrackingLazyRead {
method EnclosingPrefetchLazyRead (line 14) | public EnclosingPrefetchLazyRead(final LazyRead delegate) {
method prefetch (line 33) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/readdata/prefetch/SliceTrackingLazyRead.java
class SliceTrackingLazyRead (line 20) | public class SliceTrackingLazyRead implements LazyRead {
class Slice (line 22) | protected static class Slice implements Range {
method Slice (line 31) | Slice(final long offset, final long length, final ReadData data) {
method offset (line 37) | @Override
method length (line 42) | @Override
method toString (line 47) | @Override
method SliceTrackingLazyRead (line 60) | public SliceTrackingLazyRead(final LazyRead delegate) {
method close (line 64) | @Override
method materialize (line 69) | @Override
method size (line 81) | @Override
method isCovered (line 86) | protected boolean isCovered(final Range slice) {
FILE: src/main/java/org/janelia/saalfeldlab/n5/readdata/prefetch/Slices.java
class Slices (line 8) | class Slices {
method Slices (line 10) | private Slices() {
method findContainingSlice (line 33) | static <T extends Range> T findContainingSlice(final List<T> slices, f...
method findContainingSlice (line 71) | static <T extends Range> T findContainingSlice(final List<T> slices, f...
method addSlice (line 97) | static <T extends Range> void addSlice(final List<T> slices, final T s...
FILE: src/main/java/org/janelia/saalfeldlab/n5/readdata/segment/ConcatenatedReadData.java
class ConcatenatedReadData (line 29) | class ConcatenatedReadData implements SegmentedReadData {
method ConcatenatedReadData (line 39) | ConcatenatedReadData(final List<SegmentedReadData> content) {
method ConcatenatedReadData (line 50) | private ConcatenatedReadData(final ReadData delegate, final List<Segme...
method ensureKnownSize (line 69) | private void ensureKnownSize() throws IllegalStateException {
method location (line 94) | @Override
method segments (line 104) | @Override
method length (line 109) | @Override
method requireLength (line 125) | @Override
method slice (line 136) | @Override
method slice (line 143) | @Override
method inputStream (line 175) | @Override
method allBytes (line 180) | @Override
method toByteBuffer (line 185) | @Override
method materialize (line 190) | @Override
method writeTo (line 196) | @Override
method encode (line 201) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/readdata/segment/DefaultSegmentedReadData.java
class DefaultSegmentedReadData (line 23) | class DefaultSegmentedReadData implements SegmentedReadData {
class SegmentImpl (line 48) | private static class SegmentImpl implements Segment, Range {
method SegmentImpl (line 54) | public SegmentImpl(final SegmentedReadData source, final Range locat...
method SegmentImpl (line 58) | public SegmentImpl(final SegmentedReadData source, final long offset...
method offset (line 64) | @Override
method length (line 69) | @Override
method source (line 74) | @Override
class EnclosingSegmentImpl (line 80) | private static class EnclosingSegmentImpl extends SegmentImpl {
method EnclosingSegmentImpl (line 82) | public EnclosingSegmentImpl(final SegmentedReadData source) {
method length (line 86) | @Override
method DefaultSegmentedReadData (line 93) | private DefaultSegmentedReadData(final ReadData delegate, final ReadDa...
method DefaultSegmentedReadData (line 101) | private DefaultSegmentedReadData(final ReadData delegate, final List<S...
method wrap (line 114) | static SegmentsAndData wrap(final ReadData readData, final List<Range>...
method DefaultSegmentedReadData (line 140) | DefaultSegmentedReadData(final ReadData delegate) {
method location (line 147) | @Override
method segments (line 157) | @Override
method length (line 162) | @Override
method requireLength (line 167) | @Override
method slice (line 172) | @Override
method slice (line 189) | @Override
method inputStream (line 237) | @Override
method allBytes (line 242) | @Override
method toByteBuffer (line 247) | @Override
method materialize (line 252) | @Override
method writeTo (line 258) | @Override
method prefetch (line 263) | @Override
method encode (line 279) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/readdata/segment/Segment.java
type Segment (line 6) | public interface Segment {
method source (line 20) | SegmentedReadData source();
FILE: src/main/java/org/janelia/saalfeldlab/n5/readdata/segment/SegmentedReadData.java
type SegmentedReadData (line 19) | public interface SegmentedReadData extends ReadData {
type SegmentsAndData (line 21) | interface SegmentsAndData {
method segments (line 22) | List<Segment> segments();
method data (line 23) | SegmentedReadData data();
method wrap (line 36) | static SegmentedReadData wrap(ReadData readData) {
method wrap (line 53) | static SegmentsAndData wrap(ReadData readData, Range... locations) {
method wrap (line 70) | static SegmentsAndData wrap(ReadData readData, List<Range> locations) {
method concatenate (line 91) | static SegmentedReadData concatenate(List<SegmentedReadData> readDatas) {
method location (line 113) | Range location(Segment segment) throws IllegalArgumentException;
method segments (line 121) | List<? extends Segment> segments();
method limit (line 123) | @Override
method slice (line 141) | SegmentedReadData slice(Segment segment) throws IllegalArgumentExcepti...
method slice (line 155) | @Override
method slice (line 169) | @Override
method materialize (line 174) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/serialization/JsonArrayUtils.java
class JsonArrayUtils (line 6) | public class JsonArrayUtils {
method reverse (line 14) | public static void reverse(final JsonArray array) {
FILE: src/main/java/org/janelia/saalfeldlab/n5/serialization/N5Annotations.java
type N5Annotations (line 19) | public interface N5Annotations extends Serializable {
FILE: src/main/java/org/janelia/saalfeldlab/n5/serialization/NameConfig.java
type NameConfig (line 30) | public interface NameConfig extends Serializable {
method getType (line 120) | default String getType() {
FILE: src/main/java/org/janelia/saalfeldlab/n5/shard/DatasetAccess.java
type DatasetAccess (line 19) | public interface DatasetAccess<T> {
method readChunk (line 38) | DataBlock<T> readChunk(PositionValueAccess pva, long[] gridPosition) t...
method readChunks (line 61) | List<DataBlock<T>> readChunks(PositionValueAccess pva, List<long[]> gr...
method writeChunk (line 67) | void writeChunk(PositionValueAccess pva, DataBlock<T> chunk) throws N5...
method writeChunks (line 73) | void writeChunks(PositionValueAccess pva, List<DataBlock<T>> chunks) t...
method deleteChunk (line 80) | boolean deleteChunk(PositionValueAccess pva, long[] gridPosition) thro...
method deleteChunks (line 87) | boolean deleteChunks(PositionValueAccess pva, List<long[]> gridPositio...
method writeRegion (line 102) | void writeRegion(
method writeRegion (line 128) | void writeRegion(
method readBlock (line 155) | DataBlock<T> readBlock(PositionValueAccess pva, long[] shardGridPositi...
method writeBlock (line 175) | void writeBlock(PositionValueAccess pva, DataBlock<T> dataBlock, int l...
method getGrid (line 177) | NestedGrid getGrid();
FILE: src/main/java/org/janelia/saalfeldlab/n5/shard/DefaultDatasetAccess.java
class DefaultDatasetAccess (line 32) | public class DefaultDatasetAccess<T> implements DatasetAccess<T> {
method DefaultDatasetAccess (line 37) | public DefaultDatasetAccess(final NestedGrid grid, final BlockCodec<?>...
method getGrid (line 42) | public NestedGrid getGrid() {
method readChunk (line 46) | @Override
method readChunkRecursive (line 56) | private DataBlock<T> readChunkRecursive(
method readChunks (line 74) | @Override
method readChunksRecursive (line 108) | private void readChunksRecursive(
method writeChunk (line 154) | @Override
method writeChunkRecursive (line 175) | private ReadData writeChunkRecursive(
method writeChunks (line 199) | @Override
method writeChunksRecursive (line 233) | private ReadData writeChunksRecursive(
method writeRegion (line 269) | @Override
method writeRegion (line 296) | @Override
method writeRegionRecursive (line 325) | private ReadData writeRegionRecursive(
method deleteChunk (line 384) | @Override
method deleteChunkRecursive (line 417) | private ReadData deleteChunkRecursive(
method deleteChunks (line 458) | @Override
method deleteChunksRecursive (line 514) | private ReadData deleteChunksRecursive(
method readBlock (line 620) | @Override
method readBlockInternal (line 643) | private DataBlock<T> readBlockInternal(
method writeBlock (line 703) | @Override
method getRawShard (line 778) | private RawShard getRawShard(
class ChunkRequest (line 811) | private static final class ChunkRequest<T> {
method ChunkRequest (line 818) | ChunkRequest(final NestedPosition position, final int index) {
method ChunkRequest (line 825) | ChunkRequest(final NestedPosition position, final DataBlock<T> chunk) {
method toString (line 831) | @Override
class ChunkRequests (line 852) | private static final class ChunkRequests<T> implements Iterable<ChunkR...
method ChunkRequests (line 858) | private ChunkRequests(final List<ChunkRequest<T>> requests, final in...
method removeDuplicates (line 875) | public List<ChunkRequest<T>> removeDuplicates() {
method iterator (line 894) | @Override
method level (line 908) | public int level() {
method gridPosition (line 916) | public long[] gridPosition() {
method relativeGridPosition (line 924) | public long[] relativeGridPosition() {
method position (line 928) | private NestedPosition position() {
method split (line 937) | public List<ChunkRequests<T>> split() {
method coversShard (line 964) | public boolean coversShard() {
method chunks (line 982) | public List<DataBlock<T>> chunks(final List<ChunkRequest<T>> duplica...
method createReadRequests (line 1006) | private ChunkRequests<T> createReadRequests(final List<long[]> gridPos...
method createWriteRequests (line 1027) | private ChunkRequests<T> createWriteRequests(final List<DataBlock<T>> ...
type DataBlockFactory (line 1045) | private interface DataBlockFactory<T> {
method createDataBlock (line 1047) | DataBlock<T> createDataBlock(final int[] blockSize, final long[] gri...
method of (line 1049) | @SuppressWarnings("unchecked")
FILE: src/main/java/org/janelia/saalfeldlab/n5/shard/DefaultShardCodecInfo.java
class DefaultShardCodecInfo (line 19) | @NameConfig.Name(value = "sharding_indexed")
method getType (line 22) | @Override
method DefaultShardCodecInfo (line 50) | DefaultShardCodecInfo() {
method DefaultShardCodecInfo (line 55) | public DefaultShardCodecInfo(
method DefaultShardCodecInfo (line 76) | public DefaultShardCodecInfo(
method build (line 93) | private void build() {
method getInnerBlockSize (line 119) | @Override
method getInnerDatasetCodecInfos (line 124) | @Override
method getInnerBlockCodecInfo (line 129) | @Override
method getInnerDataCodecInfos (line 134) | @Override
method getIndexBlockCodecInfo (line 139) | @Override
method getIndexDataCodecInfos (line 144) | @Override
method getIndexLocation (line 149) | @Override
method getCodecs (line 154) | public CodecInfo[] getCodecs() {
method getIndexCodecs (line 158) | public CodecInfo[] getIndexCodecs() {
method create (line 162) | @Override
method concatenateCodecs (line 181) | private static CodecInfo[] concatenateCodecs(BlockCodecInfo blkInfo, D...
FILE: src/main/java/org/janelia/saalfeldlab/n5/shard/Nesting.java
class Nesting (line 40) | public class Nesting {
class NestedPosition (line 46) | public static class NestedPosition implements Comparable<NestedPositio...
method NestedPosition (line 52) | protected NestedPosition(final NestedGrid grid, final long[] positio...
method level (line 67) | public int level() {
method numDimensions (line 71) | public int numDimensions() {
method relative (line 84) | public long[] relative(final int level) {
method relative (line 95) | public long[] relative() {
method absolute (line 107) | public long[] absolute(final int level) {
method key (line 111) | public long[] key() {
method pixelPosition (line 115) | public long[] pixelPosition() {
method maxPixelPosition (line 119) | public long[] maxPixelPosition() {
method toString (line 123) | @Override
method compareTo (line 141) | @Override
method equals (line 172) | @Override
method hashCode (line 185) | @Override
class NestedGrid (line 205) | public static class NestedGrid {
method NestedGrid (line 244) | public NestedGrid(int[][] blockSizes, long[] datasetSize) {
method NestedGrid (line 304) | public NestedGrid(int[][] blockSizes) {
method nestedPosition (line 327) | public NestedPosition nestedPosition(final long[] position, final in...
method nestedPosition (line 345) | public NestedPosition nestedPosition(final long[] position) {
method numLevels (line 349) | public int numLevels() {
method numDimensions (line 353) | public int numDimensions() {
method getBlockSize (line 360) | public int[] getBlockSize(final int level) {
method pixelPosition (line 375) | public void pixelPosition(
method pixelPosition (line 396) | public long[] pixelPosition(
method maxPixelPosition (line 419) | public void maxPixelPosition(
method maxPixelPosition (line 444) | public long[] maxPixelPosition(
method absolutePosition (line 470) | public void absolutePosition(
method absolutePosition (line 499) | public long[] absolutePosition(
method absolutePosition (line 526) | public long[] absolutePosition(
method relativePosition (line 554) | public void relativePosition(
method relativePosition (line 568) | public long[] relativePosition(
method relativeBlockSize (line 584) | public int[] relativeBlockSize(final int level) {
method relativeToBaseBlockSize (line 595) | public int[] relativeToBaseBlockSize(final int level) {
method getDatasetSize (line 607) | public long[] getDatasetSize() {
method getDatasetSizeInChunks (line 619) | public long[] getDatasetSizeInChunks() {
FILE: src/main/java/org/janelia/saalfeldlab/n5/shard/PositionValueAccess.java
type PositionValueAccess (line 17) | public interface PositionValueAccess {
method get (line 33) | VolatileReadData get(long[] key) throws N5Exception.N5IOException;
method set (line 47) | void set(long[] key, ReadData data) throws N5Exception.N5IOException;
method exists (line 49) | boolean exists(long[] key) throws N5Exception.N5IOException;
method remove (line 51) | boolean remove(long[] key) throws N5Exception.N5IOException;
method fromKva (line 53) | static PositionValueAccess fromKva(
class KvaPositionValueAccess (line 62) | class KvaPositionValueAccess implements PositionValueAccess {
method KvaPositionValueAccess (line 69) | KvaPositionValueAccess(final KeyValueAccess kva,
method absolutePath (line 88) | protected String absolutePath(final long... gridPosition) {
method get (line 92) | @Override
method exists (line 101) | @Override
method set (line 106) | @Override
method remove (line 115) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/shard/RawShard.java
class RawShard (line 13) | public class RawShard {
method RawShard (line 19) | RawShard(final int[] size) {
method RawShard (line 24) | RawShard(final SegmentedReadData sourceData, final NDArray<Segment> in...
method RawShard (line 29) | RawShard(final ShardIndex.SegmentIndexAndData segmentIndexAndData) {
method sourceData (line 39) | public SegmentedReadData sourceData() {
method index (line 49) | public NDArray<Segment> index() {
method isEmpty (line 53) | public boolean isEmpty() {
method getElementData (line 57) | public ReadData getElementData(final long[] pos) {
method setElementData (line 62) | public void setElementData(final ReadData data, final long[] pos) {
method prefetch (line 67) | public void prefetch(List<long[]> positions) {
FILE: src/main/java/org/janelia/saalfeldlab/n5/shard/RawShardCodec.java
class RawShardCodec (line 17) | public class RawShardCodec implements BlockCodec<RawShard> {
method RawShardCodec (line 27) | RawShardCodec(final int[] size, final IndexLocation indexLocation, fin...
method encode (line 35) | @Override
method decode (line 73) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/shard/RawShardDataBlock.java
class RawShardDataBlock (line 9) | public class RawShardDataBlock implements DataBlock<RawShard> {
method RawShardDataBlock (line 15) | RawShardDataBlock(final long[] gridPosition, final RawShard shard) {
method getSize (line 23) | @Override
method getGridPosition (line 28) | @Override
method getNumElements (line 33) | @Override
method getData (line 38) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/shard/Region.java
class Region (line 14) | public class Region {
method Region (line 47) | public Region(final long[] min, final long[] size, final NestedGrid gr...
method minPos (line 68) | public Nesting.NestedPosition minPos() {
method maxPos (line 75) | public Nesting.NestedPosition maxPos() {
method fullyContains (line 92) | public boolean fullyContains(final Nesting.NestedPosition position) {
method containedNestedPositions (line 120) | List<Nesting.NestedPosition> containedNestedPositions(final Nesting.Ne...
method gridPositions (line 141) | public static List<long[]> gridPositions(final long[] min, final long[...
FILE: src/main/java/org/janelia/saalfeldlab/n5/shard/ShardCodecInfo.java
type ShardCodecInfo (line 9) | public interface ShardCodecInfo extends BlockCodecInfo {
method getInnerBlockSize (line 16) | int[] getInnerBlockSize();
method getInnerDatasetCodecInfos (line 22) | DatasetCodecInfo[] getInnerDatasetCodecInfos();
method getInnerBlockCodecInfo (line 29) | BlockCodecInfo getInnerBlockCodecInfo();
method getInnerDataCodecInfos (line 35) | DataCodecInfo[] getInnerDataCodecInfos();
method getIndexBlockCodecInfo (line 42) | BlockCodecInfo getIndexBlockCodecInfo();
method getIndexDataCodecInfos (line 49) | DataCodecInfo[] getIndexDataCodecInfos();
method getIndexLocation (line 51) | IndexLocation getIndexLocation();
method create (line 53) | @SuppressWarnings("unchecked")
method create (line 59) | RawShardCodec create(int[] blockSize, DataCodecInfo... codecs);
FILE: src/main/java/org/janelia/saalfeldlab/n5/shard/ShardIndex.java
class ShardIndex (line 18) | public class ShardIndex {
method ShardIndex (line 20) | private ShardIndex() {
type IndexLocation (line 24) | public enum IndexLocation {
class NDArray (line 35) | public static class NDArray<T> {
method NDArray (line 41) | NDArray(final int[] size, final IntFunction<T[]> createArray) {
method NDArray (line 47) | NDArray(final int[] size, final T[] data) {
method get (line 53) | T get(long... position) {
method set (line 57) | void set(T value, long... position) {
method index (line 61) | private int index(long... position) {
method size (line 69) | public int[] size() {
method numElements (line 73) | public int numElements() {
method allElementsNull (line 77) | public boolean allElementsNull() {
method getNumElements (line 87) | static int getNumElements(final int[] size) {
method getStrides (line 95) | static int[] getStrides(final int[] size) {
method fromDataBlock (line 116) | static NDArray<Range> fromDataBlock( final DataBlock<long[]> block ) {
method toDataBlock (line 133) | static DataBlock<long[]> toDataBlock( final NDArray<Range> locations, ...
method prepend (line 159) | private static int[] prepend(final int value, final int[] array) {
method blockSizeFromIndexSize (line 170) | static int[] blockSizeFromIndexSize(final int[] indexSize) {
method indexSizeFromBlockSize (line 177) | static int[] indexSizeFromBlockSize(final int[] blockSize) {
method locations (line 187) | static NDArray<Range> locations(final NDArray<Segment> segments, final...
type SegmentIndexAndData (line 200) | interface SegmentIndexAndData {
method index (line 201) | NDArray<Segment> index();
method data (line 202) | SegmentedReadData data();
method segments (line 211) | static SegmentIndexAndData segments(final NDArray<Range> locations, fi...
FILE: src/main/java/org/janelia/saalfeldlab/n5/util/FloatValueParser.java
class FloatValueParser (line 15) | public class FloatValueParser {
method parseFloat (line 26) | public static float parseFloat(String hexString) throws N5Exception {
method encodeFloat (line 40) | public static String encodeFloat(float value) {
method validateFloat (line 45) | private static void validateFloat(String hexString) {
method parseDouble (line 60) | public static double parseDouble(String hexString) throws N5Exception {
method encodeDouble (line 74) | public static String encodeDouble(double value) {
method validateDouble (line 79) | private static void validateDouble(String hexString) {
method parseBytes (line 94) | public static byte[] parseBytes(String hexString) throws N5Exception {
method validateBytes (line 104) | private static void validateBytes(String hexString) {
FILE: src/main/java/org/janelia/saalfeldlab/n5/util/MemCopy.java
type MemCopy (line 12) | public interface MemCopy<T> {
method forDataType (line 21) | static MemCopy<?> forDataType(final DataType dataType) {
method copyStrided (line 55) | void copyStrided(T src, int srcPos, T dest, int destPos, int destStrid...
class MemCopyByte (line 57) | class MemCopyByte implements MemCopy<byte[]> {
method copyStrided (line 59) | @Override
class MemCopyShort (line 69) | class MemCopyShort implements MemCopy<short[]> {
method copyStrided (line 71) | @Override
class MemCopyInt (line 81) | class MemCopyInt implements MemCopy<int[]> {
method copyStrided (line 83) | @Override
class MemCopyLong (line 93) | class MemCopyLong implements MemCopy<long[]> {
method copyStrided (line 95) | @Override
class MemCopyFloat (line 105) | class MemCopyFloat implements MemCopy<float[]> {
method copyStrided (line 107) | @Override
class MemCopyDouble (line 117) | class MemCopyDouble implements MemCopy<double[]> {
method copyStrided (line 119) | @Override
FILE: src/main/java/org/janelia/saalfeldlab/n5/util/SubArrayCopy.java
type SubArrayCopy (line 11) | public interface SubArrayCopy
method copy (line 34) | static void copy( Object src, int[] srcSize, int[] srcPos, Object dest...
method positionToIndex (line 55) | static int positionToIndex( final int[] position, final int[] dimensio...
method createAllocationSteps (line 73) | static void createAllocationSteps( final int[] dimensions, final int[]...
method createAllocationSteps (line 82) | static int[] createAllocationSteps( final int[] dimensions )
method copyNDRangeRecursive (line 119) | static <T> void copyNDRangeRecursive(
FILE: src/test/java/org/janelia/saalfeldlab/n5/AbstractN5Test.java
class AbstractN5Test (line 58) | public abstract class AbstractN5Test {
method createTempUri (line 78) | public static URI createTempUri(String prefix, String suffix, URI base) {
method createTempN5Writer (line 88) | public N5Writer createTempN5Writer() {
method createTempN5Writer (line 97) | public final N5Writer createTempN5Writer(String location) {
method createTempN5Writer (line 102) | protected final N5Writer createTempN5Writer(String location, GsonBuild...
method removeTempWriters (line 114) | @After
method tempN5Location (line 128) | protected abstract String tempN5Location() throws URISyntaxException, ...
method createN5Writer (line 130) | protected N5Writer createN5Writer() throws IOException, URISyntaxExcep...
method createN5Writer (line 135) | protected N5Writer createN5Writer(final String location) throws IOExce...
method createN5Writer (line 141) | protected abstract N5Writer createN5Writer(String location, GsonBuilde...
method createN5Reader (line 143) | protected N5Reader createN5Reader(final String location) throws IOExce...
method createN5Reader (line 148) | protected abstract N5Reader createN5Reader(String location, GsonBuilde...
method getCompressions (line 150) | protected Compression[] getCompressions() {
method setUpOnce (line 162) | @Before
method testCreateGroup (line 182) | @Test
method testSetAttributeDoesntCreateGroup (line 197) | @Test
method testCreateDataset (line 208) | @Test
method testBlocksLargerThanDimensions (line 225) | @Test
method testUnalignedBlocksTruncatedAtEnd (line 254) | @Test
method testWriteReadByteBlock (line 309) | @Test
method testWriteReadStringBlock (line 329) | @Test
method testWriteReadShortBlock (line 351) | @Test
method testWriteReadIntBlock (line 373) | @Test
method testWriteReadLongBlock (line 395) | @Test
method testWriteReadFloatBlock (line 417) | @Test
method testWriteReadDoubleBlock (line 434) | @Test
method testReadChunkVsBlock (line 451) | @Test
method testMode1WriteReadByteBlock (line 481) | @Test
method testWriteReadSerializableBlock (line 505) | @Test
method testWriteInvalidBlock (line 530) | @Test
method testOverwriteBlock (line 581) | @Test
method testAttributeParsingPrimitive (line 603) | @Test
method testAttributes (line 679) | @Test
method testDatasetAttributes (line 746) | @Test
method testNullAttributes (line 761) | @Test
method testRemoveAttributes (line 846) | @Test
method testRemoveContainer (line 959) | @Test
method testUri (line 973) | @Test
method testRemoveGroup (line 983) | @Test
method testList (line 994) | @Test
method testDeepList (line 1028) | @Test
method testExists (line 1145) | @Test
method testListAttributes (line 1166) | @Test
method testVersion (line 1215) | @Test
method testReaderCreation (line 1237) | @Test
method testDelete (line 1280) | @Test
class TestData (line 1319) | public static class TestData<T> {
method TestData (line 1326) | @SuppressWarnings("unchecked")
method testAttributePathEquivalence (line 1336) | protected static void testAttributePathEquivalence(final N5Writer writ...
method addAndTest (line 1358) | protected static void addAndTest(final N5Writer writer, final ArrayLis...
method runTests (line 1379) | protected static void runTests(final N5Writer writer, final ArrayList<...
method customObjectTest (line 1387) | @Test
method testAttributePaths (line 1422) | @Test
method testAttributePathEscaping (line 1534) | @Test
method jsonKeyVal (line 1615) | private String jsonKeyVal(final String key, final String val) {
method testRootLeaves (line 1620) | @Test
method testWriterSeparation (line 1709) | @Test
method illegalChars (line 1728) | protected String[] illegalChars() {
method testPathsWithIllegalUriCharacters (line 1732) | @Test
method assertBlockEquals (line 1764) | public static void assertBlockEquals(final DataBlock<?> expected, fina...
method assertDatasetAttributesEquals (line 1792) | protected void assertDatasetAttributesEquals(final DatasetAttributes e...
FILE: src/test/java/org/janelia/saalfeldlab/n5/DatasetAttributesTest.java
class DatasetAttributesTest (line 20) | public class DatasetAttributesTest {
method testValidateBlockShardSizesValid (line 25) | @Test
method shardDatasetAttributes (line 73) | private static DatasetAttributes shardDatasetAttributes(
method builderTests (line 87) | @Test
method testValidateBlockShardSizesInvalid (line 123) | @Test
FILE: src/test/java/org/janelia/saalfeldlab/n5/FileKeyLockManagerTest.java
class FileKeyLockManagerTest (line 27) | public class FileKeyLockManagerTest {
method setUp (line 31) | @Before
method tearDown (line 37) | @After
method testConcurrentReads (line 53) | @Test
method testReadWriteExclusion (line 118) | @Test
class CleanUpHelper (line 164) | private class CleanUpHelper implements Closeable {
method CleanUpHelper (line 169) | CleanUpHelper() throws IOException, InterruptedException {
method tryWaitForSize (line 176) | private void tryWaitForSize(final int expectedSize) throws IOExcepti...
method tryWaitForSize (line 180) | private void tryWaitForSize(final int expectedSize, final int numIte...
method close (line 201) | @Override
method testLockCleanup (line 207) | @Test
method testWriteLockCreatesFile (line 247) | @Test
method testWriteLockCreatesParentDirectories (line 266) | @Test
method testReadLockRequiresExistingFile (line 287) | @Test
method testLocksMapEmptyAfterProperClose (line 293) | @Test
method testLocksMapEmptyAfterLeakedChannelIsGCd (line 312) | @Test
method acquireAndLeakLock (line 331) | private void acquireAndLeakLock(final Path path) throws IOException {
FILE: src/test/java/org/janelia/saalfeldlab/n5/FsLockTest.java
class FsLockTest (line 16) | public class FsLockTest {
method tempPathName (line 20) | private static String tempPathName() {
method testReadLock (line 33) | @Test
method testWriteLock (line 67) | @Test
method testFSLockRelease (line 98) | @Test
method testReadLockBehavior (line 131) | @Test
method testWriteLockBehavior (line 175) | @Test
FILE: src/test/java/org/janelia/saalfeldlab/n5/N5Benchmark.java
class N5Benchmark (line 40) | public class N5Benchmark {
method setUpBeforeClass (line 70) | @BeforeClass
method rampDownAfterClass (line 91) | @AfterClass
method setUp (line 100) | @Before
method testDocExample (line 107) | public void testDocExample() {
method benchmarkWritingSpeed (line 124) | public void benchmarkWritingSpeed() {
method benchmarkParallelWritingSpeed (line 200) | @Test
FILE: src/test/java/org/janelia/saalfeldlab/n5/N5CachedFSTest.java
class N5CachedFSTest (line 26) | public class N5CachedFSTest extends N5FSTest {
method createN5Writer (line 28) | @Override
method createN5Reader (line 34) | @Override
method createN5Writer (line 40) | protected N5Writer createN5Writer(final String location, final GsonBui...
method createN5Writer (line 45) | protected N5Writer createN5Writer(final String location, final boolean...
method createN5Reader (line 50) | protected N5Reader createN5Reader(final String location, final GsonBui...
method createN5Writer (line 55) | @Override protected N5Writer createN5Writer() throws IOException, URIS...
method cacheTest (line 66) | @Test
method cacheGroupDatasetTest (line 101) | @Test
method cacheBehaviorTest (line 141) | @Test
method cacheBehaviorHelper (line 154) | public static void cacheBehaviorHelper(final TrackingStorage n5) throw...
type TrackingStorage (line 455) | public static interface TrackingStorage extends CachedGsonKeyValueN5Wr...
method getAttrCallCount (line 457) | public int getAttrCallCount();
method getExistCallCount (line 458) | public int getExistCallCount();
method getGroupCallCount (line 459) | public int getGroupCallCount();
method getGroupAttrCallCount (line 460) | public int getGroupAttrCallCount();
method getDatasetCallCount (line 461) | public int getDatasetCallCount();
method getDatasetAttrCallCount (line 462) | public int getDatasetAttrCallCount();
method getListCallCount (line 463) | public int getListCallCount();
method getWriteAttrCallCount (line 464) | public int getWriteAttrCallCount();
class N5TrackingStorage (line 467) | public static class N5TrackingStorage extends N5KeyValueWriter impleme...
method N5TrackingStorage (line 478) | public N5TrackingStorage(final KeyValueAccess keyValueAccess, final ...
method getAttributesFromContainer (line 484) | @Override
method existsFromContainer (line 490) | @Override
method isGroupFromContainer (line 496) | @Override
method isGroupFromAttributes (line 502) | @Override
method isDatasetFromContainer (line 508) | @Override
method isDatasetFromAttributes (line 514) | @Override
method listFromContainer (line 520) | @Override
method writeAttributes (line 526) | @Override public void writeAttributes(String normalGroupPath, JsonEl...
method getAttrCallCount (line 531) | @Override
method getExistCallCount (line 536) | @Override
method getGroupCallCount (line 541) | @Override
method getGroupAttrCallCount (line 546) | @Override
method getDatasetCallCount (line 551) | @Override
method getDatasetAttrCallCount (line 556) | @Override
method getListCallCount (line 561) | @Override
method getWriteAttrCallCount (line 566) | @Override public int getWriteAttrCallCount() {
FILE: src/test/java/org/janelia/saalfeldlab/n5/N5FSTest.java
class N5FSTest (line 34) | public class N5FSTest extends AbstractN5Test {
method tempN5PathName (line 36) | private static String tempN5PathName() {
method tempN5Location (line 49) | @Override
method createN5Writer (line 56) | @Override
method createN5Writer (line 62) | @Override
method createN5Reader (line 70) | @Override
FILE: src/test/java/org/janelia/saalfeldlab/n5/N5ReadBenchmark.java
class N5ReadBenchmark (line 24) | @State( Scope.Thread )
method tempN5PathName (line 30) | private static String tempN5PathName() {
method createData (line 52) | private static void createData() {
method createTempN5Writer (line 71) | private static N5Writer createTempN5Writer() {
method setup (line 78) | @Setup(Level.Trial)
method bench (line 100) | @Benchmark
method main (line 107) | public static void main( final String... args ) throws RunnerException...
FILE: src/test/java/org/janelia/saalfeldlab/n5/N5URITest.java
class N5URITest (line 11) | public class N5URITest {
method testAttributePath (line 12) | @Test
method testEscapedAttributePaths (line 68) | @Test
method testIsAbsolute (line 81) | @Test
method testGetRelative (line 96) | @Test
FILE: src/test/java/org/janelia/saalfeldlab/n5/TrackingN5Writer.java
class TrackingN5Writer (line 10) | public class TrackingN5Writer extends N5KeyValueWriter {
method TrackingN5Writer (line 14) | public TrackingN5Writer(String basePath, KeyValueAccess kva) {
method resetNumMaterializeCalls (line 20) | public void resetNumMaterializeCalls() {
method getNumMaterializeCalls (line 24) | public int getNumMaterializeCalls() {
method resetNumIsFileCalls (line 28) | public void resetNumIsFileCalls() {
method getNumIsFileCalls (line 32) | public int getNumIsFileCalls() {
method resetTotalBytesRead (line 36) | public void resetTotalBytesRead() {
method getTotalBytesRead (line 40) | public long getTotalBytesRead() {
method resetAllTracking (line 44) | public void resetAllTracking() {
FILE: src/test/java/org/janelia/saalfeldlab/n5/UriTest.java
class UriTest (line 12) | public class UriTest {
method before (line 24) | @Before
method testUriParsing (line 31) | @Test
FILE: src/test/java/org/janelia/saalfeldlab/n5/WriteLockExp.java
class WriteLockExp (line 11) | public class WriteLockExp {
method WriteLockExp (line 21) | public WriteLockExp(String root, int shardIdx) {
method main (line 27) | public static void main(String[] args) {
method run (line 36) | public void run() {
method getOrCreateDataset (line 63) | public DatasetAttributes getOrCreateDataset(N5Writer n5) {
method blockSupplier (line 78) | DataBlockSupplier<int[]> blockSupplier(final int i, final int[] chunkS...
method data (line 93) | static int[] data(final int chunkN, final int value) {
FILE: src/test/java/org/janelia/saalfeldlab/n5/backward/CompatibilityTest.java
class CompatibilityTest (line 20) | public class CompatibilityTest {
method testBackwardReads (line 31) | @Test
method backwardReadHelper (line 38) | public void backwardReadHelper(final String base, final String dsetPat...
method testBlockData (line 82) | @Test
method read (line 114) | private byte[] read(KeyValueAccess kva, String path) {
method expectedData (line 125) | private static byte[] expectedData(int size, byte value ) {
FILE: src/test/java/org/janelia/saalfeldlab/n5/backward/CreateSampleData.java
class CreateSampleData (line 14) | public class CreateSampleData {
method main (line 16) | public static void main(String[] args) throws IOException {
method createSampleData (line 23) | public static N5FSWriter createSampleData(String baseDir, String datas...
method createDataBlock (line 63) | public static ByteArrayDataBlock createDataBlock(int[] size, long[] gr...
FILE: src/test/java/org/janelia/saalfeldlab/n5/benchmarks/N5BlockWriteBenchmarks.java
class N5BlockWriteBenchmarks (line 39) | @State(Scope.Benchmark)
method main (line 68) | public static void main( String[] args ) throws RunnerException {
method teardown (line 74) | @TearDown(Level.Trial)
method setup (line 81) | @Setup(Level.Trial)
method writeBenchmark (line 121) | @Benchmark
method readBenchmark (line 129) | @Benchmark
method fillBlock (line 139) | private void fillBlock(DataType dtype, DataBlock<?> blk) {
method fill (line 181) | private void fill(short[] arr) {
method fill (line 186) | private void fill(int[] arr) {
method fill (line 191) | private void fill(long[] arr) {
method fill (line 196) | private void fill(float[] arr) {
method fill (line 201) | private void fill(double[] arr) {
method fill (line 206) | private void fill(byte[] arr) {
FILE: src/test/java/org/janelia/saalfeldlab/n5/benchmarks/ReadDataBenchmarks.java
class ReadDataBenchmarks (line 35) | @State(Scope.Benchmark)
method ReadDataBenchmarks (line 51) | public ReadDataBenchmarks() {}
method main (line 53) | public static void main(String... args) throws RunnerException {
method run (line 61) | @Benchmark
method read (line 69) | public VolatileReadData read() throws IOException {
method getPath (line 74) | protected Path getPath() {
method setup (line 79) | @Setup(Level.Trial)
method write (line 94) | protected void write(Path path, int numBytes) {
method teardown (line 113) | @TearDown(Level.Trial)
method sizes (line 122) | public int[] sizes() {
FILE: src/test/java/org/janelia/saalfeldlab/n5/cache/N5CacheTest.java
class N5CacheTest (line 19) | public class N5CacheTest {
method cacheBackingTest (line 22) | @Test
method testCopyOnReadPreventsExternalModification (line 110) | @Test
method testCacheManipulationMethods (line 128) | @Test
method testChildManagement (line 158) | @Test
method testRemoveCacheHierarchy (line 190) | @Test
method testListNonExistentGroupThrows (line 222) | @Test(expected = N5Exception.N5IOException.class)
method testEmptyCacheInfoBehavior (line 230) | @Test
method testEmptyJsonDeepCopyThrows (line 242) | @Test(expected = N5Exception.class)
method testCacheStateTransitions (line 247) | @Test
class DummyBackingStorage (line 269) | protected static class DummyBackingStorage implements N5JsonCacheableC...
method DummyBackingStorage (line 279) | public DummyBackingStorage() {
method getAttributesFromContainer (line 282) | public JsonElement getAttributesFromContainer(final String path, fin...
method existsFromContainer (line 289) | public boolean existsFromContainer(final String path, final String c...
method isGroupFromContainer (line 294) | public boolean isGroupFromContainer(final String path) {
method isDatasetFromContainer (line 299) | public boolean isDatasetFromContainer(final String path) {
method listFromContainer (line 304) | public String[] listFromContainer(final String path) {
method isGroupFromAttributes (line 309) | @Override
method isDatasetFromAttributes (line 315) | @Override
class DummyNonExistentBackingStorage (line 323) | protected static class DummyNonExistentBackingStorage extends DummyBac...
method getAttributesFromContainer (line 325) | @Override
method existsFromContainer (line 331) | @Override
FILE: src/test/java/org/janelia/saalfeldlab/n5/codec/BlockCodecTests.java
class BlockCodecTests (line 28) | public class BlockCodecTests {
method testN5BlockCodec (line 50) | @Test
method testRawBytesBlockCodec (line 67) | @Test
method testBlockCodecHelper (line 89) | private <T> void testBlockCodecHelper(DatasetAttributes attributes) th...
method testEmptyBlock (line 113) | @SuppressWarnings("unchecked")
method testEncodedSizeCalculation (line 139) | @Test
method createRandomDataBlock (line 181) | private static DataBlock<?> createRandomDataBlock(DataType dataType, i...
method verifyCompatibleDataType (line 236) | private static void verifyCompatibleDataType(DataType expectedType, Da...
method assertDataEquals (line 267) | private static void assertDataEquals(DataBlock<?> expected, DataBlock<...
class TestDatasetAttributes (line 289) | public static class TestDatasetAttributes extends DatasetAttributes {
method TestDatasetAttributes (line 291) | public TestDatasetAttributes(long[] dimensions, int[] outerBlockSize...
method getDatasetAccess (line 297) | @Override // to make this accessible for the test
FILE: src/test/java/org/janelia/saalfeldlab/n5/codec/BytesCodecTests.java
class BytesCodecTests (line 19) | public class BytesCodecTests {
method setup (line 23) | @BeforeClass
method testEncodeDecodeBytes (line 28) | @Test
method concatenatedBytesCodecTest (line 47) | @Test
class ByteFunctionCodec (line 75) | public static class ByteFunctionCodec implements DataCodec, DataCodecI...
method ByteFunctionCodec (line 80) | public ByteFunctionCodec( IntUnaryOperator encoder, IntUnaryOperator...
method getType (line 85) | @Override
method decode (line 90) | public ReadData decode(ReadData data) {
method encode (line 94) | public ReadData encode(ReadData data) {
method create (line 98) | @Override public DataCodec create() {
class ByteFun (line 104) | private static class ByteFun implements OutputStreamOperator {
method ByteFun (line 107) | public ByteFun(IntUnaryOperator fun) {
method apply (line 111) | @Override
class BitShiftBytesCodec (line 122) | @NameConfig.Name(BitShiftBytesCodec.TYPE)
method create (line 124) | @Override public DataCodec create() {
method BitShiftBytesCodec (line 134) | public BitShiftBytesCodec() {
method BitShiftBytesCodec (line 139) | public BitShiftBytesCodec(int shift) {
method getType (line 144) | @Override
method decode (line 150) | @Override
method encode (line 169) | @Override
method equals (line 187) | @Override
method hashCode (line 200) | @Override
FILE: src/test/java/org/janelia/saalfeldlab/n5/codec/ChecksumCodecTests.java
class ChecksumCodecTests (line 12) | public class ChecksumCodecTests {
method testCrc32cChecksumCodec (line 14) | @Test
FILE: src/test/java/org/janelia/saalfeldlab/n5/codec/DatasetCodecTests.java
class DatasetCodecTests (line 9) | public class DatasetCodecTests {
method testTransposeCodecSimplification (line 11) | @Test
FILE: src/test/java/org/janelia/saalfeldlab/n5/compression/CompressionTypesTest.java
class CompressionTypesTest (line 18) | public class CompressionTypesTest {
method setUpBeforeClass (line 23) | @BeforeClass
method tearDownAfterClass (line 30) | @AfterClass
method setUp (line 37) | @Before
method tearDown (line 44) | @After
method test (line 48) | @Test
FILE: src/test/java/org/janelia/saalfeldlab/n5/demo/AttributePathDemo.java
class AttributePathDemo (line 18) | public class AttributePathDemo {
method AttributePathDemo (line 22) | public AttributePathDemo() {
method main (line 26) | public static void main(String[] args) throws IOException {
method demo (line 31) | public void demo() throws IOException {
method simple (line 59) | public void simple(final N5FSWriter n5, final String group) throws IOE...
method arrays (line 89) | public void arrays(final N5FSWriter n5, final String group) throws IOE...
method objects (line 109) | @SuppressWarnings("rawtypes")
method specialChars (line 146) | public void specialChars(final N5FSWriter n5, final String group) thro...
method removingAttributesAndNulls (line 157) | public void removingAttributesAndNulls(final N5FSWriter n5, final Stri...
method getRawJson (line 188) | public String getRawJson(final N5Reader n5, final String group) throws...
method printAsJson (line 195) | public void printAsJson(final Object obj) {
class Pet (line 199) | class Pet {
method Pet (line 203) | public Pet(String name, int age) {
method toString (line 208) | public String toString() {
FILE: src/test/java/org/janelia/saalfeldlab/n5/http/HttpKeyValueAccessTest.java
class HttpKeyValueAccessTest (line 18) | public class HttpKeyValueAccessTest {
method testExistsRead (line 24) | @Test
method testUnsupportedOperations (line 41) | @Test
FILE: src/test/java/org/janelia/saalfeldlab/n5/http/HttpReaderFsWriter.java
class HttpReaderFsWriter (line 25) | public class HttpReaderFsWriter implements GsonKeyValueN5Writer {
method HttpReaderFsWriter (line 30) | public <W extends GsonKeyValueN5Writer, R extends GsonKeyValueN5Reader...
method getAttributesKey (line 61) | @Override public String getAttributesKey() {
method getVersion (line 66) | @Override public Version getVersion() throws N5Exception {
method getURI (line 71) | @Override public URI getURI() {
method getAttribute (line 76) | @Override public <T> T getAttribute(String pathName, String key, Class...
method getAttribute (line 81) | @Override public <T> T getAttribute(String pathName, String key, Type ...
method getDatasetAttributes (line 86) | @Override public DatasetAttributes getDatasetAttributes(String pathNam...
method readChunk (line 91) | @Override public DataBlock<?> readChunk(String pathName, DatasetAttrib...
method readSerializedBlock (line 96) | @Override public <T> T readSerializedBlock(String dataset, DatasetAttr...
method getKeyValueAccess (line 101) | @Override public KeyValueAccess getKeyValueAccess() {
method exists (line 106) | @Override public boolean exists(String pathName) {
method datasetExists (line 111) | @Override public boolean datasetExists(String pathName) throws N5Excep...
method list (line 116) | @Override public String[] list(String pathName) throws N5Exception {
method deepList (line 121) | @Override public String[] deepList(String pathName, Predicate<String> ...
method deepList (line 126) | @Override public String[] deepList(String pathName) throws N5Exception {
method deepListDatasets (line 131) | @Override public String[] deepListDatasets(String pathName, Predicate<...
method deepListDatasets (line 136) | @Override public String[] deepListDatasets(String pathName) throws N5E...
method deepList (line 141) | @Override public String[] deepList(String pathName, Predicate<String> ...
method deepList (line 146) | @Override public String[] deepList(String pathName, ExecutorService ex...
method deepListDatasets (line 151) | @Override public String[] deepListDatasets(String pathName, Predicate<...
method deepListDatasets (line 156) | @Override public String[] deepListDatasets(String pathName, ExecutorSe...
method getGson (line 161) | @Override public Gson getGson() {
method listAttributes (line 166) | @Override public Map<String, Class<?>> listAttributes(String pathName)...
method getGroupSeparator (line 171) | @Override public String getGroupSeparator() {
method groupPath (line 176) | @Override public String groupPath(String... nodes) {
method close (line 181) | @Override public void close() {
method setAttribute (line 187) | @Override public <T> void setAttribute(String groupPath, String attrib...
method setAttributes (line 192) | @Override public void setAttributes(String groupPath, Map<String, ?> a...
method removeAttribute (line 196) | @Override public boolean removeAttribute(String groupPath, String attr...
method removeAttribute (line 201) | @Override public <T> T removeAttribute(String groupPath, String attrib...
method removeAttributes (line 206) | @Override public boolean removeAttributes(String groupPath, List<Strin...
method setDatasetAttributes (line 211) | @Override public void setDatasetAttributes(String datasetPath, Dataset...
method getConvertedDatasetAttributes (line 216) | @Override public DatasetAttributes getConvertedDatasetAttributes(Datas...
method setVersion (line 221) | @Override public void setVersion() throws N5Exception {
method createGroup (line 226) | @Override public void createGroup(String groupPath) throws N5Exception {
method remove (line 230) | @Override public boolean remove(String groupPath) throws N5Exception {
method remove (line 235) | @Override public boolean remove() throws N5Exception {
method createDataset (line 240) | @Override public DatasetAttributes createDataset(String datasetPath, D...
method writeChunk (line 247) | @Override public <T> void writeChunk(String datasetPath, DatasetAttrib...
method writeBlock (line 251) | @Override public <T> void writeBlock(String datasetPath, DatasetAttrib...
method deleteChunk (line 255) | @Override public boolean deleteChunk(String datasetPath, long... gridP...
method deleteChunks (line 260) | @Override public boolean deleteChunks(String datasetPath, DatasetAttri...
method writeSerializedBlock (line 265) | @Override public void writeSerializedBlock(Serializable object, String...
method setVersion (line 270) | @Override public void setVersion(String path) {
method writeAttributes (line 275) | @Override public void writeAttributes(String normalGroupPath, JsonElem...
method setAttributes (line 280) | @Override public void setAttributes(String path, JsonElement attribute...
method writeAttributes (line 285) | @Override public void writeAttributes(String normalGroupPath, Map<Stri...
method writeChunks (line 290) | @Override public <T> void writeChunks(String datasetPath, DatasetAttri...
FILE: src/test/java/org/janelia/saalfeldlab/n5/http/N5HttpTest.java
class N5HttpTest (line 28) | @RunWith(RunnerWithHttpServer.class)
method tempN5Location (line 37) | @Override
method removeTempWriters (line 51) | @After
method removeClassTempWriters (line 61) | @AfterClass
method createN5Writer (line 75) | @Override
method createN5Reader (line 86) | @Override
method testVersion (line 95) | @Test
method testRemoveGroup (line 115) | @Ignore("N5Writer not supported for HTTP")
method testRemoveAttributes (line 120) | @Ignore("N5Writer not supported for HTTP")
method testRemoveContainer (line 125) | @Ignore("N5Writer not supported for HTTP")
method testDelete (line 130) | @Ignore("N5Writer not supported for HTTP")
method testWriterSeparation (line 135) | @Ignore("N5Writer not supported for HTTP")
FILE: src/test/java/org/janelia/saalfeldlab/n5/http/RunnerWithHttpServer.java
class RunnerWithHttpServer (line 25) | public class RunnerWithHttpServer extends BlockJUnit4ClassRunner {
method RunnerWithHttpServer (line 35) | public RunnerWithHttpServer(Class<?> klass) throws Exception {
method createTmpServerDirectory (line 40) | private static Path createTmpServerDirectory() throws IOException {
method createTest (line 50) | @Override protected Object createTest() throws Exception {
method runChild (line 63) | @Override protected void runChild(FrameworkMethod method, RunNotifier ...
method logHttpOutput (line 95) | private void logHttpOutput() {
method startHttpServer (line 104) | @Before
method waitForHttpReady (line 130) | private void waitForHttpReady() throws IOException, InterruptedExcepti...
method stopHttpServer (line 147) | @After
method withBeforeClasses (line 158) | @Override protected Statement withBeforeClasses(Statement statement) {
method withAfterClasses (line 165) | @Override protected Statement withAfterClasses(Statement statement) {
FILE: src/test/java/org/janelia/saalfeldlab/n5/kva/AbstractKeyValueAccessTest.java
class AbstractKeyValueAccessTest (line 17) | public abstract class AbstractKeyValueAccessTest {
method newKeyValueAccess (line 19) | protected abstract KeyValueAccess newKeyValueAccess(URI root);
method newKeyValueAccess (line 21) | protected KeyValueAccess newKeyValueAccess() {
method tempUri (line 26) | protected abstract URI tempUri();
method testURIs (line 28) | protected URI[] testURIs(final URI base) {
method testPathComponents (line 59) | protected String[][] testPathComponents(final URI base) {
method testComponentsAtLocation (line 84) | protected void testComponentsAtLocation(URI testRoot) {
method testComposeAtLocation (line 99) | protected void testComposeAtLocation(URI uri) {
method testComponents (line 119) | @Test
method testComponentsWithPathSlash (line 125) | @Test
method testComponentsWithPathEmpty (line 132) | @Test
method testCompose (line 139) | @Test
method testComposeWithPathSlash (line 157) | @Test
method testComposeWithPathEmpty (line 174) | @Test
method assertComposeEquals (line 191) | public void assertComposeEquals(String reason, KeyValueAccess kva, URI...
method setUriPath (line 197) | public URI setUriPath(final URI uri, final String path) {
FILE: src/test/java/org/janelia/saalfeldlab/n5/kva/DelegateKeyValueAccess.java
class DelegateKeyValueAccess (line 11) | public class DelegateKeyValueAccess implements KeyValueAccess {
method DelegateKeyValueAccess (line 15) | public DelegateKeyValueAccess(KeyValueAccess kva) { this.kva = kva; }
method components (line 17) | @Override
method compose (line 22) | @Override
method compose (line 27) | @Override
method parent (line 32) | @Override
method relativize (line 37) | @Override
method normalize (line 42) | @Override
method uri (line 47) | @Override
method exists (line 52) | @Override
method size (line 57) | @Override
method isDirectory (line 62) | @Override
method isFile (line 67) | @Override
method createReadData (line 72) | @Override
method write (line 77) | @Override
method listDirectories (line 82) | @Override
method list (line 87) | @Override
method createDirectories (line 92) | @Override
method delete (line 98) | @Override
FILE: src/test/java/org/janelia/saalfeldlab/n5/kva/FileSystemKeyValueAccessTest.java
class FileSystemKeyValueAccessTest (line 25) | public class FileSystemKeyValueAccessTest extends AbstractKeyValueAccess...
method newKeyValueAccess (line 33) | @Override
method newKeyValueAccess (line 39) | @Override
method testURIs (line 45) | @Override
method testComponentsAtLocation (line 62) | @Override
method getPathFromFileURI (line 86) | private Path getPathFromFileURI(URI fileUri) {
method testPathComponents (line 101) | @Override
method tempUri (line 132) | @Override
method testComposeAtLocation (line 147) | protected void testComposeAtLocation(URI uri) {
method testComponentsWithPathEmpty (line 166) | @Override
method testComposeWithPathEmpty (line 175) | @Override
FILE: src/test/java/org/janelia/saalfeldlab/n5/kva/FsLockingValidation.java
class FsLockingValidation (line 15) | @Command(
method main (line 44) | public static void main(String[] args) {
method call (line 48) | @Override
FILE: src/test/java/org/janelia/saalfeldlab/n5/kva/HttpKeyValueAccessTest.java
class HttpKeyValueAccessTest (line 17) | @RunWith(RunnerWithHttpServer.class)
method newKeyValueAccess (line 27) | @Override protected KeyValueAccess newKeyValueAccess(URI root) {
method newKeyValueAccess (line 32) | @Override protected KeyValueAccess newKeyValueAccess() {
method tempUri (line 37) | @Override protected URI tempUri() {
FILE: src/test/java/org/janelia/saalfeldlab/n5/kva/TrackingKeyValueAccess.java
class TrackingKeyValueAccess (line 10) | public class TrackingKeyValueAccess extends DelegateKeyValueAccess {
method TrackingKeyValueAccess (line 17) | public TrackingKeyValueAccess(final KeyValueAccess kva) {
method isFile (line 21) | @Override
method createReadData (line 27) | @Override
class TrackingLazyRead (line 38) | private class TrackingLazyRead implements LazyRead {
method TrackingLazyRead (line 42) | TrackingLazyRead(final VolatileReadData readData) {
method size (line 46) | @Override
method materialize (line 52) | @Override
method close (line 59) | @Override
FILE: src/test/java/org/janelia/saalfeldlab/n5/locking/JustFileChannels.java
class JustFileChannels (line 16) | public class JustFileChannels {
method write (line 47) | static void write(String path, boolean doLock, final Random random) {
method tryLockWait (line 89) | static FileLock tryLockWait(FileChannel channel, boolean shared) throw...
method verify (line 109) | static void verify(String path, boolean doLock) {
method main (line 147) | public static void main(String[] args) throws InterruptedException {
FILE: src/test/java/org/janelia/saalfeldlab/n5/locking/JustFileChannelsThreaded.java
class JustFileChannelsThreaded (line 7) | public class JustFileChannelsThreaded {
method main (line 9) | public static void main(String[] args) throws InterruptedException {
FILE: src/test/java/org/janelia/saalfeldlab/n5/readdata/RangeTests.java
class RangeTests (line 13) | public class RangeTests {
method testAggregate (line 15) | @Test
FILE: src/test/java/org/janelia/saalfeldlab/n5/readdata/ReadDataTests.java
class ReadDataTests (line 21) | public class ReadDataTests {
method testLazyReadData (line 23) | @Test
method testByteArrayReadData (line 40) | @Test
method testInputStreamReadData (line 56) | @Test
method testFileKvaReadData (line 73) | @Test
method readDataTestHelper (line 96) | private void readDataTestHelper( ReadData readData, int N, int materia...
method readDataTestEncodeHelper (line 102) | private void readDataTestEncodeHelper( ReadData readData, int N ) thro...
method sliceTestHelper (line 118) | private void sliceTestHelper( ReadData readData, int N ) throws IOExce...
class ByteFun (line 140) | private static class ByteFun implements OutputStreamOperator {
method ByteFun (line 143) | public ByteFun(IntUnaryOperator fun) {
method apply (line 147) | @Override
FILE: src/test/java/org/janelia/saalfeldlab/n5/readdata/prefetch/SliceTrackingLazyReadTests.java
class SliceTrackingLazyReadTests (line 15) | public class SliceTrackingLazyReadTests {
method testDefaultSliceTracking (line 17) | @Test
method testAggregatingSliceTracking (line 57) | @Test
method createDummyLazyRead (line 132) | private static DummyLazyRead createDummyLazyRead(int size) {
method assertStoredSlices (line 146) | private static void assertStoredSlices(TestableSliceTracker sliceTrack...
class TestableDefaultSliceTracker (line 163) | static class TestableDefaultSliceTracker extends EnclosingPrefetchLazy...
method TestableDefaultSliceTracker (line 164) | public TestableDefaultSliceTracker(LazyRead delegate) {
method getSlices (line 168) | @Override
class TestableAggregatingSliceTracker (line 177) | static class TestableAggregatingSliceTracker extends AggregatingPrefet...
method TestableAggregatingSliceTracker (line 178) | public TestableAggregatingSliceTracker(LazyRead delegate) {
method getSlices (line 182) | @Override
type TestableSliceTracker (line 191) | interface TestableSliceTracker {
method getSlices (line 192) | List<Range> getSlices();
class DummyLazyRead (line 195) | static class DummyLazyRead implements LazyRead {
method DummyLazyRead (line 200) | public DummyLazyRead( ReadData data ) {
method close (line 204) | @Override
method materialize (line 209) | @Override
method size (line 216) | @Override
method getNumMaterializeCalls (line 222) | public int getNumMaterializeCalls() {
method resetNumMaterializeCalls (line 227) | public void resetNumMaterializeCalls() {
FILE: src/test/java/org/janelia/saalfeldlab/n5/readdata/prefetch/SlicesTest.java
class SlicesTest (line 11) | public class SlicesTest {
method createSlices (line 13) | private List<Range> createSlices(final long[] offsets, final long[] le...
method testFindContaining (line 21) | @Test
method testAddSlice (line 81) | @Test
FILE: src/test/java/org/janelia/saalfeldlab/n5/readdata/segment/ConcatenatedReadDataTest.java
class ConcatenatedReadDataTest (line 16) | public class ConcatenatedReadDataTest {
method fillData (line 20) | @Before
method createKnownLength (line 37) | private SegmentsAndData createKnownLength() {
method createUnknownLength (line 55) | private SegmentsAndData createUnknownLength() {
method createConcatenate (line 102) | private SegmentsAndData createConcatenate() {
method checkSegmentLocations (line 146) | private static void checkSegmentLocations(final SegmentsAndData segmen...
method checkSegmentRange (line 153) | private static void checkSegmentRange(final SegmentsAndData data, fina...
method testConcatenateUnmaterialized (line 165) | @Test(expected = IllegalStateException.class)
method testConcatenateMaterialize (line 177) | @Test
method testConcatenateWriteTo (line 188) | @Test
FILE: src/test/java/org/janelia/saalfeldlab/n5/readdata/segment/SegmentTest.java
class SegmentTest (line 12) | public class SegmentTest {
method createReadData (line 18) | @Before
method testWrap (line 29) | @Test
method testWrapOrder (line 52) | @Test
method testSlice (line 78) | @Test
method testSliceSegment (line 100) | @Test
method testPartialSliceSegment (line 118) | @Test
method testWrapFully (line 137) | @Test
method testSliceFullyWrapped (line 156) | @Test
method testSliceSegmentFullyWrapped (line 177) | @Test
FILE: src/test/java/org/janelia/saalfeldlab/n5/serialization/CodecSerializationTest.java
class CodecSerializationTest (line 23) | public class CodecSerializationTest {
method before (line 27) | @Before
method testCodecSerialization (line 38) | @Test
method testSerializeCodecArray (line 58) | @Test
FILE: src/test/java/org/janelia/saalfeldlab/n5/shard/DatasetAccessTest.java
class DatasetAccessTest (line 28) | public class DatasetAccessTest {
method setup (line 40) | @Before
method testWriteReadIndividual (line 72) | @Test
method testWriteReadBulk (line 94) | @Test
method testDeleteBlock (line 122) | @Test
method keyExists (line 151) | private boolean keyExists(final PositionValueAccess store, final long[...
method testDeleteBlocks (line 162) | @Test
method checkBlock (line 191) | private static void checkBlock(final DataBlock<byte[]> dataBlock, fina...
method createDataBlock (line 203) | private static DataBlock<byte[]> createDataBlock(int[] size, long[] gr...
class TestDatasetAttributes (line 210) | public static class TestDatasetAttributes extends DatasetAttributes {
method TestDatasetAttributes (line 212) | public TestDatasetAttributes(long[] dimensions, int[] outerBlockSize...
method getDatasetAccess (line 218) | @Override // to make this accessible for the test
FILE: src/test/java/org/janelia/saalfeldlab/n5/shard/NestedGridTest.java
class NestedGridTest (line 14) | public class NestedGridTest {
method absPosition1D (line 16) | private static long absPosition1D(final NestedGrid grid, final int sou...
method testValidateInput (line 20) | @Test
method testAbsolutePosition (line 26) | @Test
method testAbsolutePositionChunkSize (line 41) | @Test
method relPosition1D (line 52) | private static long relPosition1D(final NestedGrid grid, final int sou...
method testRelativePosition (line 56) | @Test
method testRelativePositionChunkSize (line 68) | @Test
method testNd (line 79) | @Test
method testNestedPositionOrder (line 93) | @Test
FILE: src/test/java/org/janelia/saalfeldlab/n5/shard/ShardTest.java
class ShardTest (line 38) | @RunWith(Parameterized.class)
method createTempN5Writer (line 45) | @Override public N5Writer createTempN5Writer() {
method tempN5PathName (line 63) | private String tempN5PathName() {
method data (line 77) | @Parameterized.Parameters(name = "IndexLocation({0}), Index ByteOrder(...
method removeTempWriters (line 98) | @After
method getTestAttributes (line 104) | private DatasetAttributes getTestAttributes(long[] dimensions, int[] s...
method getTestAttributes (line 109) | private DatasetAttributes getTestAttributes(DataType dataType, long[] ...
method getTestAttributes (line 126) | protected DatasetAttributes getTestAttributes() {
method writeReadChunksTest (line 131) | @Test
method ensureKeysExist (line 248) | private void ensureKeysExist(KeyValueAccess kva, URI uri, String dataset,
method ensureKeysDoNotExist (line 257) | private void ensureKeysDoNotExist(KeyValueAccess kva, URI uri, String ...
method writeShardDataSizeTest (line 266) | @Test
method writeReadChunkTest (line 353) | @Test
method writeReadShardTest (line 394) | @Test
method numReadsTest (line 473) | public void numReadsTest() {
method shardExistsTest (line 525) | @Test
method testPartialReadAggregationBehavior (line 585) | @Test
method range (line 654) | private int[] range(int N) {
FILE: src/test/java/org/janelia/saalfeldlab/n5/shard/TestPositionValueAccess.java
class TestPositionValueAccess (line 22) | public class TestPositionValueAccess implements PositionValueAccess {
method get (line 26) | @Override
method set (line 32) | public void set(final long[] key, final ReadData data) {
method exists (line 43) | @Override
method remove (line 48) | @Override
class Key (line 53) | private static class Key {
method Key (line 57) | Key(long[] data) {
method equals (line 62) | @Override
method hashCode (line 72) | @Override
class ClosableWrapper (line 79) | private static class ClosableWrapper implements VolatileReadData {
method ClosableWrapper (line 83) | ClosableWrapper(final ReadData delegate) {
method length (line 87) | @Override
method requireLength (line 92) | @Override
method limit (line 97) | @Override
method slice (line 102) | @Override
method slice (line 107) | @Override
method inputStream (line 112) | @Override
method allBytes (line 117) | @Override
method toByteBuffer (line 122) | @Override
method materialize (line 127) | @Override
method writeTo (line 133) | @Override
method prefetch (line 138) | @Override
method encode (line 143) | @Override
method close (line 148) | @Override
FILE: src/test/java/org/janelia/saalfeldlab/n5/shard/WriteRegionTest.java
class WriteRegionTest (line 18) | public class WriteRegionTest {
method testWriteRegion (line 21) | @Test
method testWriteRegionSharded (line 91) | @Test
method checkChunk (line 233) | private static void checkChunk(final DataBlock<byte[]> chunk, final bo...
method checkKey (line 252) | private static void checkKey(PositionValueAccess pva, long[] position,...
method createDataBlock (line 263) | private static DataBlock<byte[]> createDataBlock(int[] size, long[] gr...
class TestDatasetAttributes (line 269) | public static class TestDatasetAttributes extends DatasetAttributes {
method TestDatasetAttributes (line 271) | public TestDatasetAttributes(long[] dimensions, int[] outerBlockSize...
method getDatasetAccess (line 277) | @Override // to make this accessible for the test
FILE: src/test/java/org/janelia/saalfeldlab/n5/shard/WriteShardTest.java
class WriteShardTest (line 23) | public class WriteShardTest {
method main (line 31) | public static void main(String[] args) {
method testShardDatasetAccess (line 95) | @Test
method testWriteNullBlockRemovesShard (line 135) | @Test
method createDataBlock (line 263) | private static DataBlock<int[]> createDataBlock(int[] size, long[] gri...
class TestDatasetAttributes (line 269) | public static class TestDatasetAttributes extends DatasetAttributes {
method TestDatasetAttributes (line 271) | public TestDatasetAttributes(long[] dimensions, int[] outerBlockSize...
method getDatasetAccess (line 277) | @Override // to make this accessible for the test
FILE: src/test/java/org/janelia/saalfeldlab/n5/shard/WriteShardTest2.java
class WriteShardTest2 (line 15) | public class WriteShardTest2 {
method main (line 23) | public static void main(String[] args) {
method createDataBlock (line 90) | private static DataBlock<int[]> createDataBlock(int[] size, long[] gri...
class TestDatasetAttributes (line 96) | public static class TestDatasetAttributes extends DatasetAttributes {
method TestDatasetAttributes (line 98) | public TestDatasetAttributes(long[] dimensions, int[] outerBlockSize...
method getDatasetAccess (line 104) | @Override // to make this accessible for the test
FILE: src/test/java/org/janelia/saalfeldlab/n5/shard/WriteShardTestTruncate.java
class WriteShardTestTruncate (line 15) | public class WriteShardTestTruncate {
method main (line 23) | public static void main(String[] args) {
method createDataBlock (line 98) | private static DataBlock<int[]> createDataBlock(int[] size, long[] gri...
class TestDatasetAttributes (line 104) | public static class TestDatasetAttributes extends DatasetAttributes {
method TestDatasetAttributes (line 106) | public TestDatasetAttributes(long[] dimensions, int[] outerBlockSize...
method getDatasetAccess (line 112) | @Override // to make this accessible for the test
FILE: src/test/java/org/janelia/saalfeldlab/n5/url/UriAttributeTest.java
class UriAttributeTest (line 25) | public class UriAttributeTest {
method before (line 41) | @Before
method testRootAttributes (line 58) | @SuppressWarnings("unchecked")
method testPathAttributes (line 107) | @Test
method getAttribute (line 157) | private <T> T getAttribute(
method getAttribute (line 165) | private <T> T getAttribute(
method getAttribute (line 175) | private <T> T getAttribute(
method getAttribute (line 183) | private <T> T getAttribute(
method testPathObject (line 193) | @Test
method mapsEqual (line 225) | private <K, V> boolean mapsEqual(final Map<K, V> a, final Map<K, V> b) {
class TestObject (line 238) | private static class TestObject<T> {
method TestObject (line 246) | public TestObject(final String type, final String name, final T t) {
method t (line 253) | public T t() {
method equals (line 258) | @Override
class TestDoubles (line 271) | public static class TestDoubles extends TestObject<double[]> {
method TestDoubles (line 273) | public TestDoubles(final String type, final String name, final doubl...
method equals (line 278) | @Override
class TestInts (line 291) | private static class TestInts extends TestObject<int[]> {
method TestInts (line 293) | public TestInts(final String type, final String name, final int[] t) {
method equals (line 298) | @Override
Condensed preview — 200 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,049K chars).
[
{
"path": ".github/build.sh",
"chars": 111,
"preview": "#!/bin/sh\ncurl -fsLO https://raw.githubusercontent.com/scijava/scijava-scripts/main/ci-build.sh\nsh ci-build.sh\n"
},
{
"path": ".github/setup.sh",
"chars": 301,
"preview": "#!/bin/sh\ncurl -fsLO https://raw.githubusercontent.com/scijava/scijava-scripts/main/ci-setup-github-actions.sh\nsh ci-set"
},
{
"path": ".github/workflows/build.yml",
"chars": 1089,
"preview": "name: build\n\non:\n push:\n branches:\n - master\n - development\n tags:\n - \"*-[0-9]+.*\"\n pull_request:"
},
{
"path": ".gitignore",
"chars": 243,
"preview": "*.class\n\n# Mobile Tools for Java (J2ME)\n.mtj.tmp/\n\n# Package Files #\n*.jar\n*.war\n*.ear\n\n# virtual machine crash logs, se"
},
{
"path": "LICENSE.md",
"chars": 1330,
"preview": "## BSD 2-Clause License\n\nCopyright (c) 2017-2026, Stephan Saalfeld\n\nAll rights reserved.\n\nRedistribution and use in sour"
},
{
"path": "README.md",
"chars": 7165,
"preview": "# N5 [](https://github.com/saalf"
},
{
"path": "doc/LICENSE.md",
"chars": 1359,
"preview": "## BSD 2-Clause License\n\nCopyright (c) @project.inceptionYear@-@current.year@, Stephan Saalfeld\n\nAll rights reserved.\n\nR"
},
{
"path": "doc/README.md",
"chars": 7189,
"preview": "# N5 [](https://github.com/saalf"
},
{
"path": "doc/n5-eclipse-style.xml",
"chars": 33412,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<profiles version=\"13\">\n<profile kind=\"CodeFormatterProfile\" name"
},
{
"path": "pom.xml",
"chars": 8121,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2"
},
{
"path": "scripts/fsLockValidation",
"chars": 1389,
"preview": "#!/bin/bash\n\n#\n# Run FsLockingValidation N times in parallel.\n#\n# Usage:\n# [N=<processes>] ./fsLockValidation [FsLocki"
},
{
"path": "scripts/writeLockTest.sh",
"chars": 603,
"preview": "#!/usr/bin/env bash\nset -euo pipefail\n\nTEST_DIR=/tmp/write-lock-test.zarr\n\n[ -d \"$TEST_DIR\" ] && rm -r -- \"$TEST_DIR\"\n\ni"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/AbstractDataBlock.java",
"chars": 961,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport java.util.function.ToIntFunction;\n\n/**\n * Abstract base class for {@link Dat"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/BufferedKvaLockedChannel.java",
"chars": 1614,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport org.apache.commons.io.input.ProxyInputStream;\nimport org.janelia.saalfeldlab"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/ByteArrayDataBlock.java",
"chars": 255,
"preview": "package org.janelia.saalfeldlab.n5;\n\npublic class ByteArrayDataBlock extends AbstractDataBlock<byte[]> {\n\n\tpublic ByteAr"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/Bzip2Compression.java",
"chars": 1490,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport java.io.IOException;\n\nimport org.apache.commons.compress.compressors.bzip2.B"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/CachedGsonKeyValueN5Reader.java",
"chars": 6838,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport java.lang.reflect.Type;\n\nimport com.google.gson.JsonSyntaxException;\nimport "
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/CachedGsonKeyValueN5Writer.java",
"chars": 3974,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport org.janelia.saalfeldlab.n5.N5Exception.N5IOException;\n\nimport com.google.gso"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/ChannelLock.java",
"chars": 4044,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport java.io.Closeable;\nimport java.io.IOException;\nimport java.io.UncheckedIOExc"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/Compression.java",
"chars": 1766,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport java.io.Serializable;\nimport java.lang.annotation.ElementType;\nimport java.l"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/CompressionAdapter.java",
"chars": 5556,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.Field;\nimport java.l"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/DataBlock.java",
"chars": 2103,
"preview": "package org.janelia.saalfeldlab.n5;\n\n/**\n * Interface for data blocks. A data block has data, a position on the block\n *"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/DataType.java",
"chars": 4445,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport java.lang.reflect.Type;\n\nimport com.google.gson.JsonDeserializationContext;\n"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/DatasetAttributes.java",
"chars": 15960,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport com.google.gson.JsonDeserializationContext;\nimport com.google.gson.JsonDeser"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/DoubleArrayDataBlock.java",
"chars": 263,
"preview": "package org.janelia.saalfeldlab.n5;\n\npublic class DoubleArrayDataBlock extends AbstractDataBlock<double[]> {\n\n\tpublic Do"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/FileKeyLockManager.java",
"chars": 4403,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport java.io.IOException;\nimport java.lang.ref.ReferenceQueue;\nimport java.lang.r"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/FileSystemKeyValueAccess.java",
"chars": 15802,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.io.UncheckedIOExceptio"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/FloatArrayDataBlock.java",
"chars": 259,
"preview": "package org.janelia.saalfeldlab.n5;\n\npublic class FloatArrayDataBlock extends AbstractDataBlock<float[]> {\n\n\tpublic Floa"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/FsIoPolicy.java",
"chars": 7984,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport org.janelia.saalfeldlab.n5.readdata.LazyRead;\nimport org.janelia.saalfeldlab"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/GsonKeyValueN5Reader.java",
"chars": 5234,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport java.io.InputStreamReader;\nimport java.io.UncheckedIOException;\nimport java."
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/GsonKeyValueN5Writer.java",
"chars": 11552,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport java.io.OutputStreamWriter;\nimport java.io.UncheckedIOException;\nimport java"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/GsonN5Reader.java",
"chars": 2941,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport java.lang.reflect.Type;\nimport java.util.Map;\n\nimport com.google.gson.JsonDe"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/GsonN5Writer.java",
"chars": 717,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport com.google.gson.Gson;\nimport com.google.gson.JsonElement;\n\n/**\n * {@link N5W"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/GsonUtils.java",
"chars": 19612,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport java.io.IOException;\nimport java.io.Reader;\nimport java.io.Writer;\nimport ja"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/GzipCompression.java",
"chars": 2916,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.util.zip.Deflat"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/HttpKeyValueAccess.java",
"chars": 14387,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport org.apache.commons.io.IOUtils;\n\nimport org.apache.commons.lang3.function.Tri"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/IntArrayDataBlock.java",
"chars": 251,
"preview": "package org.janelia.saalfeldlab.n5;\n\npublic class IntArrayDataBlock extends AbstractDataBlock<int[]> {\n\n\tpublic IntArray"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/IoPolicy.java",
"chars": 1362,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport org.janelia.saalfeldlab.n5.readdata.ReadData;\nimport org.janelia.saalfeldlab"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/KeyLockState.java",
"chars": 3412,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport java.io.IOException;\nimport java.nio.channels.FileChannel;\nimport java.nio.f"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/KeyValueAccess.java",
"chars": 11542,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport org.janelia.saalfeldlab.n5.N5Exception.N5IOException;\n\nimport java.net.URI;\n"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/LinkedAttributePathToken.java",
"chars": 8458,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport java.util.Iterator;\n\nimport com.google.gson.Gson;\nimport com.google.gson.Jso"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/LockedChannel.java",
"chars": 1263,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport org.janelia.saalfeldlab.n5.N5Exception.N5IOException;\n\nimport java.io.Closea"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/LockedFileChannel.java",
"chars": 2921,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport java.io.Closeable;\nimport java.io.IOException;\nimport java.io.OutputStream;\n"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/LockingPolicy.java",
"chars": 1637,
"preview": "package org.janelia.saalfeldlab.n5;\n\n/**\n * File locking policy.\n * <p>\n * Usually, we want to coordinate reads and writ"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/LongArrayDataBlock.java",
"chars": 255,
"preview": "package org.janelia.saalfeldlab.n5;\n\npublic class LongArrayDataBlock extends AbstractDataBlock<long[]> {\n\n\tpublic LongAr"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/Lz4Compression.java",
"chars": 1172,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport net.jpountz.lz4.LZ4BlockInputStream;\nimport net.jpountz.lz4.LZ4BlockOutputSt"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/N5Exception.java",
"chars": 3853,
"preview": "package org.janelia.saalfeldlab.n5;\n\npublic class N5Exception extends RuntimeException {\n\n\tpublic N5Exception() {\n\n\t\tsup"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/N5FSReader.java",
"chars": 3573,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport java.nio.file.FileSystems;\n\nimport com.google.gson.Gson;\nimport com.google.g"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/N5FSWriter.java",
"chars": 4501,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport java.nio.file.FileSystems;\n\nimport com.google.gson.GsonBuilder;\n\n/**\n * File"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/N5KeyValueReader.java",
"chars": 5270,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport java.net.URI;\nimport java.net.URISyntaxException;\n\nimport com.google.gson.Js"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/N5KeyValueWriter.java",
"chars": 2035,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport com.google.gson.GsonBuilder;\n\n/**\n * Filesystem {@link N5Writer} implementat"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/N5Reader.java",
"chars": 25215,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.IOException;\nimport java.io.Obj"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/N5URI.java",
"chars": 23101,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport java.net.URI;\nimport java.net.URISyntaxException;\nimport java.nio.ByteBuffer"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/N5Writer.java",
"chars": 15564,
"preview": "package org.janelia.saalfeldlab.n5;\n\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.io.O"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/NameConfigAdapter.java",
"chars": 8469,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport com.google.gson.JsonArray;\nimport com.google.gson.JsonDeserializationContext"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/RawCompression.java",
"chars": 855,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport org.janelia.saalfeldlab.n5.Compression.CompressionType;\nimport org.janelia.s"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/ReflectionUtils.java",
"chars": 1224,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport java.lang.reflect.Field;\nimport java.lang.reflect.Modifier;\n\nclass Reflectio"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/ShortArrayDataBlock.java",
"chars": 259,
"preview": "package org.janelia.saalfeldlab.n5;\n\npublic class ShortArrayDataBlock extends AbstractDataBlock<short[]> {\n\n\tpublic Shor"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/StringDataBlock.java",
"chars": 1792,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport java.nio.ByteBuffer;\nimport java.nio.charset.Charset;\nimport java.nio.charse"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/XzCompression.java",
"chars": 1390,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport java.io.IOException;\nimport org.apache.commons.compress.compressors.xz.XZCom"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/cache/N5JsonCache.java",
"chars": 11795,
"preview": "package org.janelia.saalfeldlab.n5.cache;\n\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.HashM"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/cache/N5JsonCacheableContainer.java",
"chars": 3039,
"preview": "package org.janelia.saalfeldlab.n5.cache;\n\nimport org.janelia.saalfeldlab.n5.CachedGsonKeyValueN5Reader;\nimport org.jane"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/codec/BlockCodec.java",
"chars": 2413,
"preview": "package org.janelia.saalfeldlab.n5.codec;\n\nimport org.janelia.saalfeldlab.n5.DataBlock;\nimport org.janelia.saalfeldlab.n"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/codec/BlockCodecInfo.java",
"chars": 1240,
"preview": "package org.janelia.saalfeldlab.n5.codec;\n\nimport org.janelia.saalfeldlab.n5.DataBlock;\nimport org.janelia.saalfeldlab.n"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/codec/CodecInfo.java",
"chars": 487,
"preview": "package org.janelia.saalfeldlab.n5.codec;\n\nimport java.io.Serializable;\nimport org.janelia.saalfeldlab.n5.serialization."
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/codec/CodecParser.java",
"chars": 2007,
"preview": "package org.janelia.saalfeldlab.n5.codec;\n\nimport java.util.ArrayList;\n\nimport org.janelia.saalfeldlab.n5.DatasetAttribu"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/codec/ConcatenatedDataCodec.java",
"chars": 697,
"preview": "package org.janelia.saalfeldlab.n5.codec;\n\nimport org.janelia.saalfeldlab.n5.readdata.ReadData;\n\nclass ConcatenatedDataC"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/codec/ConcatenatedDeterministicSizeDataCodec.java",
"chars": 504,
"preview": "package org.janelia.saalfeldlab.n5.codec;\n\nclass ConcatenatedDeterministicSizeDataCodec extends ConcatenatedDataCodec im"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/codec/DataCodec.java",
"chars": 2262,
"preview": "package org.janelia.saalfeldlab.n5.codec;\n\nimport java.util.Arrays;\nimport org.janelia.saalfeldlab.n5.N5Exception.N5IOEx"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/codec/DataCodecInfo.java",
"chars": 400,
"preview": "package org.janelia.saalfeldlab.n5.codec;\n\nimport org.janelia.saalfeldlab.n5.readdata.ReadData;\nimport org.janelia.saalf"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/codec/DatasetCodec.java",
"chars": 1708,
"preview": "package org.janelia.saalfeldlab.n5.codec;\n\nimport org.janelia.saalfeldlab.n5.DataBlock;\nimport org.janelia.saalfeldlab.n"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/codec/DatasetCodecInfo.java",
"chars": 637,
"preview": "package org.janelia.saalfeldlab.n5.codec;\n\nimport org.janelia.saalfeldlab.n5.DataBlock;\nimport org.janelia.saalfeldlab.n"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/codec/DeterministicSizeCodecInfo.java",
"chars": 380,
"preview": "package org.janelia.saalfeldlab.n5.codec;\n\n/**\n * A {@link CodecInfo} that can deterministically determine the size of e"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/codec/DeterministicSizeDataCodec.java",
"chars": 1038,
"preview": "package org.janelia.saalfeldlab.n5.codec;\n\n/**\n * A {@link DataCodec} that can deterministically determine the size of e"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/codec/FlatArrayCodec.java",
"chars": 11108,
"preview": "package org.janelia.saalfeldlab.n5.codec;\n\nimport java.io.DataInputStream;\nimport java.io.IOException;\nimport java.io.In"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/codec/IdentityCodec.java",
"chars": 735,
"preview": "package org.janelia.saalfeldlab.n5.codec;\n\nimport org.janelia.saalfeldlab.n5.readdata.ReadData;\nimport org.janelia.saalf"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/codec/IndexCodecAdapter.java",
"chars": 1405,
"preview": "package org.janelia.saalfeldlab.n5.codec;\n\npublic class IndexCodecAdapter {\n\n\tprivate final BlockCodecInfo blockCodecInf"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/codec/N5BlockCodecInfo.java",
"chars": 1303,
"preview": "package org.janelia.saalfeldlab.n5.codec;\n\nimport org.janelia.saalfeldlab.n5.DataBlock;\nimport org.janelia.saalfeldlab.n"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/codec/N5BlockCodecs.java",
"chars": 12095,
"preview": "package org.janelia.saalfeldlab.n5.codec;\n\nimport java.io.DataInputStream;\nimport java.io.DataOutputStream;\nimport java."
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/codec/RawBlockCodecInfo.java",
"chars": 2460,
"preview": "package org.janelia.saalfeldlab.n5.codec;\n\nimport java.nio.ByteOrder;\n\nimport com.google.gson.JsonDeserializationContext"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/codec/RawBlockCodecs.java",
"chars": 5051,
"preview": "package org.janelia.saalfeldlab.n5.codec;\n\nimport org.janelia.saalfeldlab.n5.ByteArrayDataBlock;\nimport org.janelia.saal"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/codec/checksum/ChecksumCodec.java",
"chars": 3918,
"preview": "package org.janelia.saalfeldlab.n5.codec.checksum;\n\nimport java.io.IOException;\nimport java.io.OutputStream;\nimport java"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/codec/checksum/ChecksumException.java",
"chars": 247,
"preview": "package org.janelia.saalfeldlab.n5.codec.checksum;\n\npublic class ChecksumException extends Exception {\n\n\tprivate static "
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/codec/checksum/Crc32cChecksumCodec.java",
"chars": 942,
"preview": "package org.janelia.saalfeldlab.n5.codec.checksum;\n\nimport org.apache.commons.codec.digest.PureJavaCrc32C;\nimport org.ja"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/codec/transpose/Transpose.java",
"chars": 3281,
"preview": "package org.janelia.saalfeldlab.n5.codec.transpose;\n\nimport org.janelia.saalfeldlab.n5.DataType;\nimport org.janelia.saal"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/codec/transpose/TransposeCodec.java",
"chars": 2859,
"preview": "package org.janelia.saalfeldlab.n5.codec.transpose;\n\nimport org.janelia.saalfeldlab.n5.DataBlock;\nimport org.janelia.saa"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/codec/transpose/TransposeCodecInfo.java",
"chars": 2591,
"preview": "package org.janelia.saalfeldlab.n5.codec.transpose;\n\nimport java.util.Arrays;\nimport java.util.stream.IntStream;\n\nimport"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/http/ApacheListResponseParser.java",
"chars": 962,
"preview": "package org.janelia.saalfeldlab.n5.http;\n\nimport java.util.regex.Pattern;\n\n/**\n * {@link ListResponseParser}s for <a hre"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/http/CandidateListResponseParser.java",
"chars": 809,
"preview": "package org.janelia.saalfeldlab.n5.http;\n\nclass CandidateListResponseParser implements ListResponseParser {\n\n\tprivate Li"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/http/ListResponseParser.java",
"chars": 905,
"preview": "package org.janelia.saalfeldlab.n5.http;\n\npublic interface ListResponseParser {\n\n\t/**\n\t * Parse a String response for a "
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/http/MicrosoftListResponseParser.java",
"chars": 998,
"preview": "package org.janelia.saalfeldlab.n5.http;\n\nimport java.util.regex.Pattern;\n\n/**\n * {@link ListResponseParser}s for <a hre"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/http/PatternListResponseParser.java",
"chars": 823,
"preview": "package org.janelia.saalfeldlab.n5.http;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.regex.Matc"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/http/PythonListResponseParser.java",
"chars": 960,
"preview": "package org.janelia.saalfeldlab.n5.http;\n\nimport java.util.regex.Pattern;\n\n/**\n * {@link ListResponseParser}s for <a hre"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/readdata/ByteArrayReadData.java",
"chars": 1693,
"preview": "package org.janelia.saalfeldlab.n5.readdata;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.InputStream;\nimport ja"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/readdata/InputStreamReadData.java",
"chars": 2100,
"preview": "package org.janelia.saalfeldlab.n5.readdata;\n\nimport java.io.DataInputStream;\nimport java.io.IOException;\nimport java.io"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/readdata/LazyGeneratedReadData.java",
"chars": 2836,
"preview": "package org.janelia.saalfeldlab.n5.readdata;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport j"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/readdata/LazyRead.java",
"chars": 1789,
"preview": "package org.janelia.saalfeldlab.n5.readdata;\n\nimport java.io.Closeable;\nimport java.util.Collection;\nimport org.janelia."
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/readdata/LazyReadData.java",
"chars": 2861,
"preview": "package org.janelia.saalfeldlab.n5.readdata;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.util.C"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/readdata/Range.java",
"chars": 3015,
"preview": "package org.janelia.saalfeldlab.n5.readdata;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util."
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/readdata/ReadData.java",
"chars": 10852,
"preview": "package org.janelia.saalfeldlab.n5.readdata;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.Out"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/readdata/VolatileReadData.java",
"chars": 1134,
"preview": "package org.janelia.saalfeldlab.n5.readdata;\n\nimport org.janelia.saalfeldlab.n5.N5Exception.N5IOException;\nimport org.ja"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/readdata/prefetch/AggregatingPrefetchLazyRead.java",
"chars": 1319,
"preview": "package org.janelia.saalfeldlab.n5.readdata.prefetch;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\n\nimport "
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/readdata/prefetch/EnclosingPrefetchLazyRead.java",
"chars": 1452,
"preview": "package org.janelia.saalfeldlab.n5.readdata.prefetch;\n\nimport java.util.Collection;\nimport org.janelia.saalfeldlab.n5.N5"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/readdata/prefetch/SliceTrackingLazyRead.java",
"chars": 2354,
"preview": "package org.janelia.saalfeldlab.n5.readdata.prefetch;\n\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport ja"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/readdata/prefetch/Slices.java",
"chars": 3575,
"preview": "package org.janelia.saalfeldlab.n5.readdata.prefetch;\n\nimport java.util.Collections;\nimport java.util.Comparator;\nimport"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/readdata/segment/ConcatenatedReadData.java",
"chars": 6303,
"preview": "package org.janelia.saalfeldlab.n5.readdata.segment;\n\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport ja"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/readdata/segment/DefaultSegmentedReadData.java",
"chars": 7922,
"preview": "package org.janelia.saalfeldlab.n5.readdata.segment;\n\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport ja"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/readdata/segment/Segment.java",
"chars": 758,
"preview": "package org.janelia.saalfeldlab.n5.readdata.segment;\n\n/**\n * A particular segment in a source {@link SegmentedReadData}."
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/readdata/segment/SegmentedReadData.java",
"chars": 6117,
"preview": "package org.janelia.saalfeldlab.n5.readdata.segment;\n\nimport java.io.OutputStream;\nimport java.util.Arrays;\nimport java."
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/serialization/JsonArrayUtils.java",
"chars": 585,
"preview": "package org.janelia.saalfeldlab.n5.serialization;\n\nimport com.google.gson.JsonArray;\nimport com.google.gson.JsonElement;"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/serialization/N5Annotations.java",
"chars": 1268,
"preview": "package org.janelia.saalfeldlab.n5.serialization;\n\nimport java.io.Serializable;\nimport java.lang.annotation.ElementType;"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/serialization/NameConfig.java",
"chars": 3817,
"preview": "package org.janelia.saalfeldlab.n5.serialization;\n\nimport org.scijava.annotations.Indexable;\n\nimport java.io.Serializabl"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/shard/DatasetAccess.java",
"chars": 5818,
"preview": "package org.janelia.saalfeldlab.n5.shard;\n\nimport java.util.List;\nimport java.util.concurrent.ExecutionException;\nimport"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/shard/DefaultDatasetAccess.java",
"chars": 41458,
"preview": "package org.janelia.saalfeldlab.n5.shard;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Compara"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/shard/DefaultShardCodecInfo.java",
"chars": 5542,
"preview": "package org.janelia.saalfeldlab.n5.shard;\n\nimport java.util.Arrays;\nimport org.janelia.saalfeldlab.n5.DataType;\nimport o"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/shard/Nesting.java",
"chars": 18927,
"preview": "package org.janelia.saalfeldlab.n5.shard;\n\n\nimport java.util.Arrays;\nimport java.util.Objects;\n\n/**\n * Container for cla"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/shard/PositionValueAccess.java",
"chars": 3595,
"preview": "package org.janelia.saalfeldlab.n5.shard;\n\nimport java.net.URI;\n\nimport org.janelia.saalfeldlab.n5.DatasetAttributes;\nim"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/shard/RawShard.java",
"chars": 2078,
"preview": "package org.janelia.saalfeldlab.n5.shard;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Lis"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/shard/RawShardCodec.java",
"chars": 3462,
"preview": "package org.janelia.saalfeldlab.n5.shard;\n\nimport static org.janelia.saalfeldlab.n5.shard.ShardIndex.IndexLocation.START"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/shard/RawShardDataBlock.java",
"chars": 926,
"preview": "package org.janelia.saalfeldlab.n5.shard;\n\nimport org.janelia.saalfeldlab.n5.DataBlock;\n\n/**\n * Wrap a RawShard as a Dat"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/shard/Region.java",
"chars": 4756,
"preview": "package org.janelia.saalfeldlab.n5.shard;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\ni"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/shard/ShardCodecInfo.java",
"chars": 1630,
"preview": "package org.janelia.saalfeldlab.n5.shard;\n\nimport org.janelia.saalfeldlab.n5.DataType;\nimport org.janelia.saalfeldlab.n5"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/shard/ShardIndex.java",
"chars": 6818,
"preview": "package org.janelia.saalfeldlab.n5.shard;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Iterato"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/util/FloatValueParser.java",
"chars": 3203,
"preview": "package org.janelia.saalfeldlab.n5.util;\n\nimport org.apache.commons.codec.DecoderException;\nimport org.apache.commons.co"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/util/MemCopy.java",
"chars": 3915,
"preview": "package org.janelia.saalfeldlab.n5.util;\n\nimport org.janelia.saalfeldlab.n5.DataType;\n\n/**\n * Low-level range copying me"
},
{
"path": "src/main/java/org/janelia/saalfeldlab/n5/util/SubArrayCopy.java",
"chars": 4438,
"preview": "package org.janelia.saalfeldlab.n5.util;\n\n/**\n * Copy sub-region between flattened arrays (of different sizes).\n * <p>\n "
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/AbstractN5Test.java",
"chars": 80104,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport static org.junit.Assert.assertArrayEquals;\nimport static org.junit.Assert.as"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/DatasetAttributesTest.java",
"chars": 6851,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport static org.junit.Assert.assertArrayEquals;\nimport static org.junit.Assert.as"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/FileKeyLockManagerTest.java",
"chars": 11989,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport java.io.Closeable;\nimport java.io.IOException;\nimport java.io.OutputStream;\n"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/FsLockTest.java",
"chars": 6694,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport org.junit.Test;\n\nimport java.io.File;\nimport java.io.IOException;\nimport jav"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/N5Benchmark.java",
"chars": 12154,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport static org.junit.Assert.fail;\n\nimport java.io.File;\nimport java.io.IOExcepti"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/N5CachedFSTest.java",
"chars": 22894,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertF"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/N5FSTest.java",
"chars": 2024,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertT"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/N5ReadBenchmark.java",
"chars": 3873,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport com.google.gson.GsonBuilder;\nimport java.io.File;\nimport java.io.IOException"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/N5URITest.java",
"chars": 6161,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport org.junit.Test;\n\nimport java.net.URISyntaxException;\n\nimport static org.juni"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/TrackingN5Writer.java",
"chars": 1232,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport com.google.gson.GsonBuilder;\nimport org.janelia.saalfeldlab.n5.kva.TrackingK"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/UriTest.java",
"chars": 1256,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport static org.junit.Assert.assertEquals;\n\nimport java.net.URI;\nimport java.net."
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/WriteLockExp.java",
"chars": 2899,
"preview": "package org.janelia.saalfeldlab.n5;\n\nimport java.util.Arrays;\n\n\nimport org.janelia.saalfeldlab.n5.N5Writer.DataBlockSupp"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/backward/CompatibilityTest.java",
"chars": 3842,
"preview": "package org.janelia.saalfeldlab.n5.backward;\n\nimport static org.junit.Assert.assertArrayEquals;\nimport static org.junit."
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/backward/CreateSampleData.java",
"chars": 2043,
"preview": "package org.janelia.saalfeldlab.n5.backward;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.Arrays;\n"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/benchmarks/N5BlockWriteBenchmarks.java",
"chars": 5257,
"preview": "package org.janelia.saalfeldlab.n5.benchmarks;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.file.Fi"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/benchmarks/ReadDataBenchmarks.java",
"chars": 3739,
"preview": "package org.janelia.saalfeldlab.n5.benchmarks;\n\nimport java.io.IOException;\nimport java.nio.file.Files;\nimport java.nio."
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/cache/N5CacheTest.java",
"chars": 11656,
"preview": "package org.janelia.saalfeldlab.n5.cache;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.a"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/codec/BlockCodecTests.java",
"chars": 10550,
"preview": "package org.janelia.saalfeldlab.n5.codec;\n\nimport static org.junit.Assert.assertArrayEquals;\nimport static org.junit.Ass"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/codec/BytesCodecTests.java",
"chars": 4949,
"preview": "package org.janelia.saalfeldlab.n5.codec;\n\nimport static org.junit.Assert.assertArrayEquals;\nimport static org.junit.Ass"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/codec/ChecksumCodecTests.java",
"chars": 1155,
"preview": "package org.janelia.saalfeldlab.n5.codec;\n\nimport static org.junit.Assert.assertArrayEquals;\nimport static org.junit.Ass"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/codec/DatasetCodecTests.java",
"chars": 2335,
"preview": "package org.janelia.saalfeldlab.n5.codec;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.a"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/compression/CompressionTypesTest.java",
"chars": 1469,
"preview": "package org.janelia.saalfeldlab.n5.compression;\n\nimport java.lang.reflect.Field;\nimport java.util.Map;\n\nimport org.apach"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/demo/AttributePathDemo.java",
"chars": 8244,
"preview": "package org.janelia.saalfeldlab.n5.demo;\n\nimport java.io.IOException;\nimport java.nio.charset.Charset;\nimport java.nio.f"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/http/HttpKeyValueAccessTest.java",
"chars": 1747,
"preview": "package org.janelia.saalfeldlab.n5.http;\n\nimport org.apache.commons.io.IOUtils;\nimport org.janelia.saalfeldlab.n5.HttpKe"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/http/HttpReaderFsWriter.java",
"chars": 9697,
"preview": "package org.janelia.saalfeldlab.n5.http;\n\nimport com.google.gson.Gson;\nimport com.google.gson.JsonElement;\nimport org.ja"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/http/N5HttpTest.java",
"chars": 3938,
"preview": "package org.janelia.saalfeldlab.n5.http;\n\nimport com.google.gson.GsonBuilder;\nimport org.janelia.saalfeldlab.n5.Abstract"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/http/RunnerWithHttpServer.java",
"chars": 5063,
"preview": "package org.janelia.saalfeldlab.n5.http;\n\nimport org.junit.After;\nimport org.junit.Before;\nimport org.junit.internal.run"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/kva/AbstractKeyValueAccessTest.java",
"chars": 8731,
"preview": "package org.janelia.saalfeldlab.n5.kva;\n\nimport org.janelia.saalfeldlab.n5.KeyValueAccess;\nimport org.janelia.saalfeldla"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/kva/DelegateKeyValueAccess.java",
"chars": 2634,
"preview": "package org.janelia.saalfeldlab.n5.kva;\n\nimport org.janelia.saalfeldlab.n5.KeyValueAccess;\nimport org.janelia.saalfeldla"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/kva/FileSystemKeyValueAccessTest.java",
"chars": 6109,
"preview": "package org.janelia.saalfeldlab.n5.kva;\n\nimport static org.junit.Assert.assertArrayEquals;\nimport static org.junit.Asser"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/kva/FsLockingValidation.java",
"chars": 3307,
"preview": "package org.janelia.saalfeldlab.n5.kva;\n\nimport java.util.Arrays;\nimport java.util.Random;\nimport java.util.concurrent.C"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/kva/HttpKeyValueAccessTest.java",
"chars": 1086,
"preview": "package org.janelia.saalfeldlab.n5.kva;\n\nimport org.janelia.saalfeldlab.n5.AbstractN5Test;\nimport org.janelia.saalfeldla"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/kva/TrackingKeyValueAccess.java",
"chars": 1943,
"preview": "package org.janelia.saalfeldlab.n5.kva;\n\nimport org.janelia.saalfeldlab.n5.KeyValueAccess;\nimport org.janelia.saalfeldla"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/locking/JustFileChannels.java",
"chars": 5122,
"preview": "package org.janelia.saalfeldlab.n5.locking;\n\nimport java.io.IOException;\nimport java.nio.ByteBuffer;\nimport java.nio.cha"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/locking/JustFileChannelsThreaded.java",
"chars": 772,
"preview": "package org.janelia.saalfeldlab.n5.locking;\n\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Ex"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/readdata/RangeTests.java",
"chars": 1759,
"preview": "package org.janelia.saalfeldlab.n5.readdata;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Asser"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/readdata/ReadDataTests.java",
"chars": 4793,
"preview": "package org.janelia.saalfeldlab.n5.readdata;\n\nimport static org.junit.Assert.assertArrayEquals;\nimport static org.junit."
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/readdata/prefetch/SliceTrackingLazyReadTests.java",
"chars": 7282,
"preview": "package org.janelia.saalfeldlab.n5.readdata.prefetch;\n\nimport static org.junit.Assert.assertEquals;\n\nimport java.io.IOEx"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/readdata/prefetch/SlicesTest.java",
"chars": 3729,
"preview": "package org.janelia.saalfeldlab.n5.readdata.prefetch;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport org.jan"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/readdata/segment/ConcatenatedReadDataTest.java",
"chars": 5861,
"preview": "package org.janelia.saalfeldlab.n5.readdata.segment;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.ByteArrayOutpu"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/readdata/segment/SegmentTest.java",
"chars": 5176,
"preview": "package org.janelia.saalfeldlab.n5.readdata.segment;\n\nimport java.io.ByteArrayInputStream;\nimport java.util.List;\nimport"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/serialization/CodecSerializationTest.java",
"chars": 3346,
"preview": "package org.janelia.saalfeldlab.n5.serialization;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit."
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/shard/DatasetAccessTest.java",
"chars": 8683,
"preview": "package org.janelia.saalfeldlab.n5.shard;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\ni"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/shard/NestedGridTest.java",
"chars": 5268,
"preview": "package org.janelia.saalfeldlab.n5.shard;\n\nimport static org.junit.Assert.assertArrayEquals;\nimport static org.junit.Ass"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/shard/ShardTest.java",
"chars": 22423,
"preview": "package org.janelia.saalfeldlab.n5.shard;\n\nimport java.io.File;\nimport java.net.URI;\nimport java.net.URISyntaxException;"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/shard/TestPositionValueAccess.java",
"chars": 3495,
"preview": "package org.janelia.saalfeldlab.n5.shard;\n\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.nio.Byte"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/shard/WriteRegionTest.java",
"chars": 9204,
"preview": "package org.janelia.saalfeldlab.n5.shard;\n\nimport java.util.Arrays;\nimport org.janelia.saalfeldlab.n5.ByteArrayDataBlock"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/shard/WriteShardTest.java",
"chars": 10198,
"preview": "package org.janelia.saalfeldlab.n5.shard;\n\nimport static org.junit.Assert.assertFalse;\nimport static org.junit.Assert.as"
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/shard/WriteShardTest2.java",
"chars": 4461,
"preview": "package org.janelia.saalfeldlab.n5.shard;\n\nimport java.util.Arrays;\nimport org.janelia.saalfeldlab.n5.DataBlock;\nimport "
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/shard/WriteShardTestTruncate.java",
"chars": 4641,
"preview": "package org.janelia.saalfeldlab.n5.shard;\n\nimport java.util.Arrays;\nimport org.janelia.saalfeldlab.n5.DataBlock;\nimport "
},
{
"path": "src/test/java/org/janelia/saalfeldlab/n5/url/UriAttributeTest.java",
"chars": 11514,
"preview": "package org.janelia.saalfeldlab.n5.url;\n\nimport static org.junit.Assert.assertArrayEquals;\nimport static org.junit.Asser"
},
{
"path": "src/test/resources/backward/data-1.5.0.n5/attributes.json",
"chars": 14,
"preview": "{\"n5\":\"1.5.0\"}"
},
{
"path": "src/test/resources/backward/data-1.5.0.n5/raw/attributes.json",
"chars": 81,
"preview": "{\"dataType\":\"uint8\",\"compressionType\":\"raw\",\"blockSize\":[5,4],\"dimensions\":[7,5]}"
},
{
"path": "src/test/resources/backward/data-2.5.1.n5/attributes.json",
"chars": 14,
"preview": "{\"n5\":\"2.5.1\"}"
},
{
"path": "src/test/resources/backward/data-2.5.1.n5/raw/attributes.json",
"chars": 86,
"preview": "{\"dataType\":\"uint8\",\"compression\":{\"type\":\"raw\"},\"blockSize\":[5,4],\"dimensions\":[7,5]}"
},
{
"path": "src/test/resources/backward/data-3.1.3.n5/attributes.json",
"chars": 14,
"preview": "{\"n5\":\"4.0.0\"}"
},
{
"path": "src/test/resources/backward/data-3.1.3.n5/raw/attributes.json",
"chars": 86,
"preview": "{\"dataType\":\"uint8\",\"compression\":{\"type\":\"raw\"},\"blockSize\":[5,4],\"dimensions\":[7,5]}"
},
{
"path": "src/test/resources/url/urlAttributes.n5/a/aa/aaa/attributes.json",
"chars": 23,
"preview": "{\n \"name\" : \"aaa\"\n}\n"
},
{
"path": "src/test/resources/url/urlAttributes.n5/a/aa/attributes.json",
"chars": 22,
"preview": "{\n \"name\" : \"aa\"\n}\n"
},
{
"path": "src/test/resources/url/urlAttributes.n5/a/attributes.json",
"chars": 21,
"preview": "{\n \"name\" : \"a\"\n}\n"
},
{
"path": "src/test/resources/url/urlAttributes.n5/attributes.json",
"chars": 175,
"preview": "{\"n5\":\"2.6.1\",\"foo\":\"bar\",\"f o o\":\"b a r\",\"list\":[0,1,2,3],\"nestedList\":[[[1,2,3,4]],[[10,20,30,40]],[[100,200,300,400]]"
},
{
"path": "src/test/resources/url/urlAttributes.n5/objs/attributes.json",
"chars": 665,
"preview": "{\n \"intsKey\": {\n \"type\": \"ints\",\n \"name\": \"intsName\",\n \"t\": [ 5, 4, 3 ]\n },\n \"doublesKey\": {\n \"type\": \"do"
}
]
// ... and 12 more files (download for full content)
About this extraction
This page contains the full source code of the saalfeldlab/n5 GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 200 files (931.3 KB), approximately 253.0k tokens, and a symbol index with 1847 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.