Skip to content

Commit

Permalink
use a vector instead of thread local
Browse files Browse the repository at this point in the history
  • Loading branch information
tusharmath committed Nov 4, 2024
1 parent 89314af commit db1c48f
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 10 deletions.
1 change: 0 additions & 1 deletion Cargo.lock

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

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,6 @@ derive_more = { workspace = true }
strum = "0.26.2"
dashmap = "6.1.0"
urlencoding = "2.1.3"
thread_local = "1.1.8"

[dev-dependencies]
datatest-stable = "0.2.9"
Expand Down
29 changes: 21 additions & 8 deletions src/core/lrwlock.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,40 @@
use std::sync::{LockResult, RwLock, RwLockReadGuard, RwLockWriteGuard};
use thread_local::ThreadLocal;

/// A RwLock that leverages thread locals to avoid contention.
pub struct LrwLock<A: Send> {
inner: ThreadLocal<RwLock<A>>,
value: A,
inner: Vec<RwLock<A>>,
}

const SIZE: usize = 16;

impl<A: Clone + Send> LrwLock<A> {
/// Create a new LrwLock.
pub fn new(value: A) -> Self {
Self { inner: ThreadLocal::new(), value }
let mut inner = Vec::with_capacity(SIZE);
for _ in 1..SIZE {
inner.push(RwLock::new(value.clone()));
}

Self { inner }
}

/// Lock the LrwLock for reading.
pub fn read(&self) -> LockResult<RwLockReadGuard<'_, A>> {
self.inner.get_or(|| RwLock::new(self.value.clone())).read()
let id = thread_id();

self.inner[id % SIZE].read()
}

/// Lock the LrwLock for writing.
pub fn write(&self) -> LockResult<RwLockWriteGuard<'_, A>> {
self.inner
.get_or(|| RwLock::new(self.value.clone()))
.write()
let id = thread_id();

self.inner[id % SIZE].write()
}
}

fn thread_id() -> usize {
format!("{:?}", std::thread::current().id())
.parse::<usize>()
.unwrap()
}

1 comment on commit db1c48f

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Running 30s test @ http://localhost:8000/graphql

4 threads and 100 connections

Thread Stats Avg Stdev Max +/- Stdev
Latency 8.61ms 4.87ms 163.08ms 96.39%
Req/Sec 3.00k 438.66 4.22k 85.92%

358176 requests in 30.03s, 1.80GB read

Requests/sec: 11929.19

Transfer/sec: 61.23MB

Please sign in to comment.