array_write_read_string/
array_write_read_string.rs

1#![allow(missing_docs)]
2
3use itertools::Itertools;
4use ndarray::{array, Array2, ArrayD};
5use zarrs::{
6    storage::storage_adapter::usage_log::UsageLogStorageAdapter,
7    storage::ReadableWritableListableStorage,
8};
9
10fn array_write_read() -> Result<(), Box<dyn std::error::Error>> {
11    use std::sync::Arc;
12    use zarrs::{array::DataType, array_subset::ArraySubset, storage::store};
13
14    // Create a store
15    // let path = tempfile::TempDir::new()?;
16    // let mut store: ReadableWritableListableStorage =
17    //     Arc::new(zarrs::filesystem::FilesystemStore::new(path.path())?);
18    // let mut store: ReadableWritableListableStorage = Arc::new(
19    //     zarrs::filesystem::FilesystemStore::new("zarrs/tests/data/array_write_read.zarr")?,
20    // );
21    let mut store: ReadableWritableListableStorage = Arc::new(store::MemoryStore::new());
22    if let Some(arg1) = std::env::args().collect::<Vec<_>>().get(1) {
23        if arg1 == "--usage-log" {
24            let log_writer = Arc::new(std::sync::Mutex::new(
25                // std::io::BufWriter::new(
26                std::io::stdout(),
27                //    )
28            ));
29            store = Arc::new(UsageLogStorageAdapter::new(store, log_writer, || {
30                chrono::Utc::now().format("[%T%.3f] ").to_string()
31            }));
32        }
33    }
34
35    // Create the root group
36    zarrs::group::GroupBuilder::new()
37        .build(store.clone(), "/")?
38        .store_metadata()?;
39
40    // Create a group with attributes
41    let group_path = "/group";
42    let mut group = zarrs::group::GroupBuilder::new().build(store.clone(), group_path)?;
43    group
44        .attributes_mut()
45        .insert("foo".into(), serde_json::Value::String("bar".into()));
46    group.store_metadata()?;
47
48    println!(
49        "The group metadata is:\n{}\n",
50        group.metadata().to_string_pretty()
51    );
52
53    // Create an array
54    let array_path = "/group/array";
55    let array = zarrs::array::ArrayBuilder::new(
56        vec![4, 4], // array shape
57        vec![2, 2], // regular chunk shape
58        DataType::String,
59        "_",
60    )
61    // .bytes_to_bytes_codecs(vec![]) // uncompressed
62    .dimension_names(["y", "x"].into())
63    // .storage_transformers(vec![].into())
64    .build(store.clone(), array_path)?;
65
66    // Write array metadata to store
67    array.store_metadata()?;
68
69    println!(
70        "The array metadata is:\n{}\n",
71        array.metadata().to_string_pretty()
72    );
73
74    // Write some chunks
75    array.store_chunk_ndarray(
76        &[0, 0],
77        ArrayD::<&str>::from_shape_vec(vec![2, 2], vec!["a", "bb", "ccc", "dddd"]).unwrap(),
78    )?;
79    array.store_chunk_ndarray(
80        &[0, 1],
81        ArrayD::<&str>::from_shape_vec(vec![2, 2], vec!["4444", "333", "22", "1"]).unwrap(),
82    )?;
83    let subset_all = array.subset_all();
84    let data_all = array.retrieve_array_subset_ndarray::<String>(&subset_all)?;
85    println!("store_chunk [0, 0] and [0, 1]:\n{data_all}\n");
86
87    // Write a subset spanning multiple chunks, including updating chunks already written
88    let ndarray_subset: Array2<&str> = array![["!", "@@"], ["###", "$$$$"]];
89    array.store_array_subset_ndarray(
90        ArraySubset::new_with_ranges(&[1..3, 1..3]).start(),
91        ndarray_subset,
92    )?;
93    let data_all = array.retrieve_array_subset_ndarray::<String>(&subset_all)?;
94    println!("store_array_subset [1..3, 1..3]:\nndarray::ArrayD<String>\n{data_all}");
95
96    // Retrieve bytes directly, convert into a single string allocation, create a &str ndarray
97    // TODO: Add a convenience function for this?
98    let data_all = array.retrieve_array_subset(&subset_all)?;
99    let (bytes, offsets) = data_all.into_variable()?;
100    let string = String::from_utf8(bytes.into_owned())?;
101    let elements = offsets
102        .iter()
103        .tuple_windows()
104        .map(|(&curr, &next)| &string[curr..next])
105        .collect::<Vec<&str>>();
106    let ndarray = ArrayD::<&str>::from_shape_vec(subset_all.shape_usize(), elements)?;
107    println!("ndarray::ArrayD<&str>:\n{ndarray}");
108
109    Ok(())
110}
111
112fn main() {
113    if let Err(err) = array_write_read() {
114        println!("{:?}", err);
115    }
116}