A very simple and cross-platform implementation of the hashtable that uses only use std::{ mem, sync::{Arc, Mutex, RwLock, TryLockError}, } set of the standard rust library
use Mambo;
use ;
Panic and Mutex handling:
Since Mutex and Rwlock have a Poison state,
this is the state when the thread that was holding Guard caused a Panic and was destroyed.
It was decided that the user would determine for
himself how to react to a panic the destruction of data in Mambo is implemented as follows:
1. if a panic was caused during the execution of mambo.read(),
the Mutex with the elements will be destroyed and replaced with an empty one,
the data of this Mutex will be destroyed.
2. If a Panic occurred during the execution of
mambo.filter() or a private method for resizing the shard,
the shard will be destroyed and the data from it will be deleted
3. Some errors in the thread can be fatal and will
cause irreversible data corruption in Mambo,
since Mambo uses only secure primitives,
a panic in case of such damage
will be caused in other threads that will access fatally corrupted data.
The num_shards table is divided into independent sections for optimization, the optimal value is num_shards = the number of cores on your processor for multithreaded operation. The redream_factor can be from 1.0 to 10.0, depending on how Mambo is planned to be applied. ->10.0 when a lot of elements are planned (more than 10_000 ). if there are few elements, about 1000 or less, it is better to use values tending to ->1.0. At ->10, memory consumption per element decreases (depending on the system, at 1.0, memory costs per element range from 32 to 64 bytes of overhead memory, at ->10.0 per 1 element costs are reduced to ~10 bytes per element)
///impl<T: Clone> Clone for Mambo<T>
Some of the Mambo structure data is thread-independent, and each copy via clone provides a convenient instance of the Mambo structure that can be used in a new thread. all data regarding the elements of the Mambo hash table can be obtained from any thread that has an instance of clone.
Attention!! DO NOT CALL read INSIDE THE read CLOSURE!!! THIS MAY CAUSE THE THREAD TO SELF-LOCK!!
reading. to access an item for reading, you need to request it using the key. and the element is read and processed in the RFy closure:FnOnce(Option<&mut T>) -> Result<(), &'static str>, since &mut T is Mutex.lock(). while processing is taking place in read< RFy >, the shard in which this element is located cannot: 1 change its size. 2: since Mutex contains elements from 0 to redream_factor (a parameter in the Mamdo::new constructor), access in other threads for elements in one Mutex is blocked. to summarize, the faster the closure is resolved inside read, the better.
to remove the fragment. you need to return the key key: u64 if an element was in the table and it was deleted, but the function returns Some(T.clone()) if there was no such element in the hash table, None will be returned
insert an element T with the key: u64.if there is already an element with the same key: u64 in the table, then when force_replace == true, the old element T will be replaced by the new element T, while the old element T will be returned as Some(T.clone()). if force_replace == false, the old element will not be replaced and the function will return None. if there is no element with this key: u64, a new element will be added to the table and the function will output None
returns the number of all items in the table.note. for optimization in multithreaded environments,
!!!item count! changes do NOT occur EVERY TIME an item is DELETED/INSERTED.!!! with a large number of elements and in a multithreaded environment, it may not be critical, but when there are few elements, when elems_im_me is called, it may return 0 even if there are elements in Mambo. This is a forced decision to increase productivity.
///`filter()` takes the closure `RFy`: FnMut(&mut T, u64) -> bool<br>
/// This closure is applied sequentially to all elements of Mambo. <br>
/// If FnMut(&mut T, u64) -> bool returns false for a specific element,<br>
/// that element is deleted; if it returns true, that element is kept.<br>
/// While the filter is running,<br>
/// it is not possible to apply functions that change the size of the shard blocked by the filter.<br>
performance test in the --release version on the i7-11700f processor shards:100, redream_factor:10.0
| threads | type | millions op/ sec |
|---|---|---|
| threads: 1 | read | M.op/S: 41.008 |
| threads: 2 | read | M.op/S: 36.142 |
| threads: 3 | read | M.op/S: 44.619 |
| threads: 4 | read | M.op/S: 53.679 |
| threads: 5 | read | M.op/S: 61.140 |
| threads: 6 | read | M.op/S: 69.721 |
| threads: 7 | read | M.op/S: 75.364 |
| threads: 8 | read | M.op/S: 77.392 |
| threads: 9 | read | M.op/S: 80.942 |
| threads: 10 | read | M.op/S: 83.545 |
| threads: 11 | read | M.op/S: 87.364 |
| threads: 12 | read | M.op/S: 90.246 |
| threads: 13 | read | M.op/S: 92.421 |
| threads: 14 | read | M.op/S: 96.775 |
| threads: 15 | read | M.op/S: 98.932 |
| threads: 16 | read | M.op/S: 97.458 |
| threads: 17 | read | M.op/S: 100.22 |
| threads: 18 | read | M.op/S: 98.580 |
| threads: 19 | read | M.op/S: 98.767 |