Skip to content

Commit 42d0dc4

Browse files
committed
refactor: Use a common code for try_take_leased_lock.
This code is shared by all `MemoryStore` implementations.
1 parent a124f1a commit 42d0dc4

File tree

3 files changed

+70
-111
lines changed

3 files changed

+70
-111
lines changed

crates/matrix-sdk-base/src/event_cache_store/memory_store.rs

Lines changed: 5 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,12 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
use std::{
16-
collections::{hash_map::Entry, HashMap},
17-
num::NonZeroUsize,
18-
sync::RwLock as StdRwLock,
19-
time::{Duration, Instant},
20-
};
15+
use std::{collections::HashMap, num::NonZeroUsize, sync::RwLock as StdRwLock, time::Instant};
2116

2217
use async_trait::async_trait;
23-
use matrix_sdk_common::ring_buffer::RingBuffer;
18+
use matrix_sdk_common::{
19+
ring_buffer::RingBuffer, store_locks::memory_store_helper::try_take_leased_lock,
20+
};
2421
use ruma::{MxcUri, OwnedMxcUri};
2522

2623
use super::{EventCacheStore, EventCacheStoreError, Result};
@@ -66,44 +63,7 @@ impl EventCacheStore for MemoryStore {
6663
key: &str,
6764
holder: &str,
6865
) -> Result<bool, Self::Error> {
69-
let now = Instant::now();
70-
let expiration = now + Duration::from_millis(lease_duration_ms.into());
71-
72-
match self.leases.write().unwrap().entry(key.to_owned()) {
73-
// There is an existing holder.
74-
Entry::Occupied(mut entry) => {
75-
let (current_holder, current_expiration) = entry.get_mut();
76-
77-
if current_holder == holder {
78-
// We had the lease before, extend it.
79-
*current_expiration = expiration;
80-
81-
Ok(true)
82-
} else {
83-
// We didn't have it.
84-
if *current_expiration < now {
85-
// Steal it!
86-
*current_holder = holder.to_owned();
87-
*current_expiration = expiration;
88-
89-
Ok(true)
90-
} else {
91-
// We tried our best.
92-
Ok(false)
93-
}
94-
}
95-
}
96-
97-
// There is no holder, easy.
98-
Entry::Vacant(entry) => {
99-
entry.insert((
100-
holder.to_owned(),
101-
Instant::now() + Duration::from_millis(lease_duration_ms.into()),
102-
));
103-
104-
Ok(true)
105-
}
106-
}
66+
Ok(try_take_leased_lock(&self.leases, lease_duration_ms, key, holder))
10767
}
10868

10969
async fn add_media_content(&self, request: &MediaRequest, data: Vec<u8>) -> Result<()> {

crates/matrix-sdk-common/src/store_locks.rs

Lines changed: 61 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ pub enum LockStoreError {
338338
mod tests {
339339
use std::{
340340
collections::HashMap,
341-
sync::{atomic, Arc, Mutex},
341+
sync::{atomic, Arc, RwLock},
342342
time::Instant,
343343
};
344344

@@ -350,47 +350,18 @@ mod tests {
350350
};
351351

352352
use super::{
353-
BackingStore, CrossProcessStoreLock, CrossProcessStoreLockGuard, LockStoreError,
354-
EXTEND_LEASE_EVERY_MS,
353+
memory_store_helper::try_take_leased_lock, BackingStore, CrossProcessStoreLock,
354+
CrossProcessStoreLockGuard, LockStoreError, EXTEND_LEASE_EVERY_MS,
355355
};
356356

357357
#[derive(Clone, Default)]
358358
struct TestStore {
359-
leases: Arc<Mutex<HashMap<String, (String, Instant)>>>,
359+
leases: Arc<RwLock<HashMap<String, (String, Instant)>>>,
360360
}
361361

362362
impl TestStore {
363363
fn try_take_leased_lock(&self, lease_duration_ms: u32, key: &str, holder: &str) -> bool {
364-
let now = Instant::now();
365-
let expiration = now + Duration::from_millis(lease_duration_ms.into());
366-
let mut leases = self.leases.lock().unwrap();
367-
if let Some(prev) = leases.get_mut(key) {
368-
if prev.0 == holder {
369-
// We had the lease before, extend it.
370-
prev.1 = expiration;
371-
true
372-
} else {
373-
// We didn't have it.
374-
if prev.1 < now {
375-
// Steal it!
376-
prev.0 = holder.to_owned();
377-
prev.1 = expiration;
378-
true
379-
} else {
380-
// We tried our best.
381-
false
382-
}
383-
}
384-
} else {
385-
leases.insert(
386-
key.to_owned(),
387-
(
388-
holder.to_owned(),
389-
Instant::now() + Duration::from_millis(lease_duration_ms.into()),
390-
),
391-
);
392-
true
393-
}
364+
try_take_leased_lock(&self.leases, lease_duration_ms, key, holder)
394365
}
395366
}
396367

@@ -525,3 +496,59 @@ mod tests {
525496
Ok(())
526497
}
527498
}
499+
500+
/// Some code that is shared by almost all `MemoryStore` implementations out
501+
/// there.
502+
pub mod memory_store_helper {
503+
use std::{
504+
collections::{hash_map::Entry, HashMap},
505+
sync::RwLock,
506+
time::{Duration, Instant},
507+
};
508+
509+
pub fn try_take_leased_lock(
510+
leases: &RwLock<HashMap<String, (String, Instant)>>,
511+
lease_duration_ms: u32,
512+
key: &str,
513+
holder: &str,
514+
) -> bool {
515+
let now = Instant::now();
516+
let expiration = now + Duration::from_millis(lease_duration_ms.into());
517+
518+
match leases.write().unwrap().entry(key.to_owned()) {
519+
// There is an existing holder.
520+
Entry::Occupied(mut entry) => {
521+
let (current_holder, current_expiration) = entry.get_mut();
522+
523+
if current_holder == holder {
524+
// We had the lease before, extend it.
525+
*current_expiration = expiration;
526+
527+
true
528+
} else {
529+
// We didn't have it.
530+
if *current_expiration < now {
531+
// Steal it!
532+
*current_holder = holder.to_owned();
533+
*current_expiration = expiration;
534+
535+
true
536+
} else {
537+
// We tried our best.
538+
false
539+
}
540+
}
541+
}
542+
543+
// There is no holder, easy.
544+
Entry::Vacant(entry) => {
545+
entry.insert((
546+
holder.to_owned(),
547+
Instant::now() + Duration::from_millis(lease_duration_ms.into()),
548+
));
549+
550+
true
551+
}
552+
}
553+
}
554+
}

crates/matrix-sdk-crypto/src/store/memorystore.rs

Lines changed: 4 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,14 @@
1313
// limitations under the License.
1414

1515
use std::{
16-
collections::{hash_map::Entry, BTreeMap, HashMap, HashSet},
16+
collections::{BTreeMap, HashMap, HashSet},
1717
convert::Infallible,
1818
sync::RwLock as StdRwLock,
19-
time::{Duration, Instant},
19+
time::Instant,
2020
};
2121

2222
use async_trait::async_trait;
23+
use matrix_sdk_common::store_locks::memory_store_helper::try_take_leased_lock;
2324
use ruma::{
2425
events::secret::request::SecretName, DeviceId, OwnedDeviceId, OwnedRoomId, OwnedTransactionId,
2526
OwnedUserId, RoomId, TransactionId, UserId,
@@ -631,36 +632,7 @@ impl CryptoStore for MemoryStore {
631632
key: &str,
632633
holder: &str,
633634
) -> Result<bool> {
634-
let now = Instant::now();
635-
let expiration = now + Duration::from_millis(lease_duration_ms.into());
636-
match self.leases.write().unwrap().entry(key.to_owned()) {
637-
Entry::Occupied(mut o) => {
638-
let prev = o.get_mut();
639-
if prev.0 == holder {
640-
// We had the lease before, extend it.
641-
prev.1 = expiration;
642-
Ok(true)
643-
} else {
644-
// We didn't have it.
645-
if prev.1 < now {
646-
// Steal it!
647-
prev.0 = holder.to_owned();
648-
prev.1 = expiration;
649-
Ok(true)
650-
} else {
651-
// We tried our best.
652-
Ok(false)
653-
}
654-
}
655-
}
656-
Entry::Vacant(v) => {
657-
v.insert((
658-
holder.to_owned(),
659-
Instant::now() + Duration::from_millis(lease_duration_ms.into()),
660-
));
661-
Ok(true)
662-
}
663-
}
635+
Ok(try_take_leased_lock(&self.leases, lease_duration_ms, key, holder))
664636
}
665637
}
666638

0 commit comments

Comments
 (0)