avoid hashmap clone in schema api calls (#158)

This commit is contained in:
QP Hou 2022-03-19 12:22:12 -07:00 committed by GitHub
parent a17887bd75
commit 2ee3927bd4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 20 deletions

View File

@ -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<String, arrow::datatypes::SchemaRef>;
async fn schemas_json_bytes(&self) -> Result<Vec<u8>, ApiErrResp>;
async fn table_schema_json_bytes(&self, table_name: &str) -> Result<Vec<u8>, ApiErrResp>;
async fn query_graphql(
&self,
query: &str,
) -> Result<Vec<arrow::record_batch::RecordBatch>, QueryError>;
async fn query_sql(
&self,
query: &str,
) -> Result<Vec<arrow::record_batch::RecordBatch>, 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<String, arrow::datatypes::SchemaRef> {
self.cq.schema_map().clone()
async fn schemas_json_bytes(&self) -> Result<Vec<u8>, 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<Vec<u8>, 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<String, arrow::datatypes::SchemaRef> {
async fn schemas_json_bytes(&self) -> Result<Vec<u8>, 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<Vec<u8>, 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]

View File

@ -10,26 +10,15 @@ pub async fn schema<H: HandlerCtx>(
state: extract::Extension<Arc<H>>,
) -> Result<impl IntoResponse, ApiErrResp> {
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<H: HandlerCtx>(
state: extract::Extension<Arc<H>>,
extract::Path(table_name): extract::Path<String>,
extract::Path(table_name): extract::Path<&str>,
) -> Result<impl IntoResponse, ApiErrResp> {
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))
}