Skip to content

Commit

Permalink
Merge pull request #302 from meilisearch/fix-notls-documentation
Browse files Browse the repository at this point in the history
Fix the `MDB_NOTLS` documentation
  • Loading branch information
Kerollmops authored Dec 27, 2024
2 parents f76bfc6 + 6f5a480 commit 68a02a2
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 64 deletions.
5 changes: 3 additions & 2 deletions heed/src/cookbook.rs
Original file line number Diff line number Diff line change
Expand Up @@ -341,8 +341,9 @@
//!
//! # Advanced Multithreaded Access of Entries
//!
//! LMDB disallow sharing cursors amongs threads. It is only possible to send
//! them between threads when the heed `read-txn-no-tls` feature is enabled.
//! LMDB disallows sharing cursors among threads. It is only possible to send
//! them between threads when the environment has been opened with
//! [`EnvOpenOptions::read_txn_without_tls`] method.
//!
//! Please note that this should not be utilized with an encrypted heed3 database. These
//! types of databases employ an internal cycling buffer for decrypting entries, which
Expand Down
35 changes: 21 additions & 14 deletions heed/src/databases/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -378,8 +378,9 @@ impl<KC, DC, C> Database<KC, DC, C> {

/// Returns an iterator over all of the values of a single key.
///
/// You can make this iterator `Send`able between threads by
/// using the `read-txn-no-tls` crate feature.
/// You can make this iterator `Send`able between threads by opening
/// the environment with the [`EnvOpenOptions::read_txn_without_tls`]
/// method.
///
/// ```
/// # use std::fs;
Expand Down Expand Up @@ -986,8 +987,9 @@ impl<KC, DC, C> Database<KC, DC, C> {

/// Return an ordered iterator of all key-value pairs in this database.
///
/// You can make this iterator `Send`able between threads by
/// using the `read-txn-no-tls` crate feature.
/// You can make this iterator `Send`able between threads by opening
/// the environment with the [`EnvOpenOptions::read_txn_without_tls`]
/// method.
///
/// ```
/// # use std::fs;
Expand Down Expand Up @@ -1087,8 +1089,9 @@ impl<KC, DC, C> Database<KC, DC, C> {

/// Return a reverse ordered iterator of all key-value pairs in this database.
///
/// You can make this iterator `Send`able between threads by
/// using the `read-txn-no-tls` crate feature.
/// You can make this iterator `Send`able between threads by opening
/// the environment with the [`EnvOpenOptions::read_txn_without_tls`]
/// method.
///
/// ```
/// # use std::fs;
Expand Down Expand Up @@ -1192,8 +1195,9 @@ impl<KC, DC, C> Database<KC, DC, C> {
///
/// Comparisons are made by using the comparator `C`.
///
/// You can make this iterator `Send`able between threads by
/// using the `read-txn-no-tls` crate feature.
/// You can make this iterator `Send`able between threads by opening
/// the environment with the [`EnvOpenOptions::read_txn_without_tls`]
/// method.
///
/// ```
/// # use std::fs;
Expand Down Expand Up @@ -1364,8 +1368,9 @@ impl<KC, DC, C> Database<KC, DC, C> {
///
/// Comparisons are made by using the comparator `C`.
///
/// You can make this iterator `Send`able between threads by
/// using the `read-txn-no-tls` crate feature.
/// You can make this iterator `Send`able between threads by opening
/// the environment with the [`EnvOpenOptions::read_txn_without_tls`]
/// method.
///
/// ```
/// # use std::fs;
Expand Down Expand Up @@ -1537,8 +1542,9 @@ impl<KC, DC, C> Database<KC, DC, C> {
///
/// Comparisons are made by using the bytes representation of the key.
///
/// You can make this iterator `Send`able between threads by
/// using the `read-txn-no-tls` crate feature.
/// You can make this iterator `Send`able between threads by opening
/// the environment with the [`EnvOpenOptions::read_txn_without_tls`]
/// method.
///
/// ```
/// # use std::fs;
Expand Down Expand Up @@ -1669,8 +1675,9 @@ impl<KC, DC, C> Database<KC, DC, C> {
///
/// Comparisons are made by using the bytes representation of the key.
///
/// You can make this iterator `Send`able between threads by
/// using the `read-txn-no-tls` crate feature.
/// You can make this iterator `Send`able between threads by opening
/// the environment with the [`EnvOpenOptions::read_txn_without_tls`]
/// method.
///
/// ```
/// # use std::fs;
Expand Down
35 changes: 21 additions & 14 deletions heed/src/databases/encrypted_database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,8 +319,9 @@ impl<KC, DC, C> EncryptedDatabase<KC, DC, C> {

/// Returns an iterator over all of the values of a single key.
///
/// You can make this iterator `Send`able between threads by
/// using the `read-txn-no-tls` crate feature.
/// You can make this iterator `Send`able between threads by opening
/// the environment with the [`EnvOpenOptions::read_txn_without_tls`]
/// method.
///
/// ```
/// # use std::fs;
Expand Down Expand Up @@ -822,8 +823,9 @@ impl<KC, DC, C> EncryptedDatabase<KC, DC, C> {

/// Return a lexicographically ordered iterator of all key-value pairs in this database.
///
/// You can make this iterator `Send`able between threads by
/// using the `read-txn-no-tls` crate feature.
/// You can make this iterator `Send`able between threads by opening
/// the environment with the [`EnvOpenOptions::read_txn_without_tls`]
/// method.
///
/// ```
/// # use std::fs;
Expand Down Expand Up @@ -920,8 +922,9 @@ impl<KC, DC, C> EncryptedDatabase<KC, DC, C> {

/// Return a reversed lexicographically ordered iterator of all key-value pairs in this database.
///
/// You can make this iterator `Send`able between threads by
/// using the `read-txn-no-tls` crate feature.
/// You can make this iterator `Send`able between threads by opening
/// the environment with the [`EnvOpenOptions::read_txn_without_tls`]
/// method.
///
/// ```
/// # use std::fs;
Expand Down Expand Up @@ -1021,8 +1024,9 @@ impl<KC, DC, C> EncryptedDatabase<KC, DC, C> {
///
/// Comparisons are made by using the comparator `C`.
///
/// You can make this iterator `Send`able between threads by
/// using the `read-txn-no-tls` crate feature.
/// You can make this iterator `Send`able between threads by opening
/// the environment with the [`EnvOpenOptions::read_txn_without_tls`]
/// method.
///
/// ```
/// # use std::fs;
Expand Down Expand Up @@ -1143,8 +1147,9 @@ impl<KC, DC, C> EncryptedDatabase<KC, DC, C> {
///
/// Comparisons are made by using the comparator `C`.
///
/// You can make this iterator `Send`able between threads by
/// using the `read-txn-no-tls` crate feature.
/// You can make this iterator `Send`able between threads by opening
/// the environment with the [`EnvOpenOptions::read_txn_without_tls`]
/// method.
///
/// ```
/// # use std::fs;
Expand Down Expand Up @@ -1265,8 +1270,9 @@ impl<KC, DC, C> EncryptedDatabase<KC, DC, C> {
///
/// Comparisons are made by using the bytes representation of the key.
///
/// You can make this iterator `Send`able between threads by
/// using the `read-txn-no-tls` crate feature.
/// You can make this iterator `Send`able between threads by opening
/// the environment with the [`EnvOpenOptions::read_txn_without_tls`]
/// method.
///
/// ```
/// # use std::fs;
Expand Down Expand Up @@ -1389,8 +1395,9 @@ impl<KC, DC, C> EncryptedDatabase<KC, DC, C> {
///
/// Comparisons are made by using the bytes representation of the key.
///
/// You can make this iterator `Send`able between threads by
/// using the `read-txn-no-tls` crate feature.
/// You can make this iterator `Send`able between threads by opening
/// the environment with the [`EnvOpenOptions::read_txn_without_tls`]
/// method.
///
/// ```
/// # use std::fs;
Expand Down
11 changes: 7 additions & 4 deletions heed/src/envs/encrypted_env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,10 @@ impl<T> EncryptedEnv<T> {

/// Create a transaction with read-only access for use with the environment.
///
/// You can make this transaction `Send`able between threads by
/// using the `read-txn-no-tls` crate feature.
/// You can make this transaction `Send`able between threads by opening
/// the environment with the [`EnvOpenOptions::read_txn_without_tls`]
/// method.
///
/// See [`Self::static_read_txn`] if you want the txn to own the environment.
///
/// ## LMDB Limitations
Expand Down Expand Up @@ -221,8 +223,9 @@ impl<T> EncryptedEnv<T> {
/// Contrary to [`Self::read_txn`], this version **owns** the environment, which
/// means you won't be able to close the environment while this transaction is alive.
///
/// You can make this transaction `Send`able between threads by
/// using the `read-txn-no-tls` crate feature.
/// You can make this transaction `Send`able between threads by opening
/// the environment with the [`EnvOpenOptions::read_txn_without_tls`]
/// method.
///
/// ## LMDB Limitations
///
Expand Down
11 changes: 7 additions & 4 deletions heed/src/envs/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -341,8 +341,10 @@ impl<T> Env<T> {

/// Create a transaction with read-only access for use with the environment.
///
/// You can make this transaction `Send`able between threads by
/// using the `read-txn-no-tls` crate feature.
/// You can make this transaction `Send`able between threads by opening
/// the environment with the [`EnvOpenOptions::read_txn_without_tls`]
/// method.
///
/// See [`Self::static_read_txn`] if you want the txn to own the environment.
///
/// ## LMDB Limitations
Expand Down Expand Up @@ -371,8 +373,9 @@ impl<T> Env<T> {
/// Contrary to [`Self::read_txn`], this version **owns** the environment, which
/// means you won't be able to close the environment while this transaction is alive.
///
/// You can make this transaction `Send`able between threads by
/// using the `read-txn-no-tls` crate feature.
/// You can make this transaction `Send`able between threads by opening
/// the environment with the [`EnvOpenOptions::read_txn_without_tls`]
/// method.
///
/// ## LMDB Limitations
///
Expand Down
17 changes: 6 additions & 11 deletions heed/src/envs/env_open_options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ impl<T: TlsUsage> EnvOpenOptions<T> {
///
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// let mut env_builder = EnvOpenOptions::new();
/// unsafe { env_builder.flags(EnvFlags::NO_TLS | EnvFlags::NO_META_SYNC); }
/// unsafe { env_builder.flags(EnvFlags::NO_META_SYNC); }
/// let dir = tempfile::tempdir().unwrap();
/// let env = unsafe { env_builder.open(dir.path())? };
///
Expand Down Expand Up @@ -457,16 +457,11 @@ impl<T: TlsUsage> EnvOpenOptions<T> {
mdb_result(ffi::mdb_env_set_maxdbs(env, dbs))?;
}

// When the `read-txn-no-tls` feature is enabled, we must force LMDB
// to avoid using the thread local storage, this way we allow users
// to use references of RoTxn between threads safely.
#[allow(deprecated)] // NO_TLS is inside of the crate
let flags = if T::ENABLED {
// TODO make this a ZST flag on the Env and on RoTxn (make them Send when we can)
self.flags
} else {
self.flags | EnvFlags::NO_TLS
};
// When the `<T as TlsUsage>::ENABLED` is true, we must tell
// LMDB to avoid using the thread local storage, this way we
// allow users to move RoTxn between threads safely.
#[allow(deprecated)] // ok because NO_TLS is inside of the crate
let flags = if T::ENABLED { self.flags } else { self.flags | EnvFlags::NO_TLS };

let result = ffi::mdb_env_open(env, path_str.as_ptr(), flags.bits(), 0o600);
match mdb_result(result) {
Expand Down
2 changes: 2 additions & 0 deletions heed/src/mdb/lmdb_flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ bitflags! {
/// Use asynchronous msync when MDB_WRITEMAP is used.
const MAP_ASYNC = ffi::MDB_MAPASYNC;
/// Tie reader locktable slots to MDB_txn objects instead of to threads.
// Note to self: When removing this flag from here, we must introduce an
// internal-only AllEnvFlags akin to the AllDatabaseFlags bitflags.
#[deprecated(since="0.22.0", note="please use `EnvOpenOptions::read_txn_with_tls` or `EnvOpenOptions::read_txn_without_tls` instead")]
const NO_TLS = ffi::MDB_NOTLS;
/// Don't do any locking, caller must manage their own locks.
Expand Down
15 changes: 0 additions & 15 deletions heed3/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,21 +45,6 @@ url = "2.5.4"
default = ["serde", "serde-bincode", "serde-json"]
serde = ["bitflags/serde", "dep:serde"]

# The #MDB_NOTLS flag is automatically set on Env opening,
# RoTxn and RoCursors implements the Send trait. This allows the
# user to move RoTxns and RoCursors between threads as read transactions
# will no more use thread local storage and will tie reader locktable
# slots to #MDB_txn objects instead of to threads.
#
# According to the LMDB documentation, when this feature is not enabled:
# A thread can only use one transaction at a time, plus any child
# transactions. Each transaction belongs to one thread. [...]
# The #MDB_NOTLS flag changes this for read-only transactions.
#
# And a #MDB_BAD_RSLOT error will be thrown when multiple read
# transactions exists on the same thread
read-txn-no-tls = []

# Enable the serde en/decoders for bincode, serde_json, or rmp_serde
serde-bincode = ["heed-types/serde-bincode"]
serde-json = ["heed-types/serde-json"]
Expand Down

0 comments on commit 68a02a2

Please sign in to comment.