Skip to content

Commit 06575ea

Browse files
committed
once_cell is way faster
1 parent 0bec14b commit 06575ea

File tree

4 files changed

+31
-18
lines changed

4 files changed

+31
-18
lines changed

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,6 @@ sha-1 = "0.10"
1717
toml = "0.5"
1818
serde = "1"
1919
serde_derive = "1"
20-
regex = "1"
20+
regex = "1"
21+
num_cpus = "1"
22+
once_cell = "1"

src/client.rs

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
/// We are pretending to the server in this scenario,
33
/// and this module implements that.
44
use bytes::{Buf, BufMut, BytesMut};
5+
use once_cell::sync::OnceCell;
56
use regex::Regex;
67
use tokio::io::{AsyncReadExt, BufReader};
78
use tokio::net::tcp::{OwnedReadHalf, OwnedWriteHalf};
@@ -14,8 +15,11 @@ use crate::pool::{ClientServerMap, ConnectionPool};
1415
use crate::server::Server;
1516
use crate::sharding::Sharder;
1617

17-
const SHARDING_REGEX: &str = r"SET SHARDING KEY TO '[0-9]+';";
18-
const ROLE_REGEX: &str = r"SET SERVER ROLE TO '(PRIMARY|REPLICA)';";
18+
pub const SHARDING_REGEX: &str = r"SET SHARDING KEY TO '[0-9]+';";
19+
pub const ROLE_REGEX: &str = r"SET SERVER ROLE TO '(PRIMARY|REPLICA)';";
20+
21+
pub static SHARDING_REGEX_RE: OnceCell<Regex> = OnceCell::new();
22+
pub static ROLE_REGEX_RE: OnceCell<Regex> = OnceCell::new();
1923

2024
/// The client state. One of these is created per client.
2125
pub struct Client {
@@ -44,12 +48,6 @@ pub struct Client {
4448
// Clients are mapped to servers while they use them. This allows a client
4549
// to connect and cancel a query.
4650
client_server_map: ClientServerMap,
47-
48-
// sharding regex
49-
sharding_regex: Regex,
50-
51-
// role detection regex
52-
role_regex: Regex,
5351
}
5452

5553
impl Client {
@@ -61,9 +59,6 @@ impl Client {
6159
client_server_map: ClientServerMap,
6260
transaction_mode: bool,
6361
) -> Result<Client, Error> {
64-
let sharding_regex = Regex::new(SHARDING_REGEX).unwrap();
65-
let role_regex = Regex::new(ROLE_REGEX).unwrap();
66-
6762
loop {
6863
// Could be StartupMessage or SSLRequest
6964
// which makes this variable length.
@@ -119,8 +114,6 @@ impl Client {
119114
process_id: process_id,
120115
secret_key: secret_key,
121116
client_server_map: client_server_map,
122-
sharding_regex: sharding_regex,
123-
role_regex: role_regex,
124117
});
125118
}
126119

@@ -140,8 +133,6 @@ impl Client {
140133
process_id: process_id,
141134
secret_key: secret_key,
142135
client_server_map: client_server_map,
143-
sharding_regex: sharding_regex,
144-
role_regex: role_regex,
145136
});
146137
}
147138

@@ -414,8 +405,12 @@ impl Client {
414405

415406
let len = buf.get_i32();
416407
let query = String::from_utf8_lossy(&buf[..len as usize - 4 - 1]).to_ascii_uppercase(); // Don't read the ternminating null
408+
let rgx = match SHARDING_REGEX_RE.get() {
409+
Some(r) => r,
410+
None => return None,
411+
};
417412

418-
if self.sharding_regex.is_match(&query) {
413+
if rgx.is_match(&query) {
419414
let shard = query.split("'").collect::<Vec<&str>>()[1];
420415
match shard.parse::<i64>() {
421416
Ok(shard) => {
@@ -441,10 +436,14 @@ impl Client {
441436

442437
let len = buf.get_i32();
443438
let query = String::from_utf8_lossy(&buf[..len as usize - 4 - 1]).to_ascii_uppercase();
439+
let rgx = match ROLE_REGEX_RE.get() {
440+
Some(r) => r,
441+
None => return None,
442+
};
444443

445444
// Copy / paste from above. If we get one more of these use cases,
446445
// it'll be time to abstract :).
447-
if self.role_regex.is_match(&query) {
446+
if rgx.is_match(&query) {
448447
let role = query.split("'").collect::<Vec<&str>>()[1];
449448
match role {
450449
"PRIMARY" => Some(Role::Primary),

src/main.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,14 @@ extern crate async_trait;
1717
extern crate bb8;
1818
extern crate bytes;
1919
extern crate md5;
20+
extern crate num_cpus;
21+
extern crate once_cell;
2022
extern crate serde;
2123
extern crate serde_derive;
2224
extern crate tokio;
2325
extern crate toml;
2426

27+
use regex::Regex;
2528
use tokio::net::TcpListener;
2629

2730
use std::collections::HashMap;
@@ -44,6 +47,13 @@ use pool::{ClientServerMap, ConnectionPool};
4447
async fn main() {
4548
println!("> Welcome to PgCat! Meow.");
4649

50+
client::SHARDING_REGEX_RE
51+
.set(Regex::new(client::SHARDING_REGEX).unwrap())
52+
.unwrap();
53+
client::ROLE_REGEX_RE
54+
.set(Regex::new(client::ROLE_REGEX).unwrap())
55+
.unwrap();
56+
4757
let config = match config::parse("pgcat.toml").await {
4858
Ok(config) => config,
4959
Err(err) => {

0 commit comments

Comments
 (0)