Agent

Struct Agent 

Source
pub struct Agent { /* private fields */ }
Expand description

An agent for search operations

Implementations§

Source§

impl Agent

Source

pub fn new() -> Result<Self, MarisaError>

Create a new agent

Examples found in repository?
examples/benchmark.rs (line 44)
39fn benchmark_predictive_search(trie: &Trie, prefixes: &[String], iterations: usize) -> f64 {
40    let start = Instant::now();
41
42    for _ in 0..iterations {
43        for prefix in prefixes {
44            let mut agent = Agent::new().unwrap();
45            let _ = trie.predictive_search(prefix, &mut agent);
46        }
47    }
48
49    let duration = start.elapsed();
50    duration.as_secs_f64()
51}
52
53fn main() -> Result<(), Box<dyn std::error::Error>> {
54    println!("Marisa FFI Benchmark");
55    println!("===================");
56    println!();
57
58    // Generate test data
59    let word_count = 10000;
60    let words = generate_words(word_count);
61    let prefixes = vec![
62        "app".to_string(),
63        "ban".to_string(),
64        "che".to_string(),
65        "dog".to_string(),
66        "ele".to_string(),
67        "fis".to_string(),
68        "gra".to_string(),
69        "hou".to_string(),
70    ];
71
72    println!("Generated {} test words", word_count);
73    println!("Test prefixes: {:?}", prefixes);
74    println!();
75
76    // Build the trie
77    println!("Building trie...");
78    let build_start = Instant::now();
79
80    let mut keyset = Keyset::new()?;
81    for word in &words {
82        keyset.push(word)?;
83    }
84
85    let trie = Trie::build(&keyset)?;
86    let build_time = build_start.elapsed();
87
88    println!("Trie built in {:.3} seconds", build_time.as_secs_f64());
89    println!();
90
91    // Benchmark exact lookup
92    println!("=== Exact Lookup Benchmark ===");
93    let lookup_iterations = 100;
94    let lookup_time = benchmark_lookup(&trie, &words, lookup_iterations);
95    let total_lookups = words.len() * lookup_iterations;
96    let lookups_per_sec = total_lookups as f64 / lookup_time;
97
98    println!(
99        "Performed {} lookups in {:.3} seconds",
100        total_lookups, lookup_time
101    );
102    println!("Lookups per second: {:.0}", lookups_per_sec);
103    println!(
104        "Average lookup time: {:.3} microseconds",
105        (lookup_time * 1_000_000.0) / total_lookups as f64
106    );
107    println!();
108
109    // Benchmark predictive search
110    println!("=== Predictive Search Benchmark ===");
111    let search_iterations = 50;
112    let search_time = benchmark_predictive_search(&trie, &prefixes, search_iterations);
113    let total_searches = prefixes.len() * search_iterations;
114    let searches_per_sec = total_searches as f64 / search_time;
115
116    println!(
117        "Performed {} predictive searches in {:.3} seconds",
118        total_searches, search_time
119    );
120    println!("Searches per second: {:.0}", searches_per_sec);
121    println!(
122        "Average search time: {:.3} microseconds",
123        (search_time * 1_000_000.0) / total_searches as f64
124    );
125    println!();
126
127    // Memory usage estimation
128    println!("=== Memory Usage ===");
129    println!("Number of keys: {}", words.len());
130    println!(
131        "Average key length: {:.1} characters",
132        words.iter().map(|w| w.len()).sum::<usize>() as f64 / words.len() as f64
133    );
134
135    // Save trie to file to measure size
136    let filename = "benchmark_trie.marisa";
137    trie.save(filename)?;
138
139    if let Ok(metadata) = std::fs::metadata(filename) {
140        let file_size = metadata.len();
141        let bytes_per_key = file_size as f64 / words.len() as f64;
142
143        println!(
144            "Trie file size: {} bytes ({:.2} KB)",
145            file_size,
146            file_size as f64 / 1024.0
147        );
148        println!("Bytes per key: {:.2}", bytes_per_key);
149        println!("Compression ratio: {:.1}%", (bytes_per_key / 10.0) * 100.0); // Assuming ~10 bytes per key on average
150    }
151
152    // Clean up
153    std::fs::remove_file(filename)?;
154    println!();
155
156    // Sample some results
157    println!("=== Sample Results ===");
158    let sample_words = vec!["apples", "bananas", "cherries", "dogs", "elephants"];
159
160    for word in sample_words {
161        match trie.lookup(word) {
162            Some(id) => println!("'{}' -> ID: {}", word, id),
163            None => println!("'{}' -> Not found", word),
164        }
165    }
166
167    println!();
168    println!("Predictive search for 'app':");
169    let mut agent = Agent::new()?;
170    if trie.predictive_search("app", &mut agent)? {
171        // Note: agent.next() is not implemented yet
172        // For now, we'll show only the first result
173        let key = agent.key()?;
174        println!("  - {}", key);
175        println!("  Total: 1 key (iteration not implemented)");
176    }
177
178    Ok(())
179}
More examples
Hide additional examples
examples/basic_usage.rs (line 67)
12fn main() -> Result<(), Box<dyn std::error::Error>> {
13    println!("Marisa FFI Example");
14    println!("Version: {}", version());
15    println!();
16
17    // Create a keyset and add some sample keys
18    let mut keyset = Keyset::new()?;
19
20    let sample_keys = vec![
21        "apple",
22        "application",
23        "apply",
24        "app",
25        "banana",
26        "band",
27        "bandit",
28        "cherry",
29        "cheese",
30        "chef",
31        "dog",
32        "doggy",
33        "doggie",
34        "elephant",
35        "eleven",
36        "elevator",
37    ];
38
39    println!("Adding {} keys to keyset...", sample_keys.len());
40    for key in &sample_keys {
41        keyset.push(key)?;
42    }
43
44    // Build the trie
45    println!("Building trie...");
46    let trie = Trie::build(&keyset)?;
47    println!("Trie built successfully!");
48    println!();
49
50    // Test exact lookup
51    println!("=== Exact Lookup Tests ===");
52    let test_keys = vec!["apple", "banana", "nonexistent", "app"];
53    for key in test_keys {
54        match trie.lookup(key) {
55            Some(id) => println!("Found '{}' with ID: {}", key, id),
56            None => println!("'{}' not found", key),
57        }
58    }
59    println!();
60
61    // Test predictive search
62    println!("=== Predictive Search Tests ===");
63    let prefixes = vec!["app", "ban", "che", "dog", "ele"];
64
65    for prefix in prefixes {
66        println!("Keys starting with '{}':", prefix);
67        let mut agent = Agent::new()?;
68
69        if trie.predictive_search(prefix, &mut agent)? {
70            // Note: agent.next() is not implemented yet
71            // For now, we'll show only the first result
72            let key = agent.key()?;
73            let id = agent.id();
74            println!("  - {} (ID: {})", key, id);
75            println!("  Total: 1 key (iteration not implemented)");
76        } else {
77            println!("  No keys found");
78        }
79        println!();
80    }
81
82    // Test reverse lookup
83    println!("=== Reverse Lookup Tests ===");
84    let test_ids = vec![0, 1, 2, 3, 4];
85    let mut agent = Agent::new()?;
86
87    for id in test_ids {
88        match trie.reverse_lookup(id, &mut agent) {
89            Ok(_) => {
90                let key = agent.key()?;
91                println!("ID {} -> '{}'", id, key);
92            }
93            Err(e) => println!("ID {} -> Error: {}", id, e),
94        }
95    }
96    println!();
97
98    // Test common prefix search
99    println!("=== Common Prefix Search Tests ===");
100    let test_strings = vec!["application", "bandit", "chef", "doggie"];
101
102    for test_str in test_strings {
103        println!("Common prefixes of '{}':", test_str);
104        let mut agent = Agent::new()?;
105
106        if trie.common_prefix_search(test_str, &mut agent)? {
107            // Note: agent.next() is not implemented yet
108            // For now, we'll show only the first result
109            let key = agent.key()?;
110            let id = agent.id();
111            println!("  - {} (ID: {})", key, id);
112            println!("  Total: 1 prefix (iteration not implemented)");
113        } else {
114            println!("  No prefixes found");
115        }
116        println!();
117    }
118
119    // Save and load example
120    println!("=== Save/Load Test ===");
121    let filename = "test_trie.marisa";
122
123    // Save the trie
124    trie.save(filename)?;
125    println!("Trie saved to '{}'", filename);
126
127    // Load it back
128    let mut loaded_trie = Trie::new()?;
129    loaded_trie.load(filename)?;
130    println!("Trie loaded from '{}'", filename);
131
132    // Verify it works
133    match loaded_trie.lookup("apple") {
134        Some(id) => println!("Loaded trie lookup 'apple' -> ID: {}", id),
135        None => println!("Loaded trie lookup 'apple' -> Not found"),
136    }
137
138    // Clean up
139    std::fs::remove_file(filename)?;
140    println!("Test file '{}' removed", filename);
141
142    Ok(())
143}
Source

pub fn key(&self) -> Result<String, MarisaError>

Get the current key as a string

Examples found in repository?
examples/basic_usage.rs (line 72)
12fn main() -> Result<(), Box<dyn std::error::Error>> {
13    println!("Marisa FFI Example");
14    println!("Version: {}", version());
15    println!();
16
17    // Create a keyset and add some sample keys
18    let mut keyset = Keyset::new()?;
19
20    let sample_keys = vec![
21        "apple",
22        "application",
23        "apply",
24        "app",
25        "banana",
26        "band",
27        "bandit",
28        "cherry",
29        "cheese",
30        "chef",
31        "dog",
32        "doggy",
33        "doggie",
34        "elephant",
35        "eleven",
36        "elevator",
37    ];
38
39    println!("Adding {} keys to keyset...", sample_keys.len());
40    for key in &sample_keys {
41        keyset.push(key)?;
42    }
43
44    // Build the trie
45    println!("Building trie...");
46    let trie = Trie::build(&keyset)?;
47    println!("Trie built successfully!");
48    println!();
49
50    // Test exact lookup
51    println!("=== Exact Lookup Tests ===");
52    let test_keys = vec!["apple", "banana", "nonexistent", "app"];
53    for key in test_keys {
54        match trie.lookup(key) {
55            Some(id) => println!("Found '{}' with ID: {}", key, id),
56            None => println!("'{}' not found", key),
57        }
58    }
59    println!();
60
61    // Test predictive search
62    println!("=== Predictive Search Tests ===");
63    let prefixes = vec!["app", "ban", "che", "dog", "ele"];
64
65    for prefix in prefixes {
66        println!("Keys starting with '{}':", prefix);
67        let mut agent = Agent::new()?;
68
69        if trie.predictive_search(prefix, &mut agent)? {
70            // Note: agent.next() is not implemented yet
71            // For now, we'll show only the first result
72            let key = agent.key()?;
73            let id = agent.id();
74            println!("  - {} (ID: {})", key, id);
75            println!("  Total: 1 key (iteration not implemented)");
76        } else {
77            println!("  No keys found");
78        }
79        println!();
80    }
81
82    // Test reverse lookup
83    println!("=== Reverse Lookup Tests ===");
84    let test_ids = vec![0, 1, 2, 3, 4];
85    let mut agent = Agent::new()?;
86
87    for id in test_ids {
88        match trie.reverse_lookup(id, &mut agent) {
89            Ok(_) => {
90                let key = agent.key()?;
91                println!("ID {} -> '{}'", id, key);
92            }
93            Err(e) => println!("ID {} -> Error: {}", id, e),
94        }
95    }
96    println!();
97
98    // Test common prefix search
99    println!("=== Common Prefix Search Tests ===");
100    let test_strings = vec!["application", "bandit", "chef", "doggie"];
101
102    for test_str in test_strings {
103        println!("Common prefixes of '{}':", test_str);
104        let mut agent = Agent::new()?;
105
106        if trie.common_prefix_search(test_str, &mut agent)? {
107            // Note: agent.next() is not implemented yet
108            // For now, we'll show only the first result
109            let key = agent.key()?;
110            let id = agent.id();
111            println!("  - {} (ID: {})", key, id);
112            println!("  Total: 1 prefix (iteration not implemented)");
113        } else {
114            println!("  No prefixes found");
115        }
116        println!();
117    }
118
119    // Save and load example
120    println!("=== Save/Load Test ===");
121    let filename = "test_trie.marisa";
122
123    // Save the trie
124    trie.save(filename)?;
125    println!("Trie saved to '{}'", filename);
126
127    // Load it back
128    let mut loaded_trie = Trie::new()?;
129    loaded_trie.load(filename)?;
130    println!("Trie loaded from '{}'", filename);
131
132    // Verify it works
133    match loaded_trie.lookup("apple") {
134        Some(id) => println!("Loaded trie lookup 'apple' -> ID: {}", id),
135        None => println!("Loaded trie lookup 'apple' -> Not found"),
136    }
137
138    // Clean up
139    std::fs::remove_file(filename)?;
140    println!("Test file '{}' removed", filename);
141
142    Ok(())
143}
More examples
Hide additional examples
examples/benchmark.rs (line 173)
53fn main() -> Result<(), Box<dyn std::error::Error>> {
54    println!("Marisa FFI Benchmark");
55    println!("===================");
56    println!();
57
58    // Generate test data
59    let word_count = 10000;
60    let words = generate_words(word_count);
61    let prefixes = vec![
62        "app".to_string(),
63        "ban".to_string(),
64        "che".to_string(),
65        "dog".to_string(),
66        "ele".to_string(),
67        "fis".to_string(),
68        "gra".to_string(),
69        "hou".to_string(),
70    ];
71
72    println!("Generated {} test words", word_count);
73    println!("Test prefixes: {:?}", prefixes);
74    println!();
75
76    // Build the trie
77    println!("Building trie...");
78    let build_start = Instant::now();
79
80    let mut keyset = Keyset::new()?;
81    for word in &words {
82        keyset.push(word)?;
83    }
84
85    let trie = Trie::build(&keyset)?;
86    let build_time = build_start.elapsed();
87
88    println!("Trie built in {:.3} seconds", build_time.as_secs_f64());
89    println!();
90
91    // Benchmark exact lookup
92    println!("=== Exact Lookup Benchmark ===");
93    let lookup_iterations = 100;
94    let lookup_time = benchmark_lookup(&trie, &words, lookup_iterations);
95    let total_lookups = words.len() * lookup_iterations;
96    let lookups_per_sec = total_lookups as f64 / lookup_time;
97
98    println!(
99        "Performed {} lookups in {:.3} seconds",
100        total_lookups, lookup_time
101    );
102    println!("Lookups per second: {:.0}", lookups_per_sec);
103    println!(
104        "Average lookup time: {:.3} microseconds",
105        (lookup_time * 1_000_000.0) / total_lookups as f64
106    );
107    println!();
108
109    // Benchmark predictive search
110    println!("=== Predictive Search Benchmark ===");
111    let search_iterations = 50;
112    let search_time = benchmark_predictive_search(&trie, &prefixes, search_iterations);
113    let total_searches = prefixes.len() * search_iterations;
114    let searches_per_sec = total_searches as f64 / search_time;
115
116    println!(
117        "Performed {} predictive searches in {:.3} seconds",
118        total_searches, search_time
119    );
120    println!("Searches per second: {:.0}", searches_per_sec);
121    println!(
122        "Average search time: {:.3} microseconds",
123        (search_time * 1_000_000.0) / total_searches as f64
124    );
125    println!();
126
127    // Memory usage estimation
128    println!("=== Memory Usage ===");
129    println!("Number of keys: {}", words.len());
130    println!(
131        "Average key length: {:.1} characters",
132        words.iter().map(|w| w.len()).sum::<usize>() as f64 / words.len() as f64
133    );
134
135    // Save trie to file to measure size
136    let filename = "benchmark_trie.marisa";
137    trie.save(filename)?;
138
139    if let Ok(metadata) = std::fs::metadata(filename) {
140        let file_size = metadata.len();
141        let bytes_per_key = file_size as f64 / words.len() as f64;
142
143        println!(
144            "Trie file size: {} bytes ({:.2} KB)",
145            file_size,
146            file_size as f64 / 1024.0
147        );
148        println!("Bytes per key: {:.2}", bytes_per_key);
149        println!("Compression ratio: {:.1}%", (bytes_per_key / 10.0) * 100.0); // Assuming ~10 bytes per key on average
150    }
151
152    // Clean up
153    std::fs::remove_file(filename)?;
154    println!();
155
156    // Sample some results
157    println!("=== Sample Results ===");
158    let sample_words = vec!["apples", "bananas", "cherries", "dogs", "elephants"];
159
160    for word in sample_words {
161        match trie.lookup(word) {
162            Some(id) => println!("'{}' -> ID: {}", word, id),
163            None => println!("'{}' -> Not found", word),
164        }
165    }
166
167    println!();
168    println!("Predictive search for 'app':");
169    let mut agent = Agent::new()?;
170    if trie.predictive_search("app", &mut agent)? {
171        // Note: agent.next() is not implemented yet
172        // For now, we'll show only the first result
173        let key = agent.key()?;
174        println!("  - {}", key);
175        println!("  Total: 1 key (iteration not implemented)");
176    }
177
178    Ok(())
179}
Source

pub fn id(&self) -> u32

Get the current key ID

Examples found in repository?
examples/basic_usage.rs (line 73)
12fn main() -> Result<(), Box<dyn std::error::Error>> {
13    println!("Marisa FFI Example");
14    println!("Version: {}", version());
15    println!();
16
17    // Create a keyset and add some sample keys
18    let mut keyset = Keyset::new()?;
19
20    let sample_keys = vec![
21        "apple",
22        "application",
23        "apply",
24        "app",
25        "banana",
26        "band",
27        "bandit",
28        "cherry",
29        "cheese",
30        "chef",
31        "dog",
32        "doggy",
33        "doggie",
34        "elephant",
35        "eleven",
36        "elevator",
37    ];
38
39    println!("Adding {} keys to keyset...", sample_keys.len());
40    for key in &sample_keys {
41        keyset.push(key)?;
42    }
43
44    // Build the trie
45    println!("Building trie...");
46    let trie = Trie::build(&keyset)?;
47    println!("Trie built successfully!");
48    println!();
49
50    // Test exact lookup
51    println!("=== Exact Lookup Tests ===");
52    let test_keys = vec!["apple", "banana", "nonexistent", "app"];
53    for key in test_keys {
54        match trie.lookup(key) {
55            Some(id) => println!("Found '{}' with ID: {}", key, id),
56            None => println!("'{}' not found", key),
57        }
58    }
59    println!();
60
61    // Test predictive search
62    println!("=== Predictive Search Tests ===");
63    let prefixes = vec!["app", "ban", "che", "dog", "ele"];
64
65    for prefix in prefixes {
66        println!("Keys starting with '{}':", prefix);
67        let mut agent = Agent::new()?;
68
69        if trie.predictive_search(prefix, &mut agent)? {
70            // Note: agent.next() is not implemented yet
71            // For now, we'll show only the first result
72            let key = agent.key()?;
73            let id = agent.id();
74            println!("  - {} (ID: {})", key, id);
75            println!("  Total: 1 key (iteration not implemented)");
76        } else {
77            println!("  No keys found");
78        }
79        println!();
80    }
81
82    // Test reverse lookup
83    println!("=== Reverse Lookup Tests ===");
84    let test_ids = vec![0, 1, 2, 3, 4];
85    let mut agent = Agent::new()?;
86
87    for id in test_ids {
88        match trie.reverse_lookup(id, &mut agent) {
89            Ok(_) => {
90                let key = agent.key()?;
91                println!("ID {} -> '{}'", id, key);
92            }
93            Err(e) => println!("ID {} -> Error: {}", id, e),
94        }
95    }
96    println!();
97
98    // Test common prefix search
99    println!("=== Common Prefix Search Tests ===");
100    let test_strings = vec!["application", "bandit", "chef", "doggie"];
101
102    for test_str in test_strings {
103        println!("Common prefixes of '{}':", test_str);
104        let mut agent = Agent::new()?;
105
106        if trie.common_prefix_search(test_str, &mut agent)? {
107            // Note: agent.next() is not implemented yet
108            // For now, we'll show only the first result
109            let key = agent.key()?;
110            let id = agent.id();
111            println!("  - {} (ID: {})", key, id);
112            println!("  Total: 1 prefix (iteration not implemented)");
113        } else {
114            println!("  No prefixes found");
115        }
116        println!();
117    }
118
119    // Save and load example
120    println!("=== Save/Load Test ===");
121    let filename = "test_trie.marisa";
122
123    // Save the trie
124    trie.save(filename)?;
125    println!("Trie saved to '{}'", filename);
126
127    // Load it back
128    let mut loaded_trie = Trie::new()?;
129    loaded_trie.load(filename)?;
130    println!("Trie loaded from '{}'", filename);
131
132    // Verify it works
133    match loaded_trie.lookup("apple") {
134        Some(id) => println!("Loaded trie lookup 'apple' -> ID: {}", id),
135        None => println!("Loaded trie lookup 'apple' -> Not found"),
136    }
137
138    // Clean up
139    std::fs::remove_file(filename)?;
140    println!("Test file '{}' removed", filename);
141
142    Ok(())
143}
Source

pub fn next(&mut self) -> Result<bool, MarisaError>

Move to the next result

Trait Implementations§

Source§

impl Drop for Agent

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

§

impl Freeze for Agent

§

impl RefUnwindSafe for Agent

§

impl !Send for Agent

§

impl !Sync for Agent

§

impl Unpin for Agent

§

impl UnwindSafe for Agent

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.