From 20500429631aaebce54ec98cbc1727107e7f27d7 Mon Sep 17 00:00:00 2001 From: Mark Goddard Date: Tue, 25 Jul 2023 16:54:37 +0100 Subject: [PATCH] Remove /v1/mean endpoint The mean operation is not very useful since it cannot be used to take a mean over several storage chunks. Instead it is necessary to use the sum endpoint and take the count from the header. --- README.md | 2 +- src/app.rs | 1 - src/operations.rs | 44 -------------------------------------------- 3 files changed, 1 insertion(+), 46 deletions(-) diff --git a/README.md b/README.md index 0a035c7..8507aef 100644 --- a/README.md +++ b/README.md @@ -85,7 +85,7 @@ with a JSON payload of the form: } ``` -The currently supported reducers are `max`, `min`, `mean`, `sum`, `select` and `count`. All reducers return the result using the same datatype as specified in the request except for `count` which always returns the result as `int64`. +The currently supported reducers are `max`, `min`, `sum`, `select` and `count`. All reducers return the result using the same datatype as specified in the request except for `count` which always returns the result as `int64`. The proxy adds two custom headers `x-activestorage-dtype` and `x-activestrorage-shape` to the HTTP response to allow the numeric result to be reconstructed from the binary content of the response. An additional `x-activestorage-count` header is also returned which contains the number of array elements operated on while performing the requested reduction. This header is useful, for example, to calculate the mean over multiple requests where the number of items operated on may differ between chunks. diff --git a/src/app.rs b/src/app.rs index 3fae026..42c6ed2 100644 --- a/src/app.rs +++ b/src/app.rs @@ -66,7 +66,6 @@ fn router() -> Router { Router::new() .route("/count", post(operation_handler::)) .route("/max", post(operation_handler::)) - .route("/mean", post(operation_handler::)) .route("/min", post(operation_handler::)) .route("/select", post(operation_handler::)) .route("/sum", post(operation_handler::)) diff --git a/src/operations.rs b/src/operations.rs index 5edae42..5b75e70 100644 --- a/src/operations.rs +++ b/src/operations.rs @@ -70,35 +70,6 @@ impl NumOperation for Max { } } -/// Return the mean of selected elements in the array. -pub struct Mean {} - -impl NumOperation for Mean { - fn execute_t( - request_data: &models::RequestData, - data: &Bytes, - ) -> Result { - let array = array::build_array::(request_data, data)?; - let slice_info = array::build_slice_info::(&request_data.selection, array.shape()); - let sliced = array.slice(slice_info); - // FIXME: Account for missing data? - let count = i64::try_from(sliced.len())?; - // FIXME: endianness? - let body = sliced - .mean() - .ok_or(ActiveStorageError::EmptyArray { operation: "mean" })?; - let body = body.as_bytes(); - // Need to copy to provide ownership to caller. - let body = Bytes::copy_from_slice(body); - Ok(models::Response::new( - body, - request_data.dtype, - vec![], - count, - )) - } -} - /// Return the minimum of selected elements in the array. pub struct Min {} @@ -236,21 +207,6 @@ mod tests { assert_eq!(1, response.count); } - #[test] - fn mean_u32_1d() { - let mut request_data = test_utils::get_test_request_data(); - request_data.dtype = models::DType::Uint32; - let data = [1, 2, 3, 4, 5, 6, 7, 8]; - let bytes = Bytes::copy_from_slice(&data); - let response = Mean::execute(&request_data, &bytes).unwrap(); - let expected: i32 = (0x08070605 + 0x04030201) / 2; - assert_eq!(expected.as_bytes(), response.body); - assert_eq!(4, response.body.len()); - assert_eq!(models::DType::Uint32, response.dtype); - assert_eq!(vec![0; 0], response.shape); - assert_eq!(2, response.count); - } - #[test] fn min_u64_1d() { let mut request_data = test_utils::get_test_request_data();