pub struct GzipCodec { /* private fields */ }
Available on crate feature
gzip
only.Expand description
A gzip
codec implementation.
Implementations§
source§impl GzipCodec
impl GzipCodec
sourcepub fn new(compression_level: u32) -> Result<Self, GzipCompressionLevelError>
pub fn new(compression_level: u32) -> Result<Self, GzipCompressionLevelError>
Create a new gzip
codec.
§Errors
Returns GzipCompressionLevelError
if compression_level
is not valid.
Examples found in repository?
examples/rectangular_array_write_read.rs (line 71)
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
fn rectangular_array_write_read() -> Result<(), Box<dyn std::error::Error>> {
use rayon::prelude::{IntoParallelIterator, ParallelIterator};
use zarrs::array::ChunkGrid;
use zarrs::{
array::{chunk_grid::RectangularChunkGrid, codec, FillValue},
node::Node,
};
use zarrs::{
array::{DataType, ZARR_NAN_F32},
array_subset::ArraySubset,
storage::store,
};
// Create a store
// let path = tempfile::TempDir::new()?;
// let mut store: ReadableWritableListableStorage = Arc::new(store::FilesystemStore::new(path.path())?);
let mut store: ReadableWritableListableStorage = std::sync::Arc::new(store::MemoryStore::new());
if let Some(arg1) = std::env::args().collect::<Vec<_>>().get(1) {
if arg1 == "--usage-log" {
let log_writer = Arc::new(std::sync::Mutex::new(
// std::io::BufWriter::new(
std::io::stdout(),
// )
));
let usage_log = Arc::new(UsageLogStorageTransformer::new(log_writer, || {
chrono::Utc::now().format("[%T%.3f] ").to_string()
}));
store = usage_log
.clone()
.create_readable_writable_listable_transformer(store);
}
}
// Create a group
let group_path = "/group";
let mut group = zarrs::group::GroupBuilder::new().build(store.clone(), group_path)?;
// Update group metadata
group
.attributes_mut()
.insert("foo".into(), serde_json::Value::String("bar".into()));
// Write group metadata to store
group.store_metadata()?;
println!(
"The group metadata is:\n{}\n",
serde_json::to_string_pretty(&group.metadata()).unwrap()
);
// Create an array
let array_path = "/group/array";
let array = zarrs::array::ArrayBuilder::new(
vec![8, 8], // array shape
DataType::Float32,
ChunkGrid::new(RectangularChunkGrid::new(&[
[1, 2, 3, 2].try_into()?,
4.try_into()?,
])),
FillValue::from(ZARR_NAN_F32),
)
.bytes_to_bytes_codecs(vec![
#[cfg(feature = "gzip")]
Box::new(codec::GzipCodec::new(5)?),
])
.dimension_names(["y", "x"].into())
// .storage_transformers(vec![].into())
.build(store.clone(), array_path)?;
// Write array metadata to store
array.store_metadata()?;
// Write some chunks (in parallel)
(0..4).into_par_iter().try_for_each(|i| {
let chunk_grid = array.chunk_grid();
let chunk_indices = vec![i, 0];
if let Some(chunk_shape) = chunk_grid.chunk_shape(&chunk_indices, array.shape())? {
let chunk_array = ndarray::ArrayD::<f32>::from_elem(
chunk_shape
.iter()
.map(|u| u.get() as usize)
.collect::<Vec<_>>(),
i as f32,
);
array.store_chunk_ndarray(&chunk_indices, chunk_array)
} else {
Err(zarrs::array::ArrayError::InvalidChunkGridIndicesError(
chunk_indices.to_vec(),
))
}
})?;
println!(
"The array metadata is:\n{}\n",
serde_json::to_string_pretty(&array.metadata()).unwrap()
);
// Write a subset spanning multiple chunks, including updating chunks already written
array.store_array_subset_ndarray(
&[3, 3], // start
ndarray::ArrayD::<f32>::from_shape_vec(
vec![3, 3],
vec![0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9],
)?,
)?;
// Store elements directly, in this case set the 7th column to 123.0
array.store_array_subset_elements::<f32>(
&ArraySubset::new_with_ranges(&[0..8, 6..7]),
vec![123.0; 8],
)?;
// Store elements directly in a chunk, in this case set the last row of the bottom right chunk
array.store_chunk_subset_elements::<f32>(
// chunk indices
&[3, 1],
// subset within chunk
&ArraySubset::new_with_ranges(&[1..2, 0..4]),
vec![-4.0; 4],
)?;
// Read the whole array
let subset_all = ArraySubset::new_with_shape(array.shape().to_vec());
let data_all = array.retrieve_array_subset_ndarray::<f32>(&subset_all)?;
println!("The whole array is:\n{data_all}\n");
// Read a chunk back from the store
let chunk_indices = vec![1, 0];
let data_chunk = array.retrieve_chunk_ndarray::<f32>(&chunk_indices)?;
println!("Chunk [1,0] is:\n{data_chunk}\n");
// Read the central 4x2 subset of the array
let subset_4x2 = ArraySubset::new_with_ranges(&[2..6, 3..5]); // the center 4x2 region
let data_4x2 = array.retrieve_array_subset_ndarray::<f32>(&subset_4x2)?;
println!("The middle 4x2 subset is:\n{data_4x2}\n");
// Show the hierarchy
let node = Node::new(&*store, "/").unwrap();
let tree = node.hierarchy_tree();
println!("The zarr hierarchy tree is:\n{tree}");
Ok(())
}
More examples
examples/sharded_array_write_read.rs (line 65)
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
fn sharded_array_write_read() -> Result<(), Box<dyn std::error::Error>> {
use zarrs::{
array::{
codec::{self, array_to_bytes::sharding::ShardingCodecBuilder},
DataType, FillValue,
},
array_subset::ArraySubset,
node::Node,
storage::store,
};
use rayon::prelude::{IntoParallelIterator, ParallelIterator};
use std::sync::Arc;
// Create a store
// let path = tempfile::TempDir::new()?;
// let mut store: ReadableWritableListableStorage = Arc::new(store::FilesystemStore::new(path.path())?);
// let mut store: ReadableWritableListableStorage = Arc::new(store::FilesystemStore::new("tests/data/sharded_array_write_read.zarr")?);
let mut store: ReadableWritableListableStorage = Arc::new(store::MemoryStore::new());
if let Some(arg1) = std::env::args().collect::<Vec<_>>().get(1) {
if arg1 == "--usage-log" {
let log_writer = Arc::new(std::sync::Mutex::new(
// std::io::BufWriter::new(
std::io::stdout(),
// )
));
let usage_log = Arc::new(UsageLogStorageTransformer::new(log_writer, || {
chrono::Utc::now().format("[%T%.3f] ").to_string()
}));
store = usage_log
.clone()
.create_readable_writable_listable_transformer(store);
}
}
// Create a group
let group_path = "/group";
let mut group = zarrs::group::GroupBuilder::new().build(store.clone(), group_path)?;
// Update group metadata
group
.attributes_mut()
.insert("foo".into(), serde_json::Value::String("bar".into()));
// Write group metadata to store
group.store_metadata()?;
// Create an array
let array_path = "/group/array";
let shard_shape = vec![4, 8];
let inner_chunk_shape = vec![4, 4];
let mut sharding_codec_builder =
ShardingCodecBuilder::new(inner_chunk_shape.as_slice().try_into()?);
sharding_codec_builder.bytes_to_bytes_codecs(vec![
#[cfg(feature = "gzip")]
Box::new(codec::GzipCodec::new(5)?),
]);
let array = zarrs::array::ArrayBuilder::new(
vec![8, 8], // array shape
DataType::UInt16,
shard_shape.try_into()?,
FillValue::from(0u16),
)
.array_to_bytes_codec(Box::new(sharding_codec_builder.build()))
.dimension_names(["y", "x"].into())
// .storage_transformers(vec![].into())
.build(store.clone(), array_path)?;
// Write array metadata to store
array.store_metadata()?;
// The array metadata is
println!(
"The array metadata is:\n{}\n",
serde_json::to_string_pretty(&array.metadata()).unwrap()
);
// Write some shards (in parallel)
(0..2).into_par_iter().try_for_each(|s| {
let chunk_grid = array.chunk_grid();
let chunk_indices = vec![s, 0];
if let Some(chunk_shape) = chunk_grid.chunk_shape(&chunk_indices, array.shape())? {
let chunk_array = ndarray::ArrayD::<u16>::from_shape_fn(
chunk_shape
.iter()
.map(|u| u.get() as usize)
.collect::<Vec<_>>(),
|ij| {
(s * chunk_shape[0].get() * chunk_shape[1].get()
+ ij[0] as u64 * chunk_shape[1].get()
+ ij[1] as u64) as u16
},
);
array.store_chunk_ndarray(&chunk_indices, chunk_array)
} else {
Err(zarrs::array::ArrayError::InvalidChunkGridIndicesError(
chunk_indices.to_vec(),
))
}
})?;
// Read the whole array
let subset_all = ArraySubset::new_with_shape(array.shape().to_vec()); // the center 4x2 region
let data_all = array.retrieve_array_subset_ndarray::<u16>(&subset_all)?;
println!("The whole array is:\n{data_all}\n");
// Read a shard back from the store
let shard_indices = vec![1, 0];
let data_shard = array.retrieve_chunk_ndarray::<u16>(&shard_indices)?;
println!("Shard [1,0] is:\n{data_shard}\n");
// Read an inner chunk from the store
let subset_chunk_1_0 = ArraySubset::new_with_ranges(&[4..8, 0..4]);
let data_chunk = array.retrieve_array_subset_ndarray::<u16>(&subset_chunk_1_0)?;
println!("Chunk [1,0] is:\n{data_chunk}\n");
// Read the central 4x2 subset of the array
let subset_4x2 = ArraySubset::new_with_ranges(&[2..6, 3..5]); // the center 4x2 region
let data_4x2 = array.retrieve_array_subset_ndarray::<u16>(&subset_4x2)?;
println!("The middle 4x2 subset is:\n{data_4x2}\n");
// Decode inner chunks
// In some cases, it might be preferable to decode inner chunks in a shard directly.
// If using the partial decoder, then the shard index will only be read once from the store.
let partial_decoder = array.partial_decoder(&[0, 0])?;
let inner_chunks_to_decode = vec![
ArraySubset::new_with_start_shape(vec![0, 0], inner_chunk_shape.clone())?,
ArraySubset::new_with_start_shape(vec![0, 4], inner_chunk_shape.clone())?,
];
let decoded_inner_chunks_bytes = partial_decoder.partial_decode(&inner_chunks_to_decode)?;
let decoded_inner_chunks_ndarray = decoded_inner_chunks_bytes
.into_iter()
.map(|bytes| bytes_to_ndarray::<u16>(&inner_chunk_shape, bytes))
.collect::<Result<Vec<_>, _>>()?;
println!("Decoded inner chunks:");
for (inner_chunk_subset, decoded_inner_chunk) in
std::iter::zip(inner_chunks_to_decode, decoded_inner_chunks_ndarray)
{
println!("{inner_chunk_subset}\n{decoded_inner_chunk}\n");
}
// Show the hierarchy
let node = Node::new(&*store, "/").unwrap();
let tree = node.hierarchy_tree();
println!("The zarr hierarchy tree is:\n{}", tree);
println!(
"The keys in the store are:\n[{}]",
store.list().unwrap_or_default().iter().format(", ")
);
Ok(())
}
sourcepub const fn new_with_configuration(
configuration: &GzipCodecConfiguration
) -> Self
pub const fn new_with_configuration( configuration: &GzipCodecConfiguration ) -> Self
Create a new gzip
codec from configuration.
Trait Implementations§
source§impl BytesToBytesCodecTraits for GzipCodec
impl BytesToBytesCodecTraits for GzipCodec
source§fn recommended_concurrency(
&self,
_decoded_representation: &BytesRepresentation
) -> Result<RecommendedConcurrency, CodecError>
fn recommended_concurrency( &self, _decoded_representation: &BytesRepresentation ) -> Result<RecommendedConcurrency, CodecError>
Return the maximum internal concurrency supported for the requested decoded representation. Read more
source§fn encode(
&self,
decoded_value: Vec<u8>,
_options: &CodecOptions
) -> Result<Vec<u8>, CodecError>
fn encode( &self, decoded_value: Vec<u8>, _options: &CodecOptions ) -> Result<Vec<u8>, CodecError>
Encode chunk bytes. Read more
source§fn decode(
&self,
encoded_value: Vec<u8>,
_decoded_representation: &BytesRepresentation,
_options: &CodecOptions
) -> Result<Vec<u8>, CodecError>
fn decode( &self, encoded_value: Vec<u8>, _decoded_representation: &BytesRepresentation, _options: &CodecOptions ) -> Result<Vec<u8>, CodecError>
Decode chunk bytes. Read more
source§fn partial_decoder<'a>(
&self,
r: Box<dyn BytesPartialDecoderTraits + 'a>,
_decoded_representation: &BytesRepresentation,
_options: &CodecOptions
) -> Result<Box<dyn BytesPartialDecoderTraits + 'a>, CodecError>
fn partial_decoder<'a>( &self, r: Box<dyn BytesPartialDecoderTraits + 'a>, _decoded_representation: &BytesRepresentation, _options: &CodecOptions ) -> Result<Box<dyn BytesPartialDecoderTraits + 'a>, CodecError>
Initialises a partial decoder. Read more
source§fn async_partial_decoder<'a, 'life0, 'life1, 'async_trait>(
&'a self,
r: Box<dyn AsyncBytesPartialDecoderTraits + 'a>,
_decoded_representation: &'life0 BytesRepresentation,
_options: &'life1 CodecOptions
) -> Pin<Box<dyn Future<Output = Result<Box<dyn AsyncBytesPartialDecoderTraits + 'a>, CodecError>> + Send + 'async_trait>>where
Self: 'async_trait,
'a: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn async_partial_decoder<'a, 'life0, 'life1, 'async_trait>(
&'a self,
r: Box<dyn AsyncBytesPartialDecoderTraits + 'a>,
_decoded_representation: &'life0 BytesRepresentation,
_options: &'life1 CodecOptions
) -> Pin<Box<dyn Future<Output = Result<Box<dyn AsyncBytesPartialDecoderTraits + 'a>, CodecError>> + Send + 'async_trait>>where
Self: 'async_trait,
'a: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Available on crate feature
async
only.Initialises an asynchronous partial decoder. Read more
source§fn compute_encoded_size(
&self,
decoded_representation: &BytesRepresentation
) -> BytesRepresentation
fn compute_encoded_size( &self, decoded_representation: &BytesRepresentation ) -> BytesRepresentation
Returns the size of the encoded representation given a size of the decoded representation.
source§impl CodecTraits for GzipCodec
impl CodecTraits for GzipCodec
source§fn create_metadata_opt(
&self,
_options: &ArrayMetadataOptions
) -> Option<Metadata>
fn create_metadata_opt( &self, _options: &ArrayMetadataOptions ) -> Option<Metadata>
Create metadata. Read more
source§fn partial_decoder_should_cache_input(&self) -> bool
fn partial_decoder_should_cache_input(&self) -> bool
Indicates if the input to a codecs partial decoder should be cached for optimal performance.
If true, a cache may be inserted before it in a
CodecChain
partial decoder.source§fn partial_decoder_decodes_all(&self) -> bool
fn partial_decoder_decodes_all(&self) -> bool
Indicates if a partial decoder decodes all bytes from its input handle and its output should be cached for optimal performance.
If true, a cache will be inserted at some point after it in a
CodecChain
partial decoder.Auto Trait Implementations§
impl Freeze for GzipCodec
impl RefUnwindSafe for GzipCodec
impl Send for GzipCodec
impl Sync for GzipCodec
impl Unpin for GzipCodec
impl UnwindSafe for GzipCodec
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more