From ee68c8f04d018f7f945ec58c3edd775b77d5019e Mon Sep 17 00:00:00 2001 From: Tpt Date: Thu, 23 Feb 2023 14:50:30 +0100 Subject: [PATCH] Replaces Store::open_with_options with explicit variants Trades enums and structs for methods --- lib/src/storage/backend/rocksdb.rs | 38 +++++++++++++----------- lib/src/storage/binary_encoder.rs | 3 +- lib/src/storage/mod.rs | 17 +++++++++-- lib/src/storage/numeric_encoder.rs | 2 +- lib/src/store.rs | 46 ++++++++++++++++++------------ lib/tests/store.rs | 12 ++------ server/src/main.rs | 13 ++------- 7 files changed, 69 insertions(+), 62 deletions(-) diff --git a/lib/src/storage/backend/rocksdb.rs b/lib/src/storage/backend/rocksdb.rs index d007ad08..3e3a49bb 100644 --- a/lib/src/storage/backend/rocksdb.rs +++ b/lib/src/storage/backend/rocksdb.rs @@ -2,8 +2,7 @@ #![allow(unsafe_code, trivial_casts)] -use crate::storage::error::StorageError; -use crate::store::{CorruptionError, StoreOpenOptions}; +use crate::storage::error::{CorruptionError, StorageError}; use lazy_static::lazy_static; use libc::{self, c_char, c_void, free}; use oxrocksdb_sys::*; @@ -225,28 +224,33 @@ impl Db { column_families: Vec, ) -> Result { Ok(Self(Arc::new(Self::do_open( - path.to_owned(), + path.to_path_buf(), column_families, &OpeningMode::Primary, )?))) } - pub fn open_with_options( - options: StoreOpenOptions, + pub fn open_secondary( + primary_path: &Path, + secondary_path: &Path, column_families: Vec, ) -> Result { - match options { - StoreOpenOptions::OpenAsReadOnly(options) => Ok(Self(Arc::new(Self::do_open( - options.path, - column_families, - &OpeningMode::ReadOnly, - )?))), - StoreOpenOptions::OpenAsSecondary(options) => Ok(Self(Arc::new(Self::do_open( - options.path, - column_families, - &OpeningMode::Secondary(options.secondary_path), - )?))), - } + Ok(Self(Arc::new(Self::do_open( + primary_path.to_path_buf(), + column_families, + &OpeningMode::Secondary(secondary_path.to_path_buf()), + )?))) + } + + pub fn open_read_only( + path: &Path, + column_families: Vec, + ) -> Result { + Ok(Self(Arc::new(Self::do_open( + path.to_path_buf(), + column_families, + &OpeningMode::ReadOnly, + )?))) } fn do_open( diff --git a/lib/src/storage/binary_encoder.rs b/lib/src/storage/binary_encoder.rs index c5a4177b..4e888c2f 100644 --- a/lib/src/storage/binary_encoder.rs +++ b/lib/src/storage/binary_encoder.rs @@ -1,7 +1,6 @@ +use crate::storage::error::{CorruptionError, StorageError}; use crate::storage::numeric_encoder::{EncodedQuad, EncodedTerm, EncodedTriple, StrHash}; use crate::storage::small_string::SmallString; -use crate::storage::StorageError; -use crate::store::CorruptionError; use oxsdatatypes::*; use std::io::{Cursor, Read}; use std::mem::size_of; diff --git a/lib/src/storage/mod.rs b/lib/src/storage/mod.rs index 0c86d3e5..02279b6b 100644 --- a/lib/src/storage/mod.rs +++ b/lib/src/storage/mod.rs @@ -14,7 +14,6 @@ pub use crate::storage::error::{CorruptionError, LoaderError, SerializerError, S #[cfg(not(target_family = "wasm"))] use crate::storage::numeric_encoder::Decoder; use crate::storage::numeric_encoder::{insert_term, EncodedQuad, EncodedTerm, StrHash, StrLookup}; -pub use crate::store::StoreOpenOptions; use backend::{ColumnFamily, ColumnFamilyDefinition, Db, Iter}; #[cfg(not(target_family = "wasm"))] use std::cmp::{max, min}; @@ -92,8 +91,20 @@ impl Storage { } #[cfg(not(target_family = "wasm"))] - pub fn open_with_options(options: StoreOpenOptions) -> Result { - Self::setup(Db::open_with_options(options, Self::column_families())?) + pub fn open_secondary( + primary_path: &Path, + secondary_path: &Path, + ) -> Result { + 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::setup(Db::open_read_only(path, Self::column_families())?) } fn column_families() -> Vec { diff --git a/lib/src/storage/numeric_encoder.rs b/lib/src/storage/numeric_encoder.rs index f75f4103..73b00fe3 100644 --- a/lib/src/storage/numeric_encoder.rs +++ b/lib/src/storage/numeric_encoder.rs @@ -1,8 +1,8 @@ #![allow(clippy::unreadable_literal)] use crate::model::*; +use crate::storage::error::{CorruptionError, StorageError}; use crate::storage::small_string::SmallString; -use crate::store::{CorruptionError, StorageError}; use oxsdatatypes::*; use siphasher::sip128::{Hasher128, SipHasher24}; use std::fmt::Debug; diff --git a/lib/src/store.rs b/lib/src/store.rs index c1261e24..726e5204 100644 --- a/lib/src/store.rs +++ b/lib/src/store.rs @@ -43,23 +43,8 @@ use std::error::Error; use std::io::{BufRead, Write}; #[cfg(not(target_family = "wasm"))] use std::path::Path; -use std::path::PathBuf; 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). /// Allows to query and update it using SPARQL. /// 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"))] pub fn open(path: impl AsRef) -> Result { 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, + secondary_path: impl AsRef, + ) -> Result { + 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"))] - pub fn open_with_options(options: StoreOpenOptions) -> Result { + pub fn open_read_only(path: impl AsRef) -> Result { Ok(Self { - storage: Storage::open_with_options(options)?, + storage: Storage::open_read_only(path.as_ref())?, }) } diff --git a/lib/tests/store.rs b/lib/tests/store.rs index 7f9fbf46..c2c30066 100644 --- a/lib/tests/store.rs +++ b/lib/tests/store.rs @@ -3,8 +3,6 @@ use oxigraph::model::vocab::{rdf, xsd}; use oxigraph::model::*; use oxigraph::store::Store; #[cfg(not(target_family = "wasm"))] -use oxigraph::store::{ReadOnlyOptions, SecondaryOptions, StoreOpenOptions}; -#[cfg(not(target_family = "wasm"))] use rand::random; #[cfg(not(target_family = "wasm"))] use std::env::temp_dir; @@ -410,14 +408,8 @@ fn test_secondary_and_readonly() -> Result<(), Box> { // create additional stores // read_only will not update after creation, so it's important we create it after insertion of // data. - let read_only = Store::open_with_options(StoreOpenOptions::OpenAsReadOnly(ReadOnlyOptions { - path: store_dir.0.clone(), - }))?; - let secondary = - Store::open_with_options(StoreOpenOptions::OpenAsSecondary(SecondaryOptions { - path: store_dir.0.clone(), - secondary_path: secondary_dir.0.clone(), - }))?; + let read_only = Store::open_read_only(&store_dir)?; + let secondary = Store::open_secondary(&store_dir, &secondary_dir)?; // see if we can read the data on all three stores: for store in &[&primary, &secondary, &read_only] { diff --git a/server/src/main.rs b/server/src/main.rs index 80d2585b..9773aa9d 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -8,9 +8,7 @@ use oxigraph::model::{ GraphName, GraphNameRef, IriParseError, NamedNode, NamedNodeRef, NamedOrBlankNode, }; use oxigraph::sparql::{Query, QueryResults, Update}; -use oxigraph::store::{ - BulkLoader, LoaderError, ReadOnlyOptions, SecondaryOptions, Store, StoreOpenOptions, -}; +use oxigraph::store::{BulkLoader, LoaderError, Store}; use oxiri::Iri; use rand::random; use rayon_core::ThreadPoolBuilder; @@ -97,14 +95,9 @@ pub fn main() -> anyhow::Result<()> { let matches = Args::parse(); let store = if let Some(path) = &matches.location { if let Some(secondary_path) = &matches.secondary_location { - Store::open_with_options(StoreOpenOptions::OpenAsSecondary(SecondaryOptions { - path: path.to_path_buf(), - secondary_path: secondary_path.to_path_buf(), - })) + Store::open_secondary(path, secondary_path) } else if matches.readonly { - Store::open_with_options(StoreOpenOptions::OpenAsReadOnly(ReadOnlyOptions { - path: path.to_path_buf(), - })) + Store::open_read_only(path) } else { Store::open(path) }