Skip to content

Commit

Permalink
Remove hashmap clones (#187)
Browse files Browse the repository at this point in the history
  • Loading branch information
sansyrox authored Apr 29, 2022
1 parent 79d33db commit fa9b7d1
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 28 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ actix-web-actors = "4.0.0-beta.1"
uuid = { version = "0.8", features = ["serde", "v4"] }
serde = "1.0.136"
serde_json = "1.0.79"
futures = "0.3.21"

[features]
# Defines a feature named `webp` that does not enable any other features.
Expand Down
63 changes: 40 additions & 23 deletions src/executors/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@
/// i.e. the functions that have the responsibility of parsing and executing functions.
use crate::io_helpers::read_file;

use std::borrow::Borrow;
use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;
use std::sync::Arc;

use actix_web::{http::Method, web, HttpRequest};
use anyhow::{bail, Result};
use futures::lock::Mutex;
// pyO3 module
use crate::types::{Headers, PyFunction};
use futures_util::stream::StreamExt;
Expand All @@ -22,7 +26,7 @@ pub async fn execute_middleware_function<'a>(
headers: &Headers,
req: &HttpRequest,
route_params: HashMap<String, String>,
queries: HashMap<String, String>,
queries: Rc<RefCell<HashMap<String, String>>>,
number_of_params: u8,
) -> Result<HashMap<String, HashMap<String, String>>> {
// TODO:
Expand Down Expand Up @@ -55,13 +59,18 @@ pub async fn execute_middleware_function<'a>(
for elem in (*headers).iter() {
headers_python.insert(elem.key().clone(), elem.value().clone());
}
let mut queries_clone: HashMap<String, String> = HashMap::new();

for (key, value) in (*queries).borrow().clone() {
queries_clone.insert(key, value);
}

match function {
PyFunction::CoRoutine(handler) => {
let output = Python::with_gil(|py| {
let handler = handler.as_ref(py);
request.insert("params", route_params.into_py(py));
request.insert("queries", queries.into_py(py));
request.insert("queries", queries_clone.into_py(py));
request.insert("headers", headers_python.into_py(py));
// request.insert("body", data.into_py(py));

Expand Down Expand Up @@ -89,28 +98,30 @@ pub async fn execute_middleware_function<'a>(
}

PyFunction::SyncFunction(handler) => {
tokio::task::spawn_blocking(move || {
Python::with_gil(|py| {
let handler = handler.as_ref(py);
request.insert("params", route_params.into_py(py));
request.insert("queries", queries.into_py(py));
request.insert("headers", headers_python.into_py(py));
request.insert("body", data.into_py(py));
// do we even need this?
// How else can we return a future from this?
// let's wrap the output in a future?
let output: Result<HashMap<String, HashMap<String, String>>> = Python::with_gil(|py| {
let handler = handler.as_ref(py);
request.insert("params", route_params.into_py(py));
request.insert("queries", queries_clone.into_py(py));
request.insert("headers", headers_python.into_py(py));
request.insert("body", data.into_py(py));

let output: PyResult<&PyAny> = match number_of_params {
0 => handler.call0(),
1 => handler.call1((request,)),
// this is done to accomodate any future params
2_u8..=u8::MAX => handler.call1((request,)),
};
let output: PyResult<&PyAny> = match number_of_params {
0 => handler.call0(),
1 => handler.call1((request,)),
// this is done to accomodate any future params
2_u8..=u8::MAX => handler.call1((request,)),
};

let output: Vec<HashMap<String, HashMap<String, String>>> =
output?.extract().unwrap();
let output: Vec<HashMap<String, HashMap<String, String>>> =
output?.extract().unwrap();

Ok(output[0].clone())
})
})
.await?
Ok(output[0].clone())
});

Ok(output.unwrap())
}
}
}
Expand All @@ -123,7 +134,7 @@ pub async fn execute_http_function(
headers: HashMap<String, String>,
req: &HttpRequest,
route_params: HashMap<String, String>,
queries: HashMap<String, String>,
queries: Rc<RefCell<HashMap<String, String>>>,
number_of_params: u8,
// need to change this to return a response struct
// create a custom struct for this
Expand Down Expand Up @@ -151,12 +162,18 @@ pub async fn execute_http_function(
// request object accessible while creating routes
let mut request = HashMap::new();

let mut queries_clone: HashMap<String, String> = HashMap::new();

for (key, value) in (*queries).borrow().clone() {
queries_clone.insert(key, value);
}

match function {
PyFunction::CoRoutine(handler) => {
let output = Python::with_gil(|py| {
let handler = handler.as_ref(py);
request.insert("params", route_params.into_py(py));
request.insert("queries", queries.into_py(py));
request.insert("queries", queries_clone.into_py(py));
request.insert("headers", headers.into_py(py));
let data = data.into_py(py);
request.insert("body", data);
Expand Down
7 changes: 4 additions & 3 deletions src/request_handler/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use crate::executors::{execute_http_function, execute_middleware_function};

use std::collections::HashMap;
use std::rc::Rc;
use std::str::FromStr;
use std::sync::Arc;
use std::{cell::RefCell, collections::HashMap};

use actix_web::{web, HttpRequest, HttpResponse, HttpResponseBuilder};
// pyO3 module
Expand Down Expand Up @@ -33,7 +34,7 @@ pub async fn handle_http_request(
payload: &mut web::Payload,
req: &HttpRequest,
route_params: HashMap<String, String>,
queries: HashMap<String, String>,
queries: Rc<RefCell<HashMap<String, String>>>,
) -> HttpResponse {
let contents = match execute_http_function(
function,
Expand Down Expand Up @@ -93,7 +94,7 @@ pub async fn handle_http_middleware_request(
payload: &mut web::Payload,
req: &HttpRequest,
route_params: HashMap<String, String>,
queries: HashMap<String, String>,
queries: Rc<RefCell<HashMap<String, String>>>,
) -> HashMap<String, HashMap<String, String>> {
let contents = match execute_middleware_function(
function,
Expand Down
9 changes: 7 additions & 2 deletions src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ use crate::shared_socket::SocketHeld;
use crate::types::{Headers, PyFunction};
use crate::web_socket_connection::start_web_socket;

use std::cell::RefCell;
use std::collections::HashMap;
use std::convert::TryInto;
use std::rc::Rc;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering::{Relaxed, SeqCst};
use std::sync::{Arc, RwLock};
Expand Down Expand Up @@ -311,13 +313,16 @@ async fn index(
) -> impl Responder {
// cloning hashmaps a lot here
// try reading about arc or rc
let mut queries = HashMap::new();

let mut queries = Rc::new(RefCell::new(HashMap::new()));

if !req.query_string().is_empty() {
let split = req.query_string().split('&');
for s in split {
let params = s.split_once('=').unwrap_or((s, ""));
queries.insert(params.0.to_string(), params.1.to_string());
queries
.borrow_mut()
.insert(params.0.to_string(), params.1.to_string());
}
}

Expand Down

0 comments on commit fa9b7d1

Please sign in to comment.