Use Array[64] for NS/KS names

We limit the sizes of keyspaces/namespaces because very long names may
cause fs errors on some file systems.
next
Sayan Nandan 3 years ago
parent 8faf653d2e
commit f4379d5688

@ -105,6 +105,24 @@ impl<T, const N: usize> Array<T, N> {
init_len: 0,
}
}
/// This literally turns [T; M] into [T; N]. How can you expect it to be safe?
/// This function is extremely unsafe. I mean, I don't even know how to call it safe.
/// There's one way though: make M == N. This will panic in debug mode if M > N. In
/// release mode, good luck
pub unsafe fn from_const_array<const M: usize>(arr: [T; M]) -> Self {
debug_assert!(
N > M,
"Provided const array exceeds size limit of initialized array"
);
// do not double-free or destroy the elements
let array = ManuallyDrop::new(arr);
let mut arr = Array::<T, N>::new();
// copy it over
let ptr = &*array as *const [T; M] as *const [MaybeUninit<T>; N];
ptr.copy_to_nonoverlapping(&mut arr.stack as *mut [MaybeUninit<T>; N], 1);
arr.set_len(N);
arr
}
/// Get the apparent length of the array
pub const fn len(&self) -> usize {
self.init_len as usize
@ -238,6 +256,15 @@ impl<T, const N: usize> Array<T, N> {
}
}
}
/// Extend self from a slice
///
/// ## Safety
/// The same danger as in from_slice_unchecked
pub unsafe fn from_slice(slice_ref: impl AsRef<[T]>) -> Self {
let mut slf = Self::new();
slf.extend_from_slice_unchecked(slice_ref.as_ref());
slf
}
// these operations are incredibly safe because we only pass the initialized part
// of the array
/// Get self as a slice. Super safe because we guarantee that all the other invarians
@ -266,16 +293,7 @@ impl<T, const N: usize> ops::DerefMut for Array<T, N> {
impl<T, const N: usize> From<[T; N]> for Array<T, N> {
fn from(array: [T; N]) -> Self {
// do not double-free or destroy the elements
let array = ManuallyDrop::new(array);
let mut arr = Array::<T, N>::new();
unsafe {
// copy it over
let ptr = &*array as *const [T; N] as *const [MaybeUninit<T>; N];
ptr.copy_to_nonoverlapping(&mut arr.stack as *mut [MaybeUninit<T>; N], 1);
arr.set_len(N);
}
arr
unsafe { Array::from_const_array::<N>(array) }
}
}
@ -557,7 +575,7 @@ macro_rules! array_from_string {
}
#[test]
fn test_map_serialize() {
fn test_map_serialize_deserialize() {
use crate::coredb::htable::Coremap;
let map = Coremap::new();
map.true_if_insert(
@ -569,3 +587,17 @@ fn test_map_serialize() {
assert!(bc.len() == map.len());
assert!(bc.into_iter().all(|(k, _v)| { map.contains_key(&k) }));
}
#[test]
#[should_panic]
fn test_array_overflow() {
let mut arr: Array<u8, 5> = Array::new();
arr.extend_from_slice("123456".as_bytes()).unwrap();
}
#[test]
#[should_panic]
fn test_array_overflow_iter() {
let mut arr: Array<char, 5> = Array::new();
arr.extend("123456".chars());
}

@ -56,6 +56,7 @@
#![allow(dead_code)] // TODO(@ohsayan): Remove this onece we're done
use crate::coredb::array::Array;
use crate::coredb::htable::Coremap;
use crate::coredb::htable::Data;
use crate::coredb::SnapshotStatus;
@ -63,6 +64,16 @@ use crate::kvengine::KVEngine;
use std::sync::atomic::AtomicBool;
use std::sync::Arc;
const DEFAULT_ARRAY: [u8; 7] = [b'd', b'e', b'f', b'a', b'u', b'l', b't'];
/// typedef for the namespace/keyspace IDs. We don't need too much fancy here,
/// no atomic pointers and all. Just a nice array. With amazing gurantees
type NsKsTblId = Array<u8, 64>;
macro_rules! defaultid {
() => {{
unsafe { Array::from_const_array(DEFAULT_ARRAY) }
}};
}
mod cluster {
/// This is for the future where every node will be allocated a shard
#[derive(Debug)]
@ -105,7 +116,7 @@ pub enum DdlError {
/// for connection-level control abilities over the namespace
pub struct Memstore {
/// the namespaces
namespaces: Arc<Coremap<Data, Arc<Namespace>>>,
namespaces: Arc<Coremap<NsKsTblId, Arc<Namespace>>>,
}
impl Memstore {
@ -134,19 +145,22 @@ impl Memstore {
Self {
namespaces: {
let n = Coremap::new();
n.true_if_insert(Data::from("default"), Arc::new(Namespace::empty_default()));
n.true_if_insert(defaultid!(), Arc::new(Namespace::empty_default()));
Arc::new(n)
},
}
}
/// Get an atomic reference to a namespace
pub fn get_namespace_atomic_ref(&self, namespace_identifier: Data) -> Option<Arc<Namespace>> {
pub fn get_namespace_atomic_ref(
&self,
namespace_identifier: NsKsTblId,
) -> Option<Arc<Namespace>> {
self.namespaces
.get(&namespace_identifier)
.map(|ns| ns.clone())
}
/// Returns true if a new namespace was created
pub fn create_namespace(&self, namespace_identifier: Data) -> bool {
pub fn create_namespace(&self, namespace_identifier: NsKsTblId) -> bool {
self.namespaces
.true_if_insert(namespace_identifier, Arc::new(Namespace::empty()))
}
@ -156,7 +170,7 @@ impl Memstore {
/// Namespaces hold keyspaces
pub struct Namespace {
/// the keyspaces stored in this namespace
keyspaces: Coremap<Data, Arc<Keyspace>>,
keyspaces: Coremap<NsKsTblId, Arc<Keyspace>>,
/// the shard range
shard_range: cluster::ClusterShardRange,
}
@ -180,24 +194,24 @@ impl Namespace {
Self {
keyspaces: {
let ks = Coremap::new();
ks.true_if_insert(Data::from("default"), Arc::new(Keyspace::empty_default()));
ks.true_if_insert(defaultid!(), Arc::new(Keyspace::empty_default()));
ks
},
shard_range: cluster::ClusterShardRange::default(),
}
}
/// Get an atomic reference to a keyspace, if it exists
pub fn get_keyspace_atomic_ref(&self, keyspace_idenitifer: Data) -> Option<Arc<Keyspace>> {
pub fn get_keyspace_atomic_ref(&self, keyspace_idenitifer: NsKsTblId) -> Option<Arc<Keyspace>> {
self.keyspaces.get(&keyspace_idenitifer).map(|v| v.clone())
}
/// Create a new keyspace if it doesn't exist
pub fn create_keyspace(&self, keyspace_idenitifer: Data) -> bool {
pub fn create_keyspace(&self, keyspace_idenitifer: NsKsTblId) -> bool {
self.keyspaces
.true_if_insert(keyspace_idenitifer, Arc::new(Keyspace::empty()))
}
/// Drop a keyspace if it is not in use **and** it is empty and not the default
pub fn drop_keyspace(&self, keyspace_idenitifer: Data) -> Result<(), DdlError> {
if keyspace_idenitifer.eq(&Data::from("default")) {
pub fn drop_keyspace(&self, keyspace_idenitifer: NsKsTblId) -> Result<(), DdlError> {
if keyspace_idenitifer.eq(&defaultid!()) {
// can't delete default keyspace
Err(DdlError::ProtectedObject)
} else if self.keyspaces.contains_key(&keyspace_idenitifer) {

Loading…
Cancel
Save