Replaces Store::open_with_options with explicit variants

Trades enums and structs for methods
pull/409/head
Tpt 2 years ago committed by Thomas Tanon
parent df2233c51c
commit 855c39146d
  1. 38
      lib/src/storage/backend/rocksdb.rs
  2. 3
      lib/src/storage/binary_encoder.rs
  3. 17
      lib/src/storage/mod.rs
  4. 2
      lib/src/storage/numeric_encoder.rs
  5. 46
      lib/src/store.rs
  6. 12
      lib/tests/store.rs
  7. 13
      server/src/main.rs

@ -2,8 +2,7 @@
#![allow(unsafe_code, trivial_casts)] #![allow(unsafe_code, trivial_casts)]
use crate::storage::error::StorageError; use crate::storage::error::{CorruptionError, StorageError};
use crate::store::{CorruptionError, StoreOpenOptions};
use lazy_static::lazy_static; use lazy_static::lazy_static;
use libc::{self, c_char, c_void, free}; use libc::{self, c_char, c_void, free};
use oxrocksdb_sys::*; use oxrocksdb_sys::*;
@ -225,28 +224,33 @@ impl Db {
column_families: Vec<ColumnFamilyDefinition>, column_families: Vec<ColumnFamilyDefinition>,
) -> Result<Self, StorageError> { ) -> Result<Self, StorageError> {
Ok(Self(Arc::new(Self::do_open( Ok(Self(Arc::new(Self::do_open(
path.to_owned(), path.to_path_buf(),
column_families, column_families,
&OpeningMode::Primary, &OpeningMode::Primary,
)?))) )?)))
} }
pub fn open_with_options( pub fn open_secondary(
options: StoreOpenOptions, primary_path: &Path,
secondary_path: &Path,
column_families: Vec<ColumnFamilyDefinition>, column_families: Vec<ColumnFamilyDefinition>,
) -> Result<Self, StorageError> { ) -> Result<Self, StorageError> {
match options { Ok(Self(Arc::new(Self::do_open(
StoreOpenOptions::OpenAsReadOnly(options) => Ok(Self(Arc::new(Self::do_open( primary_path.to_path_buf(),
options.path, column_families,
column_families, &OpeningMode::Secondary(secondary_path.to_path_buf()),
&OpeningMode::ReadOnly, )?)))
)?))), }
StoreOpenOptions::OpenAsSecondary(options) => Ok(Self(Arc::new(Self::do_open(
options.path, pub fn open_read_only(
column_families, path: &Path,
&OpeningMode::Secondary(options.secondary_path), column_families: Vec<ColumnFamilyDefinition>,
)?))), ) -> Result<Self, StorageError> {
} Ok(Self(Arc::new(Self::do_open(
path.to_path_buf(),
column_families,
&OpeningMode::ReadOnly,
)?)))
} }
fn do_open( fn do_open(

@ -1,7 +1,6 @@
use crate::storage::error::{CorruptionError, StorageError};
use crate::storage::numeric_encoder::{EncodedQuad, EncodedTerm, EncodedTriple, StrHash}; use crate::storage::numeric_encoder::{EncodedQuad, EncodedTerm, EncodedTriple, StrHash};
use crate::storage::small_string::SmallString; use crate::storage::small_string::SmallString;
use crate::storage::StorageError;
use crate::store::CorruptionError;
use oxsdatatypes::*; use oxsdatatypes::*;
use std::io::{Cursor, Read}; use std::io::{Cursor, Read};
use std::mem::size_of; use std::mem::size_of;

@ -14,7 +14,6 @@ pub use crate::storage::error::{CorruptionError, LoaderError, SerializerError, S
#[cfg(not(target_family = "wasm"))] #[cfg(not(target_family = "wasm"))]
use crate::storage::numeric_encoder::Decoder; use crate::storage::numeric_encoder::Decoder;
use crate::storage::numeric_encoder::{insert_term, EncodedQuad, EncodedTerm, StrHash, StrLookup}; use crate::storage::numeric_encoder::{insert_term, EncodedQuad, EncodedTerm, StrHash, StrLookup};
pub use crate::store::StoreOpenOptions;
use backend::{ColumnFamily, ColumnFamilyDefinition, Db, Iter}; use backend::{ColumnFamily, ColumnFamilyDefinition, Db, Iter};
#[cfg(not(target_family = "wasm"))] #[cfg(not(target_family = "wasm"))]
use std::cmp::{max, min}; use std::cmp::{max, min};
@ -92,8 +91,20 @@ impl Storage {
} }
#[cfg(not(target_family = "wasm"))] #[cfg(not(target_family = "wasm"))]
pub fn open_with_options(options: StoreOpenOptions) -> Result<Self, StorageError> { pub fn open_secondary(
Self::setup(Db::open_with_options(options, Self::column_families())?) primary_path: &Path,
secondary_path: &Path,
) -> Result<Self, StorageError> {
Self::setup(Db::open_secondary(
primary_path,
secondary_path,
Self::column_families(),
)?)
}
#[cfg(not(target_family = "wasm"))]
pub fn open_read_only(path: &Path) -> Result<Self, StorageError> {
Self::setup(Db::open_read_only(path, Self::column_families())?)
} }
fn column_families() -> Vec<ColumnFamilyDefinition> { fn column_families() -> Vec<ColumnFamilyDefinition> {

@ -1,8 +1,8 @@
#![allow(clippy::unreadable_literal)] #![allow(clippy::unreadable_literal)]
use crate::model::*; use crate::model::*;
use crate::storage::error::{CorruptionError, StorageError};
use crate::storage::small_string::SmallString; use crate::storage::small_string::SmallString;
use crate::store::{CorruptionError, StorageError};
use oxsdatatypes::*; use oxsdatatypes::*;
use siphasher::sip128::{Hasher128, SipHasher24}; use siphasher::sip128::{Hasher128, SipHasher24};
use std::fmt::Debug; use std::fmt::Debug;

@ -43,23 +43,8 @@ use std::error::Error;
use std::io::{BufRead, Write}; use std::io::{BufRead, Write};
#[cfg(not(target_family = "wasm"))] #[cfg(not(target_family = "wasm"))]
use std::path::Path; use std::path::Path;
use std::path::PathBuf;
use std::{fmt, str}; use std::{fmt, str};
pub struct SecondaryOptions {
pub path: PathBuf,
pub secondary_path: PathBuf,
}
pub struct ReadOnlyOptions {
pub path: PathBuf,
}
pub enum StoreOpenOptions {
OpenAsSecondary(SecondaryOptions),
OpenAsReadOnly(ReadOnlyOptions),
}
/// An on-disk [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset). /// An on-disk [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset).
/// Allows to query and update it using SPARQL. /// Allows to query and update it using SPARQL.
/// It is based on the [RocksDB](https://rocksdb.org/) key-value store. /// It is based on the [RocksDB](https://rocksdb.org/) key-value store.
@ -109,7 +94,11 @@ impl Store {
}) })
} }
/// Opens a [`Store`] and creates it if it does not exist yet. /// Opens a read-write [`Store`] and creates it if it does not exist yet.
///
/// Only one read-write [`Store`] can exist at the same time.
/// If you want to have extra [`Store`] instance opened on a same data
/// use [`Store::open_secondary`] or [`Store::open_read_only`].
#[cfg(not(target_family = "wasm"))] #[cfg(not(target_family = "wasm"))]
pub fn open(path: impl AsRef<Path>) -> Result<Self, StorageError> { pub fn open(path: impl AsRef<Path>) -> Result<Self, StorageError> {
Ok(Self { Ok(Self {
@ -117,11 +106,30 @@ impl Store {
}) })
} }
/// Opens a [`Store`] with options /// Opens a read-only clone of a running [`Store`].
///
/// It should only be used if a primary instance opened with [`Store::open`] is running at the same time.
/// `primary_path` must be the path of the primary instance and `secondary_path` an other directory for the secondary instance cache.
///
/// If you want to simple read-only [`Store`] use [`Store::open_read_only`].
#[cfg(not(target_family = "wasm"))]
pub fn open_secondary(
primary_path: impl AsRef<Path>,
secondary_path: impl AsRef<Path>,
) -> Result<Self, StorageError> {
Ok(Self {
storage: Storage::open_secondary(primary_path.as_ref(), secondary_path.as_ref())?,
})
}
/// Opens a read-only [`Store`] from disk.
///
/// It should not be already opened in write mode.
/// If you want to do so, use [`Store::open_secondary`].
#[cfg(not(target_family = "wasm"))] #[cfg(not(target_family = "wasm"))]
pub fn open_with_options(options: StoreOpenOptions) -> Result<Self, StorageError> { pub fn open_read_only(path: impl AsRef<Path>) -> Result<Self, StorageError> {
Ok(Self { Ok(Self {
storage: Storage::open_with_options(options)?, storage: Storage::open_read_only(path.as_ref())?,
}) })
} }

@ -3,8 +3,6 @@ use oxigraph::model::vocab::{rdf, xsd};
use oxigraph::model::*; use oxigraph::model::*;
use oxigraph::store::Store; use oxigraph::store::Store;
#[cfg(not(target_family = "wasm"))] #[cfg(not(target_family = "wasm"))]
use oxigraph::store::{ReadOnlyOptions, SecondaryOptions, StoreOpenOptions};
#[cfg(not(target_family = "wasm"))]
use rand::random; use rand::random;
#[cfg(not(target_family = "wasm"))] #[cfg(not(target_family = "wasm"))]
use std::env::temp_dir; use std::env::temp_dir;
@ -410,14 +408,8 @@ fn test_secondary_and_readonly() -> Result<(), Box<dyn Error>> {
// create additional stores // create additional stores
// read_only will not update after creation, so it's important we create it after insertion of // read_only will not update after creation, so it's important we create it after insertion of
// data. // data.
let read_only = Store::open_with_options(StoreOpenOptions::OpenAsReadOnly(ReadOnlyOptions { let read_only = Store::open_read_only(&store_dir)?;
path: store_dir.0.clone(), let secondary = Store::open_secondary(&store_dir, &secondary_dir)?;
}))?;
let secondary =
Store::open_with_options(StoreOpenOptions::OpenAsSecondary(SecondaryOptions {
path: store_dir.0.clone(),
secondary_path: secondary_dir.0.clone(),
}))?;
// see if we can read the data on all three stores: // see if we can read the data on all three stores:
for store in &[&primary, &secondary, &read_only] { for store in &[&primary, &secondary, &read_only] {

@ -8,9 +8,7 @@ use oxigraph::model::{
GraphName, GraphNameRef, IriParseError, NamedNode, NamedNodeRef, NamedOrBlankNode, GraphName, GraphNameRef, IriParseError, NamedNode, NamedNodeRef, NamedOrBlankNode,
}; };
use oxigraph::sparql::{Query, QueryResults, Update}; use oxigraph::sparql::{Query, QueryResults, Update};
use oxigraph::store::{ use oxigraph::store::{BulkLoader, LoaderError, Store};
BulkLoader, LoaderError, ReadOnlyOptions, SecondaryOptions, Store, StoreOpenOptions,
};
use oxiri::Iri; use oxiri::Iri;
use rand::random; use rand::random;
use rayon_core::ThreadPoolBuilder; use rayon_core::ThreadPoolBuilder;
@ -97,14 +95,9 @@ pub fn main() -> anyhow::Result<()> {
let matches = Args::parse(); let matches = Args::parse();
let store = if let Some(path) = &matches.location { let store = if let Some(path) = &matches.location {
if let Some(secondary_path) = &matches.secondary_location { if let Some(secondary_path) = &matches.secondary_location {
Store::open_with_options(StoreOpenOptions::OpenAsSecondary(SecondaryOptions { Store::open_secondary(path, secondary_path)
path: path.to_path_buf(),
secondary_path: secondary_path.to_path_buf(),
}))
} else if matches.readonly { } else if matches.readonly {
Store::open_with_options(StoreOpenOptions::OpenAsReadOnly(ReadOnlyOptions { Store::open_read_only(path)
path: path.to_path_buf(),
}))
} else { } else {
Store::open(path) Store::open(path)
} }

Loading…
Cancel
Save