Upgrade deps

Also added docs for Skymap
next
Sayan Nandan 3 years ago
parent da8462eda3
commit 42f3251d2c

23
Cargo.lock generated

@ -223,12 +223,6 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "doc-comment"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
[[package]] [[package]]
name = "either" name = "either"
version = "1.6.1" version = "1.6.1"
@ -468,9 +462,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.98" version = "0.2.99"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790" checksum = "a7f823d141fe0a24df1e23b4af4e3c7ba9e5966ec514ea068c93024aa7deb765"
[[package]] [[package]]
name = "libsky" name = "libsky"
@ -878,18 +872,18 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.126" version = "1.0.127"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03" checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.126" version = "1.0.127"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43" checksum = "a024926d3432516606328597e0f224a51355a493b49fdd67e9209187cbe55ecc"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -1067,13 +1061,12 @@ dependencies = [
[[package]] [[package]]
name = "sysinfo" name = "sysinfo"
version = "0.19.2" version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e7de153d0438a648bb71e06e300e54fc641685e96af96d49b843f43172d341c" checksum = "0af066e6272f2175c1783cfc2ebf3e2d8dfe2c182b00677fdeccbf8291af83fb"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"core-foundation-sys", "core-foundation-sys",
"doc-comment",
"libc", "libc",
"ntapi", "ntapi",
"once_cell", "once_cell",

@ -8,10 +8,13 @@ edition = "2018"
[dependencies] [dependencies]
# internal deps # internal deps
libsky = { path="../libsky" } libsky = { path = "../libsky" }
skytable = { git="https://github.com/skytable/client-rust", branch="next", features=["async", "aio-sslv"], default-features=false } skytable = { git = "https://github.com/skytable/client-rust", branch = "next", features = [
"async",
"aio-sslv",
], default-features = false }
# external deps # external deps
tokio = { version="1.9.0", features=["full"] } tokio = { version = "1.9.0", features = ["full"] }
clap = { version="2.33.3", features=["yaml"] } clap = { version = "2.33.3", features = ["yaml"] }
rustyline = "8.2.0" rustyline = "8.2.0"
crossterm = "0.20.0" crossterm = "0.20.0"

@ -8,7 +8,9 @@ edition = "2018"
[dependencies] [dependencies]
# internal deps # internal deps
skytable = { git="https://github.com/skytable/client-rust", branch="next", features=["dbg"], default-features=false } skytable = { git = "https://github.com/skytable/client-rust", branch = "next", features = [
"dbg",
], default-features = false }
# external deps # external deps
lazy_static = "1.4.0" lazy_static = "1.4.0"
termcolor = "1.1.2" termcolor = "1.1.2"

@ -9,12 +9,12 @@ build = "build.rs"
# internal deps # internal deps
skytable = { git = "https://github.com/skytable/client-rust", branch = "next", default-features = false } skytable = { git = "https://github.com/skytable/client-rust", branch = "next", default-features = false }
sky_macros = { path = "../sky-macros" } sky_macros = { path = "../sky-macros" }
libsky = { path = "../libsky" }
# external deps # external deps
tokio = { version = "1.9.0", features = ["full"] } tokio = { version = "1.9.0", features = ["full"] }
ahash = "0.7.4" ahash = "0.7.4"
bytes = "1.0.1" bytes = "1.0.1"
libsky = { path = "../libsky" } serde = { version = "1.0.127", features = ["derive"] }
serde = { version = "1.0.126", features = ["derive"] }
toml = "0.5.8" toml = "0.5.8"
clap = { version = "2.33.3", features = ["yaml"] } clap = { version = "2.33.3", features = ["yaml"] }
env_logger = "0.9.0" env_logger = "0.9.0"
@ -23,7 +23,7 @@ chrono = "0.4.19"
regex = "1.5.4" regex = "1.5.4"
tokio-openssl = "0.6.2" tokio-openssl = "0.6.2"
openssl = { version = "0.10.35", features = ["vendored"] } openssl = { version = "0.10.35", features = ["vendored"] }
hashbrown = { version = "*", features = ["raw"] } hashbrown = { version = "0.11.2", features = ["raw"] }
parking_lot = "0.11.1" parking_lot = "0.11.1"
num_cpus = "1.13.0" num_cpus = "1.13.0"
@ -51,4 +51,4 @@ rand = "0.8.4"
bincode = "1.3.3" bincode = "1.3.3"
[target.'cfg(unix)'.dependencies] [target.'cfg(unix)'.dependencies]
# external deps # external deps
libc = "0.2.98" libc = "0.2.99"

@ -36,7 +36,7 @@ macro_rules! push_self {
macro_rules! lut { macro_rules! lut {
($e:expr) => { ($e:expr) => {
PAIR_MAP_LUT[($e) as usize] *PAIR_MAP_LUT.get_unchecked(($e) as usize)
}; };
} }

@ -37,22 +37,27 @@ use parking_lot::RwLockWriteGuard;
use std::collections::hash_map::RandomState; use std::collections::hash_map::RandomState;
use std::sync::Arc; use std::sync::Arc;
/// A read-only reference to a bucket
pub struct Ref<'a, K, V> { pub struct Ref<'a, K, V> {
_guard: RwLockReadGuard<'a, LowMap<K, V>>, _g: RwLockReadGuard<'a, LowMap<K, V>>,
k: &'a K, k: &'a K,
v: &'a V, v: &'a V,
} }
impl<'a, K, V> Ref<'a, K, V> { impl<'a, K, V> Ref<'a, K, V> {
pub const fn new(_guard: RwLockReadGuard<'a, LowMap<K, V>>, k: &'a K, v: &'a V) -> Self { /// Create a new reference
Self { _guard, k, v } pub(super) const fn new(_g: RwLockReadGuard<'a, LowMap<K, V>>, k: &'a K, v: &'a V) -> Self {
Self { _g, k, v }
} }
/// Get a ref to the key
pub const fn key(&self) -> &K { pub const fn key(&self) -> &K {
self.k self.k
} }
/// Get a ref to the value
pub const fn value(&self) -> &V { pub const fn value(&self) -> &V {
self.v self.v
} }
/// Get a ref to the key/value pair
pub const fn pair(&self) -> (&K, &V) { pub const fn pair(&self) -> (&K, &V) {
let Self { k, v, .. } = self; let Self { k, v, .. } = self;
(k, v) (k, v)
@ -69,32 +74,35 @@ impl<'a, K, V> Deref for Ref<'a, K, V> {
unsafe impl<'a, K: Send, V: Send> Send for Ref<'a, K, V> {} unsafe impl<'a, K: Send, V: Send> Send for Ref<'a, K, V> {}
unsafe impl<'a, K: Sync, V: Sync> Sync for Ref<'a, K, V> {} unsafe impl<'a, K: Sync, V: Sync> Sync for Ref<'a, K, V> {}
/// A r/w ref to a bucket
pub struct RefMut<'a, K, V> { pub struct RefMut<'a, K, V> {
guard: RwLockWriteGuard<'a, LowMap<K, V>>, _g: RwLockWriteGuard<'a, LowMap<K, V>>,
k: &'a K, k: &'a K,
v: &'a mut V, v: &'a mut V,
} }
impl<'a, K, V> RefMut<'a, K, V> { impl<'a, K, V> RefMut<'a, K, V> {
pub fn new(guard: RwLockWriteGuard<'a, LowMap<K, V>>, k: &'a K, v: &'a mut V) -> Self { /// Create a new ref
Self { guard, k, v } pub(super) fn new(_g: RwLockWriteGuard<'a, LowMap<K, V>>, k: &'a K, v: &'a mut V) -> Self {
Self { _g, k, v }
} }
/// Get a ref to the key
pub const fn key(&self) -> &K { pub const fn key(&self) -> &K {
self.k self.k
} }
/// Get a ref to the value
pub const fn value(&self) -> &V { pub const fn value(&self) -> &V {
self.v self.v
} }
/// Get a mutable ref to the value
pub fn value_mut(&mut self) -> &mut V { pub fn value_mut(&mut self) -> &mut V {
self.v self.v
} }
/// Get a ref to the k/v pair
pub fn pair(&mut self) -> (&K, &V) { pub fn pair(&mut self) -> (&K, &V) {
let Self { k, v, .. } = self; let Self { k, v, .. } = self;
(k, v) (k, v)
} }
pub fn downgrade_ref(self) -> Ref<'a, K, V> {
Ref::new(RwLockWriteGuard::downgrade(self.guard), self.k, self.v)
}
} }
impl<'a, K, V> Deref for RefMut<'a, K, V> { impl<'a, K, V> Deref for RefMut<'a, K, V> {
@ -113,6 +121,7 @@ impl<'a, K, V> DerefMut for RefMut<'a, K, V> {
unsafe impl<'a, K: Send, V: Send> Send for RefMut<'a, K, V> {} unsafe impl<'a, K: Send, V: Send> Send for RefMut<'a, K, V> {}
unsafe impl<'a, K: Sync, V: Sync> Sync for RefMut<'a, K, V> {} unsafe impl<'a, K: Sync, V: Sync> Sync for RefMut<'a, K, V> {}
/// A reference to an occupied entry
pub struct OccupiedEntry<'a, K, V, S> { pub struct OccupiedEntry<'a, K, V, S> {
guard: RwLockWriteGuard<'a, LowMap<K, V>>, guard: RwLockWriteGuard<'a, LowMap<K, V>>,
elem: (&'a K, &'a mut V), elem: (&'a K, &'a mut V),
@ -121,7 +130,8 @@ pub struct OccupiedEntry<'a, K, V, S> {
} }
impl<'a, K: Hash + Eq, V, S: BuildHasher> OccupiedEntry<'a, K, V, S> { impl<'a, K: Hash + Eq, V, S: BuildHasher> OccupiedEntry<'a, K, V, S> {
pub fn new( /// Create a new occupied entry ref
pub(super) fn new(
guard: RwLockWriteGuard<'a, LowMap<K, V>>, guard: RwLockWriteGuard<'a, LowMap<K, V>>,
key: K, key: K,
elem: (&'a K, &'a mut V), elem: (&'a K, &'a mut V),
@ -134,15 +144,19 @@ impl<'a, K: Hash + Eq, V, S: BuildHasher> OccupiedEntry<'a, K, V, S> {
hasher, hasher,
} }
} }
/// Get a ref to the key
pub fn key(&self) -> &K { pub fn key(&self) -> &K {
self.elem.0 self.elem.0
} }
/// Get a ref to the value
pub fn value(&self) -> &V { pub fn value(&self) -> &V {
self.elem.1 self.elem.1
} }
/// Insert a value into this bucket
pub fn insert(&mut self, other: V) -> V { pub fn insert(&mut self, other: V) -> V {
mem::replace(self.elem.1, other) mem::replace(self.elem.1, other)
} }
/// Remove this element from the map
pub fn remove(mut self) -> V { pub fn remove(mut self) -> V {
let hash = super::make_hash::<K, K, S>(&self.hasher, &self.key); let hash = super::make_hash::<K, K, S>(&self.hasher, &self.key);
unsafe { unsafe {
@ -157,6 +171,7 @@ impl<'a, K: Hash + Eq, V, S: BuildHasher> OccupiedEntry<'a, K, V, S> {
unsafe impl<'a, K: Send, V: Send, S> Send for OccupiedEntry<'a, K, V, S> {} unsafe impl<'a, K: Send, V: Send, S> Send for OccupiedEntry<'a, K, V, S> {}
unsafe impl<'a, K: Sync, V: Sync, S> Sync for OccupiedEntry<'a, K, V, S> {} unsafe impl<'a, K: Sync, V: Sync, S> Sync for OccupiedEntry<'a, K, V, S> {}
/// A ref to a vacant entry
pub struct VacantEntry<'a, K, V, S> { pub struct VacantEntry<'a, K, V, S> {
guard: RwLockWriteGuard<'a, LowMap<K, V>>, guard: RwLockWriteGuard<'a, LowMap<K, V>>,
key: K, key: K,
@ -164,9 +179,11 @@ pub struct VacantEntry<'a, K, V, S> {
} }
impl<'a, K: Hash + Eq, V, S: BuildHasher> VacantEntry<'a, K, V, S> { impl<'a, K: Hash + Eq, V, S: BuildHasher> VacantEntry<'a, K, V, S> {
pub fn new(guard: RwLockWriteGuard<'a, LowMap<K, V>>, key: K, hasher: S) -> Self { /// Create a vacant entry ref
pub(super) fn new(guard: RwLockWriteGuard<'a, LowMap<K, V>>, key: K, hasher: S) -> Self {
Self { guard, key, hasher } Self { guard, key, hasher }
} }
/// Insert a value into this bucket
pub fn insert(mut self, value: V) -> RefMut<'a, K, V> { pub fn insert(mut self, value: V) -> RefMut<'a, K, V> {
unsafe { unsafe {
let hash = super::make_insert_hash::<K, S>(&self.hasher, &self.key); let hash = super::make_insert_hash::<K, S>(&self.hasher, &self.key);
@ -180,28 +197,34 @@ impl<'a, K: Hash + Eq, V, S: BuildHasher> VacantEntry<'a, K, V, S> {
RefMut::new(self.guard, kptr, vptr) RefMut::new(self.guard, kptr, vptr)
} }
} }
/// Turns self into a key (effectively freeing up the entry for another thread)
pub fn into_key(self) -> K { pub fn into_key(self) -> K {
self.key self.key
} }
/// Get a ref to the key
pub fn key(&self) -> &K { pub fn key(&self) -> &K {
&self.key &self.key
} }
} }
/// An entry, either occupied or vacant
pub enum Entry<'a, K, V, S = RandomState> { pub enum Entry<'a, K, V, S = RandomState> {
Occupied(OccupiedEntry<'a, K, V, S>), Occupied(OccupiedEntry<'a, K, V, S>),
Vacant(VacantEntry<'a, K, V, S>), Vacant(VacantEntry<'a, K, V, S>),
} }
impl<'a, K, V, S> Entry<'a, K, V, S> { impl<'a, K, V, S> Entry<'a, K, V, S> {
/// Check if an entry is occupied
pub const fn is_occupied(&self) -> bool { pub const fn is_occupied(&self) -> bool {
matches!(self, Self::Occupied(_)) matches!(self, Self::Occupied(_))
} }
/// Check if an entry is vacant
pub const fn is_vacant(&self) -> bool { pub const fn is_vacant(&self) -> bool {
matches!(self, Self::Vacant(_)) matches!(self, Self::Vacant(_))
} }
} }
/// A shared ref to a key
pub struct RefMulti<'a, K, V> { pub struct RefMulti<'a, K, V> {
_g: Arc<RwLockReadGuard<'a, LowMap<K, V>>>, _g: Arc<RwLockReadGuard<'a, LowMap<K, V>>>,
k: &'a K, k: &'a K,
@ -209,15 +232,19 @@ pub struct RefMulti<'a, K, V> {
} }
impl<'a, K, V> RefMulti<'a, K, V> { impl<'a, K, V> RefMulti<'a, K, V> {
/// Create a new shared ref
pub const fn new(_g: Arc<RwLockReadGuard<'a, LowMap<K, V>>>, k: &'a K, v: &'a V) -> Self { pub const fn new(_g: Arc<RwLockReadGuard<'a, LowMap<K, V>>>, k: &'a K, v: &'a V) -> Self {
Self { _g, k, v } Self { _g, k, v }
} }
/// Get a ref to the key
pub const fn key(&self) -> &K { pub const fn key(&self) -> &K {
self.k self.k
} }
/// Get a ref to the value
pub const fn value(&self) -> &V { pub const fn value(&self) -> &V {
self.v self.v
} }
/// Get a ref to the k/v pair
pub const fn pair(&self) -> (&K, &V) { pub const fn pair(&self) -> (&K, &V) {
let Self { k, v, .. } = self; let Self { k, v, .. } = self;
(k, v) (k, v)
@ -234,6 +261,7 @@ impl<'a, K, V> Deref for RefMulti<'a, K, V> {
unsafe impl<'a, K: Sync, V: Sync> Sync for RefMulti<'a, K, V> {} unsafe impl<'a, K: Sync, V: Sync> Sync for RefMulti<'a, K, V> {}
unsafe impl<'a, K: Send, V: Send> Send for RefMulti<'a, K, V> {} unsafe impl<'a, K: Send, V: Send> Send for RefMulti<'a, K, V> {}
/// A shared r/w ref to a bucket
pub struct RefMultiMut<'a, K, V> { pub struct RefMultiMut<'a, K, V> {
_g: Arc<RwLockWriteGuard<'a, LowMap<K, V>>>, _g: Arc<RwLockWriteGuard<'a, LowMap<K, V>>>,
k: &'a K, k: &'a K,
@ -241,22 +269,28 @@ pub struct RefMultiMut<'a, K, V> {
} }
impl<'a, K, V> RefMultiMut<'a, K, V> { impl<'a, K, V> RefMultiMut<'a, K, V> {
/// Create a new shared r/w ref
pub fn new(_g: Arc<RwLockWriteGuard<'a, LowMap<K, V>>>, k: &'a K, v: &'a mut V) -> Self { pub fn new(_g: Arc<RwLockWriteGuard<'a, LowMap<K, V>>>, k: &'a K, v: &'a mut V) -> Self {
Self { _g, k, v } Self { _g, k, v }
} }
/// Get a ref to the key
pub const fn key(&self) -> &K { pub const fn key(&self) -> &K {
self.k self.k
} }
/// Get a ref to the value
pub const fn value(&self) -> &V { pub const fn value(&self) -> &V {
self.v self.v
} }
/// Get a mutable ref to the value
pub fn value_mut(&mut self) -> &mut V { pub fn value_mut(&mut self) -> &mut V {
self.v self.v
} }
/// Get a ref to the k/v pair
pub fn pair(&self) -> (&K, &V) { pub fn pair(&self) -> (&K, &V) {
let Self { k, v, .. } = self; let Self { k, v, .. } = self;
(k, v) (k, v)
} }
/// Get a mutable ref to the k/v (k, mut v) pair
pub fn pair_mut(&mut self) -> (&K, &mut V) { pub fn pair_mut(&mut self) -> (&K, &mut V) {
let Self { k, v, .. } = self; let Self { k, v, .. } = self;
(k, v) (k, v)

@ -35,6 +35,7 @@ use parking_lot::RwLockWriteGuard;
use std::collections::hash_map::RandomState; use std::collections::hash_map::RandomState;
use std::sync::Arc; use std::sync::Arc;
/// An owned iterator for a [`Skymap`]
pub struct OwnedIter<K, V, S = RandomState> { pub struct OwnedIter<K, V, S = RandomState> {
map: Skymap<K, V, S>, map: Skymap<K, V, S>,
cs: usize, cs: usize,
@ -80,6 +81,7 @@ unsafe impl<K: Sync, V: Sync, S> Sync for OwnedIter<K, V, S> {}
type BorrowedIterGroup<'a, K, V> = (RawIter<(K, V)>, Arc<RwLockReadGuard<'a, LowMap<K, V>>>); type BorrowedIterGroup<'a, K, V> = (RawIter<(K, V)>, Arc<RwLockReadGuard<'a, LowMap<K, V>>>);
type BorrowedIterGroupMut<'a, K, V> = (RawIter<(K, V)>, Arc<RwLockWriteGuard<'a, LowMap<K, V>>>); type BorrowedIterGroupMut<'a, K, V> = (RawIter<(K, V)>, Arc<RwLockWriteGuard<'a, LowMap<K, V>>>);
/// A borrowed iterator for a [`Skymap`]
pub struct BorrowedIter<'a, K, V, S = RandomState> { pub struct BorrowedIter<'a, K, V, S = RandomState> {
map: &'a Skymap<K, V, S>, map: &'a Skymap<K, V, S>,
cs: usize, cs: usize,
@ -131,6 +133,7 @@ impl<'a, K, V, S> Iterator for BorrowedIter<'a, K, V, S> {
unsafe impl<'a, K: Send, V: Send, S> Send for BorrowedIter<'a, K, V, S> {} unsafe impl<'a, K: Send, V: Send, S> Send for BorrowedIter<'a, K, V, S> {}
unsafe impl<'a, K: Sync, V: Sync, S> Sync for BorrowedIter<'a, K, V, S> {} unsafe impl<'a, K: Sync, V: Sync, S> Sync for BorrowedIter<'a, K, V, S> {}
/// A borrowed iterator with mutable references for a [`Skymap`]
pub struct BorrowedIterMut<'a, K, V, S> { pub struct BorrowedIterMut<'a, K, V, S> {
map: &'a Skymap<K, V, S>, map: &'a Skymap<K, V, S>,
cs: usize, cs: usize,

@ -89,13 +89,14 @@ where
} }
fn get_shard_count() -> usize { fn get_shard_count() -> usize {
(num_cpus::get() * 4).next_power_of_two() (num_cpus::get() * 8).next_power_of_two()
} }
const fn cttz(amount: usize) -> usize { const fn cttz(amount: usize) -> usize {
amount.trailing_zeros() as usize amount.trailing_zeros() as usize
} }
/// A striped in-memory map
pub struct Skymap<K, V, S = RandomState> { pub struct Skymap<K, V, S = RandomState> {
shards: Box<ShardSlice<K, V>>, shards: Box<ShardSlice<K, V>>,
hasher: S, hasher: S,
@ -136,6 +137,7 @@ where
} }
impl<K, V> Skymap<K, V, ahash::RandomState> { impl<K, V> Skymap<K, V, ahash::RandomState> {
/// Get a Skymap with the ahash hasher
pub fn new_ahash() -> Self { pub fn new_ahash() -> Self {
Skymap::new() Skymap::new()
} }
@ -146,12 +148,15 @@ impl<K, V, S> Skymap<K, V, S>
where where
S: BuildHasher + Default, S: BuildHasher + Default,
{ {
/// Create a new Skymap with the default state (or seed) of the hasher
pub fn new() -> Self { pub fn new() -> Self {
Self::with_hasher(S::default()) Self::with_hasher(S::default())
} }
/// Create a new Skymap with the provided capacity
pub fn with_capacity(cap: usize) -> Self { pub fn with_capacity(cap: usize) -> Self {
Self::with_capacity_and_hasher(cap, S::default()) Self::with_capacity_and_hasher(cap, S::default())
} }
/// Create a new Skymap with the provided cap and hasher
pub fn with_capacity_and_hasher(mut cap: usize, hasher: S) -> Self { pub fn with_capacity_and_hasher(mut cap: usize, hasher: S) -> Self {
let shard_count = get_shard_count(); let shard_count = get_shard_count();
let shift = BITS_IN_USIZE - cttz(shard_count); let shift = BITS_IN_USIZE - cttz(shard_count);
@ -168,24 +173,31 @@ where
shift, shift,
} }
} }
/// Create a new Skymap with the provided hasher
pub fn with_hasher(hasher: S) -> Self { pub fn with_hasher(hasher: S) -> Self {
Self::with_capacity_and_hasher(DEFAULT_CAP, hasher) Self::with_capacity_and_hasher(DEFAULT_CAP, hasher)
} }
/// Get the len of the Skymap
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
self.shards.iter().map(|s| s.read().len()).sum() self.shards.iter().map(|s| s.read().len()).sum()
} }
/// Get the capacity of the Skymap
pub fn capacity(&self) -> usize { pub fn capacity(&self) -> usize {
self.shards.iter().map(|s| s.read().capacity()).sum() self.shards.iter().map(|s| s.read().capacity()).sum()
} }
/// Check if the Skymap is empty
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
self.len() == 0 self.len() == 0
} }
/// Get a borrowed iterator for the Skymap. Bound to the lifetime
pub fn get_iter(&self) -> BorrowedIter<K, V, S> { pub fn get_iter(&self) -> BorrowedIter<K, V, S> {
BorrowedIter::new(self) BorrowedIter::new(self)
} }
/// Get a borrowed mutable iterator for the Skymap, Bound to the lifetime
pub fn get_iter_mut(&self) -> BorrowedIterMut<K, V, S> { pub fn get_iter_mut(&self) -> BorrowedIterMut<K, V, S> {
BorrowedIterMut::new(self) BorrowedIterMut::new(self)
} }
/// Get an owned iterator to the Skymap
pub fn get_owned_iter(self) -> OwnedIter<K, V, S> { pub fn get_owned_iter(self) -> OwnedIter<K, V, S> {
OwnedIter::new(self) OwnedIter::new(self)
} }
@ -193,12 +205,16 @@ where
// const impls // const impls
impl<K, V, S> Skymap<K, V, S> { impl<K, V, S> Skymap<K, V, S> {
/// Get a ref to the stripes
const fn shards(&self) -> &ShardSlice<K, V> { const fn shards(&self) -> &ShardSlice<K, V> {
&self.shards &self.shards
} }
/// Determine the shard
const fn determine_shard(&self, hash: usize) -> usize { const fn determine_shard(&self, hash: usize) -> usize {
// the idea of the shift was inspired by Joel's idea
(hash << 7) >> self.shift (hash << 7) >> self.shift
} }
/// Get a ref to the underlying hasher
const fn h(&self) -> &S { const fn h(&self) -> &S {
&self.hasher &self.hasher
} }
@ -211,6 +227,7 @@ where
K: Eq + Hash, K: Eq + Hash,
S: BuildHasher + Clone, S: BuildHasher + Clone,
{ {
/// Insert a key/value into the Skymap
pub fn insert(&self, k: K, v: V) -> Option<V> { pub fn insert(&self, k: K, v: V) -> Option<V> {
let hash = make_insert_hash::<K, S>(&self.hasher, &k); let hash = make_insert_hash::<K, S>(&self.hasher, &k);
let idx = self.determine_shard(hash as usize); let idx = self.determine_shard(hash as usize);
@ -226,6 +243,7 @@ where
// end critical section // end critical section
} }
} }
/// Remove a key/value from the Skymap
pub fn remove<Q>(&self, k: &Q) -> Option<(K, V)> pub fn remove<Q>(&self, k: &Q) -> Option<(K, V)>
where where
K: Borrow<Q>, K: Borrow<Q>,
@ -243,6 +261,7 @@ where
// end critical section // end critical section
} }
} }
/// Remove a key/value from the Skymap if it satisfies a certain condition
pub fn remove_if<Q>(&self, k: &Q, f: impl FnOnce(&K, &V) -> bool) -> Option<(K, V)> pub fn remove_if<Q>(&self, k: &Q, f: impl FnOnce(&K, &V) -> bool) -> Option<(K, V)>
where where
K: Borrow<Q>, K: Borrow<Q>,
@ -271,6 +290,7 @@ where
// lt impls // lt impls
impl<'a, K: 'a + Hash + Eq, V: 'a, S: BuildHasher + Clone> Skymap<K, V, S> { impl<'a, K: 'a + Hash + Eq, V: 'a, S: BuildHasher + Clone> Skymap<K, V, S> {
/// Get a ref to an entry in the Skymap
pub fn get<Q>(&'a self, k: &Q) -> Option<Ref<'a, K, V>> pub fn get<Q>(&'a self, k: &Q) -> Option<Ref<'a, K, V>>
where where
K: Borrow<Q>, K: Borrow<Q>,
@ -293,6 +313,7 @@ impl<'a, K: 'a + Hash + Eq, V: 'a, S: BuildHasher + Clone> Skymap<K, V, S> {
} }
} }
/// Get a mutable ref to an entry in the Skymap
pub fn get_mut<Q>(&'a self, k: &Q) -> Option<RefMut<'a, K, V>> pub fn get_mut<Q>(&'a self, k: &Q) -> Option<RefMut<'a, K, V>>
where where
K: Borrow<Q>, K: Borrow<Q>,
@ -314,6 +335,7 @@ impl<'a, K: 'a + Hash + Eq, V: 'a, S: BuildHasher + Clone> Skymap<K, V, S> {
// end critical section // end critical section
} }
} }
/// Get an entry for in-place mutation
pub fn entry(&'a self, key: K) -> Entry<'a, K, V, S> { pub fn entry(&'a self, key: K) -> Entry<'a, K, V, S> {
let hash = make_insert_hash::<K, S>(self.h(), &key); let hash = make_insert_hash::<K, S>(self.h(), &key);
let idx = self.determine_shard(hash as usize); let idx = self.determine_shard(hash as usize);
@ -336,6 +358,7 @@ impl<'a, K: 'a + Hash + Eq, V: 'a, S: BuildHasher + Clone> Skymap<K, V, S> {
// end critical section // end critical section
} }
} }
/// Check if the Skymap contains the provided key
pub fn contains_key<Q>(&self, key: &Q) -> bool pub fn contains_key<Q>(&self, key: &Q) -> bool
where where
K: Borrow<Q>, K: Borrow<Q>,
@ -343,16 +366,40 @@ impl<'a, K: 'a + Hash + Eq, V: 'a, S: BuildHasher + Clone> Skymap<K, V, S> {
{ {
self.get(key).is_some() self.get(key).is_some()
} }
/// Clear out all the entries in the Skymap
pub fn clear(&self) { pub fn clear(&self) {
self.shards().iter().for_each(|shard| shard.write().clear()) self.shards().iter().for_each(|shard| shard.write().clear())
} }
} }
// cloned impls
impl<'a, K: Clone, V: Clone, S: BuildHasher> Skymap<K, V, S> {
pub fn get_cloned<Q>(&'a self, k: &Q) -> Option<V>
where
K: Borrow<Q>,
Q: Hash + Eq + ?Sized,
{
let hash = make_hash::<K, Q, S>(self.h(), k);
let idx = self.determine_shard(hash as usize);
unsafe {
// begin critical section
let lowtable = self.get_rshard_unchecked(idx);
match lowtable.get(hash, ceq(k)) {
Some((_kptr, ref vptr)) => Some(vptr.clone()),
None => None,
}
// end critical section
}
}
}
// inner impls // inner impls
impl<'a, K: 'a, V: 'a, S> Skymap<K, V, S> { impl<'a, K: 'a, V: 'a, S> Skymap<K, V, S> {
/// Get a rlock to a certain stripe
unsafe fn get_rshard_unchecked(&'a self, shard: usize) -> SRlock<'a, K, V> { unsafe fn get_rshard_unchecked(&'a self, shard: usize) -> SRlock<'a, K, V> {
self.shards.get_unchecked(shard).read() self.shards.get_unchecked(shard).read()
} }
/// Get a wlock to a certain stripe
unsafe fn get_wshard_unchecked(&'a self, shard: usize) -> SWlock<'a, K, V> { unsafe fn get_wshard_unchecked(&'a self, shard: usize) -> SWlock<'a, K, V> {
self.shards.get_unchecked(shard).write() self.shards.get_unchecked(shard).write()
} }

@ -8,12 +8,12 @@ edition = "2018"
[dependencies] [dependencies]
# internal deps # internal deps
skytable = { git="https://github.com/skytable/client-rust", branch="next" } skytable = { git = "https://github.com/skytable/client-rust", branch = "next" }
libsky = { path="../libsky" } libsky = { path = "../libsky" }
libstress = { path="../libstress" } libstress = { path = "../libstress" }
# external deps # external deps
rand = "0.8.4" rand = "0.8.4"
devtimer = "4.0.1" devtimer = "4.0.1"
clap = { version="2.33.3", features=["yaml"] } clap = { version = "2.33.3", features = ["yaml"] }
serde = { version="1.0.126", features=["derive"] } serde = { version = "1.0.127", features = ["derive"] }
serde_json = "1.0.66" serde_json = "1.0.66"

@ -12,7 +12,7 @@ libstress = { path = "../libstress" }
skytable = { git = "https://github.com/skytable/client-rust.git", branch = "next", features = [ skytable = { git = "https://github.com/skytable/client-rust.git", branch = "next", features = [
"dbg", "dbg",
] } ] }
sysinfo = "0.19.2" sysinfo = "0.20.0"
devtimer = "4.0.1" devtimer = "4.0.1"
# external deps # external deps
env_logger = "0.9.0" env_logger = "0.9.0"

Loading…
Cancel
Save