use std::path::PathBuf;
use super::ArrayCache;
use crate::{
schema::{
array_uri_reference::ArrayUriReference,
axes::{Base, CoordinateAxis, Numeric, NumericAxis},
},
strided_array_file::{ArrayProxy, Statistics, StridedArrayFile},
};
use ndarray::{Array1, SliceInfo, SliceInfoElem};
fn from_coordinates(coordinates: Array1<f64>) -> CoordinateAxis {
let proxy = ArrayProxy::F64(coordinates.view().into_dyn());
CoordinateAxis {
name: "".into(),
units: None,
bounds: [
proxy.calc_stats(Statistics::Min).unwrap(),
proxy.calc_stats(Statistics::Max).unwrap(),
],
size: coordinates.len(),
transform: None,
uri: ArrayCache::insert(proxy).unwrap(),
}
}
fn from_uri(uri: ArrayUriReference) -> CoordinateAxis {
CoordinateAxis {
name: "".into(),
units: None,
bounds: [0.1, 0.2],
size: 10,
transform: None,
uri,
}
}
#[test]
fn coordinate_axis_slicing() {
let axis = {
let coordinates = Array1::linspace(-2.7, 3.14, 42);
from_coordinates(coordinates)
};
let slice_info = SliceInfoElem::Slice {
start: 0,
end: None,
step: 2,
};
let sliced_axis: NumericAxis = axis.slice(&slice_info).unwrap().try_into().unwrap();
let sliced_coordinates = {
let slice_info: &[SliceInfoElem] = &[slice_info];
let slice_info = SliceInfo::try_from(slice_info).unwrap();
let coordinates = axis.coordinates().unwrap();
coordinates.slice(slice_info).to_owned()
};
assert_eq!(sliced_axis.coordinates().unwrap(), sliced_coordinates);
}
#[test]
fn insertion_into_cache_copies_data_to_new_location() {
let mut array = Array1::from_vec(vec![-2.7, 3.14, 0f64, 4f64]);
let proxy = ArrayProxy::F64(array.view().into_dyn());
let uri = ArrayCache::insert(proxy).unwrap();
let proxy = ArrayCache::get(&uri).unwrap();
array[2] = 100500f64;
assert_ne!(array.view().into_dyn(), proxy.try_as::<f64>().unwrap());
}
#[test]
fn reference_counting() {
let uri = {
let path = std::env::current_dir().unwrap().join("1.star");
if path.is_file() {
std::fs::remove_file(path.clone()).unwrap();
}
ArrayUriReference::try_from(path.as_path()).unwrap()
};
assert!(!PathBuf::try_from(&uri).unwrap().exists());
assert_eq!(ArrayCache::reference_count(&uri).unwrap(), 1);
let axis1 = from_uri(uri.clone());
assert!(axis1.coordinates().is_err());
assert_eq!(ArrayCache::reference_count(&uri).unwrap(), 2);
{
let array = Array1::from_vec(vec![-5f64, 20f64, 0.33]);
let file_path = PathBuf::try_from(&uri).unwrap();
StridedArrayFile::write(&file_path, &[ArrayProxy::F64(array.view().into_dyn())]).unwrap();
}
assert!(axis1.coordinates().is_ok());
assert_eq!(ArrayCache::reference_count(&uri).unwrap(), 2);
let axis2 = from_uri(uri.clone());
assert!(axis1.coordinates().unwrap() == axis2.coordinates().unwrap());
assert_eq!(ArrayCache::reference_count(&uri).unwrap(), 3);
std::mem::drop(uri);
std::mem::drop(axis1);
assert_eq!(ArrayCache::reference_count(&axis2.uri).unwrap(), 1);
let _proxy = ArrayCache::get(&axis2.uri).unwrap();
std::mem::drop(axis2);
}