From 2ee3927bd4bb91c268ca3b16ef7b9d9ee11561de Mon Sep 17 00:00:00 2001 From: QP Hou Date: Sat, 19 Mar 2022 12:22:12 -0700 Subject: [PATCH] avoid hashmap clone in schema api calls (#158) --- roapi-http/src/api/mod.rs | 48 +++++++++++++++++++++++++++++++----- roapi-http/src/api/schema.rs | 17 +++---------- 2 files changed, 45 insertions(+), 20 deletions(-) diff --git a/roapi-http/src/api/mod.rs b/roapi-http/src/api/mod.rs index 2383de1..920eec5 100644 --- a/roapi-http/src/api/mod.rs +++ b/roapi-http/src/api/mod.rs @@ -49,16 +49,21 @@ pub trait HandlerCtx: Send + Sync + 'static { fn read_only_mode() -> bool; async fn load_table(&self, table: &TableSource) -> Result<(), ColumnQError>; - // FIXME: avoid clone - async fn schema_map(&self) -> HashMap; + + async fn schemas_json_bytes(&self) -> Result, ApiErrResp>; + + async fn table_schema_json_bytes(&self, table_name: &str) -> Result, ApiErrResp>; + async fn query_graphql( &self, query: &str, ) -> Result, QueryError>; + async fn query_sql( &self, query: &str, ) -> Result, QueryError>; + async fn query_rest_table( &self, table_name: &str, @@ -81,8 +86,23 @@ impl HandlerCtx for RawHandlerContext { } #[inline] - async fn schema_map(&self) -> HashMap { - self.cq.schema_map().clone() + async fn schemas_json_bytes(&self) -> Result, ApiErrResp> { + serde_json::to_vec(self.cq.schema_map()) + .map_err(columnq::error::ColumnQError::from) + .map_err(ApiErrResp::json_serialization) + } + + #[inline] + async fn table_schema_json_bytes(&self, table_name: &str) -> Result, ApiErrResp> { + serde_json::to_vec( + self.cq + .schema_map() + .get(table_name) + .ok_or_else(|| ApiErrResp::not_found("invalid table name"))? + .as_ref(), + ) + .map_err(columnq::error::ColumnQError::from) + .map_err(ApiErrResp::json_serialization) } #[inline] @@ -125,9 +145,25 @@ impl HandlerCtx for ConcurrentHandlerContext { } #[inline] - async fn schema_map(&self) -> HashMap { + async fn schemas_json_bytes(&self) -> Result, ApiErrResp> { let ctx = self.read().await; - ctx.cq.schema_map().clone() + serde_json::to_vec(ctx.cq.schema_map()) + .map_err(columnq::error::ColumnQError::from) + .map_err(ApiErrResp::json_serialization) + } + + #[inline] + async fn table_schema_json_bytes(&self, table_name: &str) -> Result, ApiErrResp> { + let ctx = self.read().await; + serde_json::to_vec( + ctx.cq + .schema_map() + .get(table_name) + .ok_or_else(|| ApiErrResp::not_found("invalid table name"))? + .as_ref(), + ) + .map_err(columnq::error::ColumnQError::from) + .map_err(ApiErrResp::json_serialization) } #[inline] diff --git a/roapi-http/src/api/schema.rs b/roapi-http/src/api/schema.rs index d7ac91d..a2c0e66 100644 --- a/roapi-http/src/api/schema.rs +++ b/roapi-http/src/api/schema.rs @@ -10,26 +10,15 @@ pub async fn schema( state: extract::Extension>, ) -> Result { let ctx = state.0; - let schema = ctx.schema_map().await; - let payload = serde_json::to_vec(&schema) - .map_err(columnq::error::ColumnQError::from) - .map_err(ApiErrResp::json_serialization)?; + let payload = ctx.schemas_json_bytes().await?; Ok(bytes_to_json_resp(payload)) } pub async fn get_by_table_name( state: extract::Extension>, - extract::Path(table_name): extract::Path, + extract::Path(table_name): extract::Path<&str>, ) -> Result { let ctx = state.0; - let payload = serde_json::to_vec( - ctx.schema_map() - .await - .get(&table_name) - .ok_or_else(|| ApiErrResp::not_found("invalid table name"))? - .as_ref(), - ) - .map_err(columnq::error::ColumnQError::from) - .map_err(ApiErrResp::json_serialization)?; + let payload = ctx.table_schema_json_bytes(table_name).await?; Ok(bytes_to_json_resp(payload)) }