diff --git a/src/database/document_key.rs b/src/database/document_key.rs new file mode 100644 index 000000000..09eba8067 --- /dev/null +++ b/src/database/document_key.rs @@ -0,0 +1,96 @@ +use std::io::{Cursor, Read, Write}; +use std::mem::size_of; + +use byteorder::{NativeEndian, WriteBytesExt, ReadBytesExt}; + +use crate::index::schema::SchemaAttr; +use crate::DocumentId; + +const DOC_KEY_LEN: usize = 4 + size_of::(); +const DOC_KEY_ATTR_LEN: usize = DOC_KEY_LEN + 1 + size_of::(); + +#[derive(Copy, Clone)] +pub struct DocumentKey([u8; DOC_KEY_LEN]); + +impl DocumentKey { + pub fn new(id: DocumentId) -> DocumentKey { + let mut buffer = [0; DOC_KEY_LEN]; + + let mut wtr = Cursor::new(&mut buffer[..]); + wtr.write_all(b"doc-").unwrap(); + wtr.write_u64::(id).unwrap(); + + DocumentKey(buffer) + } + + pub fn from_bytes(mut bytes: &[u8]) -> DocumentKey { + assert!(bytes.len() >= DOC_KEY_LEN); + assert_eq!(&bytes[..4], b"doc-"); + + let mut buffer = [0; DOC_KEY_LEN]; + bytes.read_exact(&mut buffer).unwrap(); + + DocumentKey(buffer) + } + + pub fn with_attribute(&self, attr: SchemaAttr) -> DocumentKeyAttr { + DocumentKeyAttr::new(self.document_id(), attr) + } + + pub fn document_id(&self) -> DocumentId { + (&self.0[4..]).read_u64::().unwrap() + } +} + +impl AsRef<[u8]> for DocumentKey { + fn as_ref(&self) -> &[u8] { + &self.0 + } +} + +#[derive(Copy, Clone)] +pub struct DocumentKeyAttr([u8; DOC_KEY_ATTR_LEN]); + +impl DocumentKeyAttr { + pub fn new(id: DocumentId, attr: SchemaAttr) -> DocumentKeyAttr { + let mut buffer = [0; DOC_KEY_ATTR_LEN]; + let DocumentKey(raw_key) = DocumentKey::new(id); + + let mut wtr = Cursor::new(&mut buffer[..]); + wtr.write_all(&raw_key).unwrap(); + wtr.write_all(b"-").unwrap(); + wtr.write_u32::(attr.as_u32()).unwrap(); + + DocumentKeyAttr(buffer) + } + + pub fn from_bytes(mut bytes: &[u8]) -> DocumentKeyAttr { + assert!(bytes.len() >= DOC_KEY_ATTR_LEN); + assert_eq!(&bytes[..4], b"doc-"); + + let mut buffer = [0; DOC_KEY_ATTR_LEN]; + bytes.read_exact(&mut buffer).unwrap(); + + DocumentKeyAttr(buffer) + } + + pub fn document_id(&self) -> DocumentId { + (&self.0[4..]).read_u64::().unwrap() + } + + pub fn attribute(&self) -> SchemaAttr { + let offset = 4 + size_of::() + 1; + let value = (&self.0[offset..]).read_u32::().unwrap(); + SchemaAttr::new(value) + } + + pub fn into_document_key(self) -> DocumentKey { + DocumentKey::new(self.document_id()) + } +} + +impl AsRef<[u8]> for DocumentKeyAttr { + fn as_ref(&self) -> &[u8] { + &self.0 + } +} diff --git a/src/database/mod.rs b/src/database/mod.rs index 3d8e6e184..2cc38c72c 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -1,27 +1,24 @@ -use std::io::{Cursor, Read, Write}; use std::{fmt, marker}; use std::error::Error; -use std::mem::size_of; use std::path::Path; -use rocksdb::rocksdb::{DB, Snapshot, DBVector}; +use rocksdb::rocksdb::{DB, Snapshot}; use rocksdb::rocksdb_options::ReadOptions; -use byteorder::{NativeEndian, WriteBytesExt, ReadBytesExt}; use serde::de::{DeserializeOwned, Visitor}; use serde::de::value::MapDeserializer; use serde::forward_to_deserialize_any; -use crate::index::schema::{Schema, SchemaAttr}; +use crate::index::schema::Schema; use crate::blob::positive::PositiveBlob; use crate::index::update::Update; +use crate::database::document_key::{DocumentKey, DocumentKeyAttr}; use crate::DocumentId; +pub mod document_key; + const DATA_INDEX: &[u8] = b"data-index"; const DATA_SCHEMA: &[u8] = b"data-schema"; -const DOC_KEY_LEN: usize = 4 + size_of::(); -const DOC_KEY_ATTR_LEN: usize = DOC_KEY_LEN + 1 + size_of::(); - // FIXME Do not panic! fn retrieve_data_schema(snapshot: &Snapshot<&DB>) -> Result> { match snapshot.get(DATA_SCHEMA)? { @@ -37,92 +34,6 @@ fn retrieve_data_index(snapshot: &Snapshot<&DB>) -> Result DocumentKey { - let mut buffer = [0; DOC_KEY_LEN]; - - let mut wtr = Cursor::new(&mut buffer[..]); - wtr.write_all(b"doc-").unwrap(); - wtr.write_u64::(id).unwrap(); - - DocumentKey(buffer) - } - - pub fn from_bytes(mut bytes: &[u8]) -> DocumentKey { - assert!(bytes.len() >= DOC_KEY_LEN); - assert_eq!(&bytes[..4], b"doc-"); - - let mut buffer = [0; DOC_KEY_LEN]; - bytes.read_exact(&mut buffer).unwrap(); - - DocumentKey(buffer) - } - - pub fn with_attribute(&self, attr: SchemaAttr) -> DocumentKeyAttr { - DocumentKeyAttr::new(self.document_id(), attr) - } - - pub fn document_id(&self) -> DocumentId { - (&self.0[4..]).read_u64::().unwrap() - } -} - -impl AsRef<[u8]> for DocumentKey { - fn as_ref(&self) -> &[u8] { - &self.0 - } -} - -#[derive(Copy, Clone)] -pub struct DocumentKeyAttr([u8; DOC_KEY_ATTR_LEN]); - -impl DocumentKeyAttr { - pub fn new(id: DocumentId, attr: SchemaAttr) -> DocumentKeyAttr { - let mut buffer = [0; DOC_KEY_ATTR_LEN]; - let DocumentKey(raw_key) = DocumentKey::new(id); - - let mut wtr = Cursor::new(&mut buffer[..]); - wtr.write_all(&raw_key).unwrap(); - wtr.write_all(b"-").unwrap(); - wtr.write_u32::(attr.as_u32()).unwrap(); - - DocumentKeyAttr(buffer) - } - - pub fn from_bytes(mut bytes: &[u8]) -> DocumentKeyAttr { - assert!(bytes.len() >= DOC_KEY_ATTR_LEN); - assert_eq!(&bytes[..4], b"doc-"); - - let mut buffer = [0; DOC_KEY_ATTR_LEN]; - bytes.read_exact(&mut buffer).unwrap(); - - DocumentKeyAttr(buffer) - } - - pub fn document_id(&self) -> DocumentId { - (&self.0[4..]).read_u64::().unwrap() - } - - pub fn attribute(&self) -> SchemaAttr { - let offset = 4 + size_of::() + 1; - let value = (&self.0[offset..]).read_u32::().unwrap(); - SchemaAttr::new(value) - } - - pub fn into_document_key(self) -> DocumentKey { - DocumentKey::new(self.document_id()) - } -} - -impl AsRef<[u8]> for DocumentKeyAttr { - fn as_ref(&self) -> &[u8] { - &self.0 - } -} - pub struct Database(DB); impl Database {