Impl SDSS Writer
parent
17b07897e5
commit
9091db6bd3
@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Created on Thu Jul 23 2023
|
||||
*
|
||||
* This file is a part of Skytable
|
||||
* Skytable (formerly known as TerrabaseDB or Skybase) is a free and open-source
|
||||
* NoSQL database written by Sayan Nandan ("the Author") with the
|
||||
* vision to provide flexibility in data modelling without compromising
|
||||
* on performance, queryability or scalability.
|
||||
*
|
||||
* Copyright (c) 2023, Sayan Nandan <ohsayan@outlook.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
use {
|
||||
super::{
|
||||
rw::{RawFileIOInterface, RawFileOpen},
|
||||
SDSSError, SDSSResult,
|
||||
},
|
||||
crate::engine::sync::cell::Lazy,
|
||||
parking_lot::RwLock,
|
||||
std::{
|
||||
collections::{hash_map::Entry, HashMap},
|
||||
io::{ErrorKind, Read, Write},
|
||||
},
|
||||
};
|
||||
|
||||
static VFS: Lazy<
|
||||
RwLock<HashMap<String, VirtualFile>>,
|
||||
fn() -> RwLock<HashMap<String, VirtualFile>>,
|
||||
> = Lazy::new(|| RwLock::new(HashMap::new()));
|
||||
|
||||
fn vfs<T>(fname: &str, mut func: impl FnMut(&mut VirtualFile) -> SDSSResult<T>) -> SDSSResult<T> {
|
||||
let mut vfs = VFS.write();
|
||||
let f = vfs
|
||||
.get_mut(fname)
|
||||
.ok_or(SDSSError::from(std::io::Error::from(ErrorKind::NotFound)))?;
|
||||
func(f)
|
||||
}
|
||||
|
||||
struct VirtualFile {
|
||||
read: bool,
|
||||
write: bool,
|
||||
data: Vec<u8>,
|
||||
}
|
||||
|
||||
impl VirtualFile {
|
||||
fn new(read: bool, write: bool, data: Vec<u8>) -> Self {
|
||||
Self { read, write, data }
|
||||
}
|
||||
fn rw(data: Vec<u8>) -> Self {
|
||||
Self::new(true, true, data)
|
||||
}
|
||||
fn w(data: Vec<u8>) -> Self {
|
||||
Self::new(false, true, data)
|
||||
}
|
||||
fn r(data: Vec<u8>) -> Self {
|
||||
Self::new(true, false, data)
|
||||
}
|
||||
}
|
||||
|
||||
struct VirtualFileInterface(Box<str>);
|
||||
|
||||
impl RawFileIOInterface for VirtualFileInterface {
|
||||
fn fopen_or_create_rw(file_path: &str) -> SDSSResult<RawFileOpen<Self>> {
|
||||
match VFS.write().entry(file_path.to_owned()) {
|
||||
Entry::Occupied(_) => Ok(RawFileOpen::Existing(Self(file_path.into()))),
|
||||
Entry::Vacant(ve) => {
|
||||
ve.insert(VirtualFile::rw(vec![]));
|
||||
Ok(RawFileOpen::Created(Self(file_path.into())))
|
||||
}
|
||||
}
|
||||
}
|
||||
fn fread_exact(&mut self, buf: &mut [u8]) -> super::SDSSResult<()> {
|
||||
vfs(&self.0, |f| {
|
||||
assert!(f.read);
|
||||
f.data.as_slice().read_exact(buf)?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
fn fwrite_all(&mut self, bytes: &[u8]) -> super::SDSSResult<()> {
|
||||
vfs(&self.0, |f| {
|
||||
assert!(f.write);
|
||||
f.data.write_all(bytes)?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
fn fsync_all(&mut self) -> super::SDSSResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
mod rw {
|
||||
use {
|
||||
super::VirtualFileInterface,
|
||||
crate::engine::storage::v1::{
|
||||
header_impl::{FileScope, FileSpecifier, FileSpecifierVersion, HostRunMode},
|
||||
rw::{FileOpen, SDSSFileIO},
|
||||
},
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn create_delete() {
|
||||
let f = SDSSFileIO::<VirtualFileInterface>::open_or_create_perm_rw(
|
||||
"hello_world.db-tlog",
|
||||
FileScope::TransactionLogCompacted,
|
||||
FileSpecifier::GNSTxnLog,
|
||||
FileSpecifierVersion::__new(0),
|
||||
0,
|
||||
HostRunMode::Prod,
|
||||
0,
|
||||
)
|
||||
.unwrap();
|
||||
match f {
|
||||
FileOpen::Existing(_, _) => panic!(),
|
||||
FileOpen::Created(_) => {}
|
||||
};
|
||||
let open = SDSSFileIO::<VirtualFileInterface>::open_or_create_perm_rw(
|
||||
"hello_world.db-tlog",
|
||||
FileScope::TransactionLogCompacted,
|
||||
FileSpecifier::GNSTxnLog,
|
||||
FileSpecifierVersion::__new(0),
|
||||
0,
|
||||
HostRunMode::Prod,
|
||||
0,
|
||||
)
|
||||
.unwrap();
|
||||
let h = match open {
|
||||
FileOpen::Existing(_, header) => header,
|
||||
_ => panic!(),
|
||||
};
|
||||
assert_eq!(h.gr_mdr().file_scope(), FileScope::TransactionLogCompacted);
|
||||
assert_eq!(h.gr_mdr().file_spec(), FileSpecifier::GNSTxnLog);
|
||||
assert_eq!(h.gr_mdr().file_spec_id(), FileSpecifierVersion::__new(0));
|
||||
assert_eq!(h.gr_hr().run_mode(), HostRunMode::Prod);
|
||||
assert_eq!(h.gr_hr().setting_version(), 0);
|
||||
assert_eq!(h.gr_hr().startup_counter(), 0);
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Created on Thu Jul 23 2023
|
||||
*
|
||||
* This file is a part of Skytable
|
||||
* Skytable (formerly known as TerrabaseDB or Skybase) is a free and open-source
|
||||
* NoSQL database written by Sayan Nandan ("the Author") with the
|
||||
* vision to provide flexibility in data modelling without compromising
|
||||
* on performance, queryability or scalability.
|
||||
*
|
||||
* Copyright (c) 2023, Sayan Nandan <ohsayan@outlook.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
+----------------+------------------------------+-----------------+------------------+--------------------+
|
||||
| EVENT ID (16B) | EVENT SOURCE + METADATA (8B) | EVENT MD5 (16B) | PAYLOAD LEN (8B) | EVENT PAYLOAD (?B) |
|
||||
+----------------+------------------------------+-----------------+------------------+--------------------+
|
||||
Event ID:
|
||||
- The atomically incrementing event ID (for future scale we have 16B; it's like the ZFS situation haha)
|
||||
- Event source (1B) + 7B padding (for future metadata)
|
||||
- Event MD5; yeah, it's "not as strong as" SHA256 but I've chosen to have it here (since it's sometimes faster and further on,
|
||||
we already sum the entire log)
|
||||
- Payload len: the size of the pyload
|
||||
- Payload: the payload
|
||||
*/
|
Loading…
Reference in New Issue