# Groupex
Syncronization primitive that allows acquire lock by index.
## `RawGroupex`
`RawGroupex` is base on which you can build collections with concurrent access.
It implements basic functions for acquiring and releasing a lock, such as `lock`, `try_lock` and `unlock`.
These functions recieve index on which lock must be acquired/released.
Example:
```rust
let groupex = Arc::new(RawGroupex::<1>::new());
let groupex = &groupex;
scope.spawn(move || {
groupex.lock(i % 2);
// critical section
groupex.unlock(i % 2);
});
}
});
```
If lock already acquired by other thread, current thread will go to sleep until the lock is released.
`RawGroupex` uses [parking_lot_core](https://docs.rs/parking_lot_core/latest/parking_lot_core/) internally for parking and unparking threads.
These functions will panic if index out of range. Range depends on generic parameter `BLOCKS`.
One block contains 32 slots so the range of possible indexes is [0; BLOCKS * 32 - 1]. For example, this code will panic:
```rust
let groupex = RawGroupex::<8>::new();
groupex.lock(8 * 32);
```
`RawGroupex` also has auxiliary functions `is_locked` and `elements`.
The first one will be useful to check if index currently acquired.
The second one will return number of indexes and will useful when creating other data structures on top of `RawGroupex`.
## `GroupexMap` and `GroupexVec`
This crate provides `GroupexMap` and `GroupexVec` structs - hash table and array.
### `GroupexMap`
`GroupexMap` is hash table built on top of `HashMap` and `RawGroupex`.
Its cells can be locked by keys of any type that implement traits `Eq` and `Hash`.
Computed hash will be simply divided by `Groupex::elements()`'s result and remainder of the division will be used as index for locking.
Thus different keys can be resolved to the same index. So **it's dangerous to lock another cell when one lock already acquired in the thread**.
Take into account that using just `HashMap<_, Mutex<_>>` is faster than `GroupexMap`.
The second one is your choice only if you need more space-efficient solution.
### `GroupexVec`
`GroupexVec` works similar to the previous one but includes `Vec` and its cells can be locked just by index.
It's also **dangerous to lock another cell when one lock already acquired in the thread** because different indexes can be collided due to size of the `RawGroupex`.