mirror of
https://github.com/postgresml/pgcat.git
synced 2026-03-22 17:06:29 +00:00
once_cell is way faster
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -323,6 +323,8 @@ dependencies = [
|
||||
"bytes",
|
||||
"chrono",
|
||||
"md-5",
|
||||
"num_cpus",
|
||||
"once_cell",
|
||||
"rand",
|
||||
"regex",
|
||||
"serde",
|
||||
|
||||
@@ -17,4 +17,6 @@ sha-1 = "0.10"
|
||||
toml = "0.5"
|
||||
serde = "1"
|
||||
serde_derive = "1"
|
||||
regex = "1"
|
||||
regex = "1"
|
||||
num_cpus = "1"
|
||||
once_cell = "1"
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
/// We are pretending to the server in this scenario,
|
||||
/// and this module implements that.
|
||||
use bytes::{Buf, BufMut, BytesMut};
|
||||
use once_cell::sync::OnceCell;
|
||||
use regex::Regex;
|
||||
use tokio::io::{AsyncReadExt, BufReader};
|
||||
use tokio::net::tcp::{OwnedReadHalf, OwnedWriteHalf};
|
||||
@@ -14,8 +15,11 @@ use crate::pool::{ClientServerMap, ConnectionPool};
|
||||
use crate::server::Server;
|
||||
use crate::sharding::Sharder;
|
||||
|
||||
const SHARDING_REGEX: &str = r"SET SHARDING KEY TO '[0-9]+';";
|
||||
const ROLE_REGEX: &str = r"SET SERVER ROLE TO '(PRIMARY|REPLICA)';";
|
||||
pub const SHARDING_REGEX: &str = r"SET SHARDING KEY TO '[0-9]+';";
|
||||
pub const ROLE_REGEX: &str = r"SET SERVER ROLE TO '(PRIMARY|REPLICA)';";
|
||||
|
||||
pub static SHARDING_REGEX_RE: OnceCell<Regex> = OnceCell::new();
|
||||
pub static ROLE_REGEX_RE: OnceCell<Regex> = OnceCell::new();
|
||||
|
||||
/// The client state. One of these is created per client.
|
||||
pub struct Client {
|
||||
@@ -44,12 +48,6 @@ pub struct Client {
|
||||
// Clients are mapped to servers while they use them. This allows a client
|
||||
// to connect and cancel a query.
|
||||
client_server_map: ClientServerMap,
|
||||
|
||||
// sharding regex
|
||||
sharding_regex: Regex,
|
||||
|
||||
// role detection regex
|
||||
role_regex: Regex,
|
||||
}
|
||||
|
||||
impl Client {
|
||||
@@ -61,9 +59,6 @@ impl Client {
|
||||
client_server_map: ClientServerMap,
|
||||
transaction_mode: bool,
|
||||
) -> Result<Client, Error> {
|
||||
let sharding_regex = Regex::new(SHARDING_REGEX).unwrap();
|
||||
let role_regex = Regex::new(ROLE_REGEX).unwrap();
|
||||
|
||||
loop {
|
||||
// Could be StartupMessage or SSLRequest
|
||||
// which makes this variable length.
|
||||
@@ -119,8 +114,6 @@ impl Client {
|
||||
process_id: process_id,
|
||||
secret_key: secret_key,
|
||||
client_server_map: client_server_map,
|
||||
sharding_regex: sharding_regex,
|
||||
role_regex: role_regex,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -140,8 +133,6 @@ impl Client {
|
||||
process_id: process_id,
|
||||
secret_key: secret_key,
|
||||
client_server_map: client_server_map,
|
||||
sharding_regex: sharding_regex,
|
||||
role_regex: role_regex,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -414,8 +405,12 @@ impl Client {
|
||||
|
||||
let len = buf.get_i32();
|
||||
let query = String::from_utf8_lossy(&buf[..len as usize - 4 - 1]).to_ascii_uppercase(); // Don't read the ternminating null
|
||||
let rgx = match SHARDING_REGEX_RE.get() {
|
||||
Some(r) => r,
|
||||
None => return None,
|
||||
};
|
||||
|
||||
if self.sharding_regex.is_match(&query) {
|
||||
if rgx.is_match(&query) {
|
||||
let shard = query.split("'").collect::<Vec<&str>>()[1];
|
||||
match shard.parse::<i64>() {
|
||||
Ok(shard) => {
|
||||
@@ -441,10 +436,14 @@ impl Client {
|
||||
|
||||
let len = buf.get_i32();
|
||||
let query = String::from_utf8_lossy(&buf[..len as usize - 4 - 1]).to_ascii_uppercase();
|
||||
let rgx = match ROLE_REGEX_RE.get() {
|
||||
Some(r) => r,
|
||||
None => return None,
|
||||
};
|
||||
|
||||
// Copy / paste from above. If we get one more of these use cases,
|
||||
// it'll be time to abstract :).
|
||||
if self.role_regex.is_match(&query) {
|
||||
if rgx.is_match(&query) {
|
||||
let role = query.split("'").collect::<Vec<&str>>()[1];
|
||||
match role {
|
||||
"PRIMARY" => Some(Role::Primary),
|
||||
|
||||
10
src/main.rs
10
src/main.rs
@@ -17,11 +17,14 @@ extern crate async_trait;
|
||||
extern crate bb8;
|
||||
extern crate bytes;
|
||||
extern crate md5;
|
||||
extern crate num_cpus;
|
||||
extern crate once_cell;
|
||||
extern crate serde;
|
||||
extern crate serde_derive;
|
||||
extern crate tokio;
|
||||
extern crate toml;
|
||||
|
||||
use regex::Regex;
|
||||
use tokio::net::TcpListener;
|
||||
|
||||
use std::collections::HashMap;
|
||||
@@ -44,6 +47,13 @@ use pool::{ClientServerMap, ConnectionPool};
|
||||
async fn main() {
|
||||
println!("> Welcome to PgCat! Meow.");
|
||||
|
||||
client::SHARDING_REGEX_RE
|
||||
.set(Regex::new(client::SHARDING_REGEX).unwrap())
|
||||
.unwrap();
|
||||
client::ROLE_REGEX_RE
|
||||
.set(Regex::new(client::ROLE_REGEX).unwrap())
|
||||
.unwrap();
|
||||
|
||||
let config = match config::parse("pgcat.toml").await {
|
||||
Ok(config) => config,
|
||||
Err(err) => {
|
||||
|
||||
Reference in New Issue
Block a user