use std::{num::NonZeroU64, sync::Arc};
use icechunk::{repository::VersionInfo, Repository, RepositoryConfig};
use zarrs::array::{data_type, ArrayBuilder, ArraySubset};
use zarrs_icechunk::AsyncIcechunkStore;
#[tokio::test]
async fn icechunk_array() -> Result<(), Box<dyn std::error::Error>> {
let storage = icechunk::new_in_memory_storage().await?;
let config = RepositoryConfig::default();
let repo = Repository::create(
Some(config),
storage,
Default::default(),
Default::default(),
true,
)
.await?;
let array_path = "/array";
let data_type = data_type::uint8();
let mut builder = ArrayBuilder::new(
vec![4, 4], vec![2, 2], data_type.clone(),
0u8,
);
builder.bytes_to_bytes_codecs(vec![]);
builder.array_to_bytes_codec(Arc::new(
zarrs::array::codec::array_to_bytes::sharding::ShardingCodecBuilder::new(
vec![NonZeroU64::new(1).unwrap(), NonZeroU64::new(1).unwrap()],
&data_type,
)
.bytes_to_bytes_codecs(vec![Arc::new(zarrs::array::codec::GzipCodec::new(5)?)])
.build(),
));
let session = repo.writable_session("main").await?;
let store = Arc::new(AsyncIcechunkStore::new(session));
let array = builder.build(store.clone(), array_path).unwrap();
array.async_store_metadata().await?;
assert_eq!(array.data_type(), &data_type::uint8());
assert_eq!(array.fill_value().as_ne_bytes(), &[0u8]);
assert_eq!(array.shape(), &[4, 4]);
assert_eq!(
array.chunk_shape(&[0, 0]).unwrap(),
vec![NonZeroU64::new(2).unwrap(), NonZeroU64::new(2).unwrap()]
);
assert_eq!(array.chunk_grid_shape(), &[2, 2]);
array.async_store_chunk(&[0, 0], &[1u8, 2, 0, 0]).await?;
let snapshot0 = store.session().write().await.commit("a").execute().await?;
let session = repo.writable_session("main").await?;
let store = Arc::new(AsyncIcechunkStore::new(session));
let array = builder.build(store.clone(), array_path).unwrap();
array.async_store_chunk(&[0, 1], &[3u8, 4, 7, 8]).await?;
array
.async_store_array_subset(
&ArraySubset::new_with_ranges(&[1..3, 0..2]),
&[5u8, 6, 9, 10],
)
.await?;
assert!(array
.async_retrieve_chunk::<Vec<u8>>(&[0, 0, 0])
.await
.is_err());
assert_eq!(
array.async_retrieve_chunk::<Vec<u8>>(&[0, 0]).await?,
vec![1u8, 2, 5, 6]
);
let _snapshot1 = store.session().write().await.commit("b").execute().await?;
let session = repo
.readonly_session(&VersionInfo::SnapshotId(snapshot0))
.await?;
let store = Arc::new(AsyncIcechunkStore::new(session));
let array = builder.build(store.clone(), array_path).unwrap();
assert_eq!(
array.async_retrieve_chunk::<Vec<u8>>(&[0, 0]).await?,
vec![1u8, 2, 0, 0]
);
Ok(())
}