• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

getdozer / dozer / 4392484403

pending completion
4392484403

push

github

GitHub
feat: Asynchoronous indexing (#1206)

270 of 270 new or added lines in 13 files covered. (100.0%)

28714 of 38777 relevant lines covered (74.05%)

89484.24 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

81.34
/dozer-cache/src/cache/lmdb/utils.rs
1
use std::{
2
    fs,
3
    ops::Deref,
4
    path::{Path, PathBuf},
5
};
6

7
use crate::errors::CacheError;
8
use dozer_storage::{
9
    lmdb::EnvironmentFlags,
10
    lmdb_storage::{LmdbEnvironmentManager, LmdbEnvironmentOptions},
11
};
12
use tempdir::TempDir;
13

14
use super::cache::{CacheCommonOptions, CacheWriteOptions};
15

16
#[allow(clippy::type_complexity)]
×
17
pub fn init_env(
×
18
    common_options: &CacheCommonOptions,
19
    write_options: Option<CacheWriteOptions>,
×
20
) -> Result<(LmdbEnvironmentManager, (PathBuf, String), Option<TempDir>), CacheError> {
×
21
    if let Some(write_options) = write_options {
2,588✔
22
        create_env(common_options, write_options)
878✔
23
    } else {
24
        let (env, (base_path, name), temp_dir) = open_env(common_options)?;
1,710✔
25
        Ok((env, (base_path.to_path_buf(), name.to_string()), temp_dir))
1,710✔
26
    }
×
27
}
2,588✔
28

×
29
#[allow(clippy::type_complexity)]
30
fn create_env(
879✔
31
    common_options: &CacheCommonOptions,
879✔
32
    write_options: CacheWriteOptions,
879✔
33
) -> Result<(LmdbEnvironmentManager, (PathBuf, String), Option<TempDir>), CacheError> {
879✔
34
    let (base_path, name, temp_dir) = match &common_options.path {
879✔
35
        None => {
×
36
            let base_path =
17✔
37
                TempDir::new("dozer").map_err(|e| CacheError::Io("tempdir".into(), e))?;
17✔
38
            (
17✔
39
                base_path.path().to_path_buf(),
17✔
40
                "dozer-cache",
17✔
41
                Some(base_path),
17✔
42
            )
17✔
43
        }
44
        Some((base_path, name)) => {
862✔
45
            fs::create_dir_all(base_path).map_err(|e| CacheError::Io(base_path.clone(), e))?;
862✔
46
            (base_path.clone(), name.deref(), None)
862✔
47
        }
×
48
    };
×
49

×
50
    let options = LmdbEnvironmentOptions::new(
879✔
51
        common_options.max_db_size,
879✔
52
        common_options.max_readers,
879✔
53
        write_options.max_size,
879✔
54
        EnvironmentFlags::empty(),
879✔
55
    );
879✔
56

879✔
57
    Ok((
879✔
58
        LmdbEnvironmentManager::create(&base_path, name, options)?,
879✔
59
        (base_path, name.to_string()),
879✔
60
        temp_dir,
879✔
61
    ))
×
62
}
879✔
63

×
64
#[allow(clippy::type_complexity)]
×
65
fn open_env(
1,710✔
66
    options: &CacheCommonOptions,
1,710✔
67
) -> Result<(LmdbEnvironmentManager, (&Path, &str), Option<TempDir>), CacheError> {
1,710✔
68
    let (base_path, name) = options
1,710✔
69
        .path
1,710✔
70
        .as_ref()
1,710✔
71
        .ok_or(CacheError::PathNotInitialized)?;
1,710✔
72

×
73
    let env_options = LmdbEnvironmentOptions {
1,710✔
74
        max_dbs: options.max_db_size,
1,710✔
75
        max_readers: options.max_readers,
1,710✔
76
        flags: EnvironmentFlags::READ_ONLY,
1,710✔
77
        ..Default::default()
1,710✔
78
    };
1,710✔
79

1,710✔
80
    Ok((
1,710✔
81
        LmdbEnvironmentManager::create(base_path, name, env_options)?,
1,710✔
82
        (base_path, name),
1,710✔
83
        None,
1,710✔
84
    ))
85
}
1,710✔
86

×
87
#[cfg(test)]
×
88
mod tests {
×
89
    use dozer_storage::{
×
90
        lmdb::{Cursor, DatabaseFlags, RoCursor, Transaction, WriteFlags},
×
91
        lmdb_storage::CreateDatabase,
×
92
    };
×
93
    use dozer_types::types::Field;
94

×
95
    use super::*;
×
96

×
97
    fn cursor_dump(mut cursor: RoCursor) -> Vec<(&[u8], &[u8])> {
1✔
98
        cursor
1✔
99
            .iter_dup()
1✔
100
            .flatten()
1✔
101
            .collect::<dozer_storage::lmdb::Result<Vec<_>>>()
1✔
102
            .unwrap()
1✔
103
    }
1✔
104

×
105
    #[test]
1✔
106
    fn duplicate_test_nested() {
1✔
107
        let mut env = create_env(&Default::default(), Default::default())
1✔
108
            .unwrap()
1✔
109
            .0;
1✔
110

1✔
111
        let db = env
1✔
112
            .create_database(
1✔
113
                Some("test"),
1✔
114
                Some(DatabaseFlags::DUP_SORT | DatabaseFlags::INTEGER_KEY),
1✔
115
            )
1✔
116
            .unwrap();
1✔
117

1✔
118
        let txn = env.create_txn().unwrap();
1✔
119
        let mut master_txn = txn.write();
1✔
120
        let txn = master_txn.txn_mut();
1✔
121

1✔
122
        let mut c_txn = txn.begin_nested_txn().unwrap();
1✔
123

1✔
124
        let items: Vec<(i64, &[u8])> = vec![
1✔
125
            (1, b"a"),
1✔
126
            (2, b"a"),
1✔
127
            (3, b"a"),
1✔
128
            (1, b"b"),
1✔
129
            (2, b"b"),
1✔
130
            (3, b"b"),
1✔
131
            (1, b"c"),
1✔
132
            (2, b"c"),
1✔
133
            (3, b"c"),
1✔
134
            (1, b"e"),
1✔
135
            (2, b"e"),
1✔
136
            (3, b"e"),
1✔
137
        ];
1✔
138
        for (key, data) in &items {
13✔
139
            let key = [
12✔
140
                "idx".as_bytes().to_vec(),
12✔
141
                Field::Int(*key).encode(),
12✔
142
                key.to_be_bytes().to_vec(),
12✔
143
            ]
12✔
144
            .join("#".as_bytes());
12✔
145
            c_txn.put(db, &key, data, WriteFlags::empty()).unwrap();
12✔
146
        }
12✔
147
        c_txn.commit().unwrap();
1✔
148
        master_txn.commit_and_renew().unwrap();
1✔
149

1✔
150
        let rtxn = master_txn.txn();
1✔
151

1✔
152
        let cursor = rtxn.open_ro_cursor(db).unwrap();
1✔
153
        let vals = cursor_dump(cursor);
1✔
154
        assert_eq!(vals.len(), items.len(), "must have duplicate records");
1✔
155
    }
1✔
156
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc