pub struct SetOptions {
pub ttl: Option<Duration>,
pub expires_at: Option<SystemTime>,
}Expand description
Options for setting values with optional TTL
Fields§
§ttl: Option<Duration>Time-to-live for this item
expires_at: Option<SystemTime>Absolute expiration time (takes precedence over TTL)
Implementations§
Source§impl SetOptions
impl SetOptions
Sourcepub fn with_ttl(ttl: Duration) -> Self
pub fn with_ttl(ttl: Duration) -> Self
Create options with TTL
Examples found in repository?
examples/persistence_lifecycle.rs (line 201)
182fn demo_graceful_shutdown() -> Result<(), Box<dyn std::error::Error>> {
183 println!("--- Demo 4: Graceful Shutdown ---");
184
185 let db_path = "/tmp/spatio_demo_shutdown.db";
186
187 println!("Creating database and inserting critical data...");
188 let mut db = Spatio::open(db_path)?;
189
190 // Insert critical data
191 db.insert("transaction:001", b"payment_processed", None)?;
192 db.insert("transaction:002", b"refund_pending", None)?;
193
194 println!(" ✓ Critical data inserted");
195
196 // Force sync before critical operations
197 db.sync()?;
198 println!(" ✓ Forced sync to disk");
199
200 // Add TTL data
201 let opts = SetOptions::with_ttl(Duration::from_secs(300));
202 db.insert("session:xyz", b"temporary_session", Some(opts))?;
203 println!(" ✓ Added temporary session with 5-minute TTL");
204
205 // Explicit close with error handling
206 println!("Performing explicit graceful shutdown...");
207 match db.close() {
208 Ok(_) => println!(" ✓ Database closed successfully"),
209 Err(e) => {
210 eprintln!(" ✗ Error during close: {}", e);
211 return Err(e.into());
212 }
213 }
214
215 // Verify we can't use closed database
216 match db.insert("should_fail", b"data", None) {
217 Err(e) => println!(" ✓ Correctly rejected operation on closed database: {}", e),
218 Ok(_) => println!(" ✗ Unexpectedly accepted operation on closed database"),
219 }
220
221 println!();
222 Ok(())
223}More examples
examples/getting_started.rs (line 21)
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5 println!("Spatio - Getting Started Example");
6 println!("=================================");
7
8 // Create an in-memory database
9 let db = Spatio::memory()?;
10 println!("Created in-memory database");
11
12 // Basic key-value operations
13 db.insert("user:123", b"John Doe", None)?;
14 let value = db.get("user:123")?.unwrap();
15 println!(
16 "Basic storage: user:123 = {}",
17 String::from_utf8_lossy(&value)
18 );
19
20 // Store data with TTL (time-to-live)
21 let ttl_options = SetOptions::with_ttl(Duration::from_secs(5));
22 db.insert("session:abc", b"expires_soon", Some(ttl_options))?;
23 println!("Stored session data with 5-second TTL");
24
25 // Spatial point operations
26 let new_york = Point::new(40.7128, -74.0060);
27 let london = Point::new(51.5074, -0.1278);
28 let tokyo = Point::new(35.6762, 139.6503);
29
30 // Store geographic points (automatically indexed for spatial queries)
31 db.insert_point("cities", &new_york, b"New York", None)?;
32 db.insert_point("cities", &london, b"London", None)?;
33 db.insert_point("cities", &tokyo, b"Tokyo", None)?;
34 println!("Stored geographic points for major cities");
35
36 // Calculate distance between cities
37 let distance_km = new_york.distance_to(&london) / 1000.0;
38 println!("Distance NYC ↔ London: {:.0} km", distance_km);
39
40 // Find nearby cities (within 2000km of NYC)
41 let nearby = db.find_nearby("cities", &new_york, 2_000_000.0, 5)?;
42 println!("Found {} cities within 2000km of NYC", nearby.len());
43 for (point, data) in &nearby {
44 println!(
45 " - {} at ({:.2}, {:.2})",
46 String::from_utf8_lossy(data),
47 point.lat,
48 point.lon
49 );
50 }
51
52 // Atomic batch operations
53 db.atomic(|batch| {
54 batch.insert("sensor:temperature", b"22.5C", None)?;
55 batch.insert("sensor:humidity", b"65%", None)?;
56 batch.insert("sensor:pressure", b"1013.25 hPa", None)?;
57 Ok(())
58 })?;
59 println!("Performed atomic batch insert of sensor data");
60
61 // Trajectory tracking example
62 let vehicle_path = vec![
63 (Point::new(40.7128, -74.0060), 1640995200), // Start: NYC
64 (Point::new(40.7150, -74.0040), 1640995260), // 1 minute later
65 (Point::new(40.7172, -74.0020), 1640995320), // 2 minutes later
66 (Point::new(40.7194, -74.0000), 1640995380), // 3 minutes later
67 ];
68
69 db.insert_trajectory("vehicle:truck001", &vehicle_path, None)?;
70 println!(
71 "Stored vehicle trajectory with {} waypoints",
72 vehicle_path.len()
73 );
74
75 // Query trajectory for a time range
76 let path_segment = db.query_trajectory("vehicle:truck001", 1640995200, 1640995320)?;
77 println!(
78 "Retrieved {} waypoints for first 2 minutes",
79 path_segment.len()
80 );
81
82 // Check database statistics
83 let stats = db.stats()?;
84 println!("Database contains {} keys", stats.key_count);
85
86 // Wait a moment to see TTL in action
87 println!("\nWaiting 6 seconds to demonstrate TTL...");
88 std::thread::sleep(Duration::from_secs(6));
89
90 // Try to retrieve expired data
91 match db.get("session:abc")? {
92 Some(_) => println!("TTL data still exists (unexpected)"),
93 None => println!("TTL data expired as expected"),
94 }
95
96 println!("\nGetting started example completed successfully!");
97 println!("\nKey features demonstrated:");
98 println!("- Simple key-value storage");
99 println!("- Automatic spatial indexing for points");
100 println!("- Nearby point queries");
101 println!("- Trajectory tracking over time");
102 println!("- TTL (time-to-live) support");
103 println!("- Atomic batch operations");
104
105 println!("\nNext steps:");
106 println!("- Try the 'spatial_queries' example for more spatial operations");
107 println!("- See 'trajectory_tracking' for advanced movement analysis");
108
109 Ok(())
110}examples/comprehensive_demo.rs (line 28)
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5 println!("Spatio - Comprehensive Demo");
6 println!("===========================");
7
8 // Create an in-memory database
9 let db = Spatio::memory()?;
10 println!("Created in-memory database");
11
12 // === BASIC KEY-VALUE OPERATIONS ===
13 println!("\nBasic Key-Value Operations");
14
15 // Simple string storage
16 db.insert("app:name", b"Spatio Demo App", None)?;
17 db.insert("app:version", b"1.0.0", None)?;
18 db.insert("app:author", b"Spatio Team", None)?;
19
20 // Retrieve and display
21 let app_name = db.get("app:name")?.unwrap();
22 println!(" App: {}", String::from_utf8_lossy(&app_name));
23
24 // === TTL (TIME-TO-LIVE) OPERATIONS ===
25 println!("\nTTL (Time-to-Live) Operations");
26
27 // Short-lived session data
28 let session_opts = SetOptions::with_ttl(Duration::from_secs(10));
29 db.insert("session:user123", b"active", Some(session_opts))?;
30 println!(" Created session with 10-second TTL");
31
32 // Cache data with different TTL
33 let cache_opts = SetOptions::with_ttl(Duration::from_secs(300)); // 5 minutes
34 db.insert("cache:weather", b"sunny, 22C", Some(cache_opts.clone()))?;
35 db.insert(
36 "cache:news",
37 b"Latest tech news...",
38 Some(cache_opts.clone()),
39 )?;
40 println!(" Cached data with 5-minute TTL");
41
42 // === ATOMIC BATCH OPERATIONS ===
43 println!("\nAtomic Batch Operations");
44
45 // User profile creation (all-or-nothing)
46 db.atomic(|batch| {
47 batch.insert("user:123:name", b"Alice Johnson", None)?;
48 batch.insert("user:123:email", b"alice@example.com", None)?;
49 batch.insert("user:123:role", b"admin", None)?;
50 batch.insert("user:123:created", b"2024-01-01", None)?;
51 Ok(())
52 })?;
53 println!(" Created user profile atomically");
54
55 // Sensor data batch insert
56 db.atomic(|batch| {
57 batch.insert("sensor:temp", b"23.5", None)?;
58 batch.insert("sensor:humidity", b"68", None)?;
59 batch.insert("sensor:pressure", b"1013.2", None)?;
60 batch.insert("sensor:timestamp", b"1640995200", None)?;
61 Ok(())
62 })?;
63 println!(" Recorded sensor readings atomically");
64
65 // === SPATIAL POINT OPERATIONS ===
66 println!("\nSpatial Point Operations");
67
68 // Major world cities
69 let cities = vec![
70 ("New York", Point::new(40.7128, -74.0060)),
71 ("London", Point::new(51.5074, -0.1278)),
72 ("Tokyo", Point::new(35.6762, 139.6503)),
73 ("Paris", Point::new(48.8566, 2.3522)),
74 ("Sydney", Point::new(-33.8688, 151.2093)),
75 ("São Paulo", Point::new(-23.5505, -46.6333)),
76 ("Mumbai", Point::new(19.0760, 72.8777)),
77 ("Cairo", Point::new(30.0444, 31.2357)),
78 ];
79
80 // Insert cities with automatic spatial indexing
81 for (name, point) in &cities {
82 db.insert_point("cities", point, name.as_bytes(), None)?;
83 }
84 println!(
85 " Added {} cities with automatic spatial indexing",
86 cities.len()
87 );
88
89 // Calculate distances between cities
90 let london = Point::new(51.5074, -0.1278);
91 let paris = Point::new(48.8566, 2.3522);
92 let distance_km = london.distance_to(&paris) / 1000.0;
93 println!(" London ↔ Paris: {:.0} km", distance_km);
94
95 // Find cities near London (within 1000km)
96 let nearby_london = db.find_nearby("cities", &london, 1_000_000.0, 5)?;
97 println!(" Cities within 1000km of London:");
98 for (point, data) in &nearby_london {
99 let city_name = String::from_utf8_lossy(data);
100 let distance = london.distance_to(point) / 1000.0;
101 println!(" - {} ({:.0} km)", city_name, distance);
102 }
103
104 // === RESTAURANT/POI DATA ===
105 println!("\nPoints of Interest");
106
107 let london_restaurants = vec![
108 ("The Shard Restaurant", Point::new(51.5045, -0.0865)),
109 ("Sketch", Point::new(51.5115, -0.1442)),
110 ("Dishoom", Point::new(51.5145, -0.1270)),
111 ("Borough Market", Point::new(51.5055, -0.0931)),
112 ];
113
114 for (name, point) in &london_restaurants {
115 db.insert_point("london_food", point, name.as_bytes(), None)?;
116 }
117 println!(" Added {} London restaurants", london_restaurants.len());
118
119 // Find restaurants near a specific location (Covent Garden)
120 let covent_garden = Point::new(51.5118, -0.1226);
121 let nearby_food = db.find_nearby("london_food", &covent_garden, 2000.0, 10)?;
122 println!(" Restaurants within 2km of Covent Garden:");
123 for (point, data) in &nearby_food {
124 let restaurant_name = String::from_utf8_lossy(data);
125 let distance = covent_garden.distance_to(point);
126 println!(" - {} ({:.0}m away)", restaurant_name, distance);
127 }
128
129 // === TRAJECTORY TRACKING ===
130 println!("\nTrajectory Tracking");
131
132 // Delivery truck route through London
133 let delivery_route = vec![
134 (Point::new(51.5074, -0.1278), 1640995200), // Start: London center
135 (Point::new(51.5055, -0.0931), 1640995260), // Stop 1: Borough Market (1 min)
136 (Point::new(51.5045, -0.0865), 1640995320), // Stop 2: The Shard (2 min)
137 (Point::new(51.4994, -0.1245), 1640995380), // Stop 3: Big Ben (3 min)
138 (Point::new(51.5014, -0.1419), 1640995440), // Stop 4: Buckingham Palace (4 min)
139 (Point::new(51.5118, -0.1226), 1640995500), // End: Covent Garden (5 min)
140 ];
141
142 db.insert_trajectory("delivery:truck001", &delivery_route, None)?;
143 println!(
144 " Stored delivery truck trajectory ({} waypoints)",
145 delivery_route.len()
146 );
147
148 // Taxi route
149 let taxi_route = vec![
150 (Point::new(51.4700, -0.4543), 1640995200), // Heathrow Airport
151 (Point::new(51.4900, -0.1743), 1640995800), // Kensington (10 min)
152 (Point::new(51.5074, -0.1278), 1640996100), // Central London (15 min)
153 ];
154
155 db.insert_trajectory("taxi:cab042", &taxi_route, None)?;
156 println!(" Stored taxi trajectory ({} waypoints)", taxi_route.len());
157
158 // Query trajectories for specific time ranges
159 let truck_morning = db.query_trajectory("delivery:truck001", 1640995200, 1640995380)?;
160 println!(
161 " Truck trajectory (first 3 minutes): {} points",
162 truck_morning.len()
163 );
164
165 let taxi_full = db.query_trajectory("taxi:cab042", 1640995200, 1640996200)?;
166 println!(" Full taxi journey: {} points", taxi_full.len());
167
168 // === SENSOR NETWORK SIMULATION ===
169 println!("\nIoT Sensor Network");
170
171 // Simulate temperature sensors across London
172 let sensors = vec![
173 ("sensor001", Point::new(51.5074, -0.1278), "22.5°C"), // Central
174 ("sensor002", Point::new(51.5200, -0.1000), "21.8°C"), // North
175 ("sensor003", Point::new(51.4900, -0.1500), "23.1°C"), // South
176 ("sensor004", Point::new(51.5100, -0.0800), "22.9°C"), // East
177 ("sensor005", Point::new(51.5000, -0.1800), "21.5°C"), // West
178 ];
179
180 for (sensor_id, point, reading) in &sensors {
181 db.insert_point(
182 "sensors",
183 point,
184 format!("{}:{}", sensor_id, reading).as_bytes(),
185 None,
186 )?;
187 }
188 println!(" Deployed {} temperature sensors", sensors.len());
189
190 // Find sensors near a specific location
191 let monitoring_center = Point::new(51.5100, -0.1200);
192 let nearby_sensors = db.find_nearby("sensors", &monitoring_center, 5000.0, 10)?;
193 println!(" Sensors within 5km of monitoring center:");
194 for (point, data) in &nearby_sensors {
195 let sensor_info = String::from_utf8_lossy(data);
196 let distance = monitoring_center.distance_to(point);
197 println!(" - {} ({:.0}m away)", sensor_info, distance);
198 }
199
200 // === REAL-TIME UPDATES ===
201 println!("\nReal-time Updates");
202
203 // Simulate updating sensor readings
204 db.insert_point(
205 "sensors",
206 &Point::new(51.5074, -0.1278),
207 b"sensor001:24.2C",
208 None,
209 )?;
210 println!(" Updated sensor001 reading");
211
212 // Add new vehicle to tracking
213 let bus_route = vec![
214 (Point::new(51.5155, -0.0922), 1640995600), // Liverpool Street
215 (Point::new(51.5074, -0.1278), 1640995660), // Central London
216 ];
217 db.insert_trajectory("bus:route25", &bus_route, None)?;
218 println!(" Added new bus to tracking system");
219
220 // === DATABASE STATISTICS ===
221 println!("\nDatabase Statistics");
222
223 let stats = db.stats()?;
224 println!(" Total keys: {}", stats.key_count);
225 println!(" Operations performed: {}", stats.operations_count);
226
227 // Count items by namespace
228 let mut namespace_counts = std::collections::HashMap::new();
229 // This is a simplified count - in practice you'd query by prefix
230 namespace_counts.insert("cities", cities.len());
231 namespace_counts.insert("restaurants", london_restaurants.len());
232 namespace_counts.insert("sensors", sensors.len());
233 namespace_counts.insert("trajectories", 3); // truck, taxi, bus
234
235 println!(" Data distribution:");
236 for (namespace, count) in &namespace_counts {
237 println!(" - {}: {} items", namespace, count);
238 }
239
240 // === CLEANUP DEMONSTRATION ===
241 println!("\nCleanup & TTL Demo");
242
243 // Check if session has expired (it should have by now)
244 if let Some(_session) = db.get("session:user123")? {
245 println!(" Session still active");
246 } else {
247 println!(" Session expired as expected");
248 }
249
250 // Delete specific items
251 db.delete("app:version")?;
252 println!(" Removed app version info");
253
254 // Final statistics
255 let final_stats = db.stats()?;
256 println!(" Final key count: {}", final_stats.key_count);
257
258 println!("\nComprehensive demo completed successfully!");
259 println!("\nFeatures demonstrated:");
260 println!("- Key-value storage with TTL");
261 println!("- Atomic batch operations");
262 println!("- Automatic spatial indexing");
263 println!("- Geographic point queries");
264 println!("- Distance calculations");
265 println!("- Trajectory tracking");
266 println!("- Multi-namespace organization");
267 println!("- Real-time updates");
268 println!("- Data expiration");
269
270 Ok(())
271}examples/trajectory_tracking.rs (line 94)
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5 println!("Spatio - Trajectory Tracking Example");
6 println!("========================================");
7
8 // Create an in-memory database
9 let db = Spatio::memory()?;
10 println!("Created in-memory database");
11
12 // === VEHICLE TRAJECTORY TRACKING ===
13 println!("\n--- Vehicle Trajectory Tracking ---");
14
15 // Simulate a delivery truck route through Manhattan
16 let delivery_truck_route = vec![
17 (Point::new(40.7128, -74.0060), 1640995200), // Start: Financial District
18 (Point::new(40.7180, -74.0020), 1640995260), // Move north
19 (Point::new(40.7230, -73.9980), 1640995320), // Continue north
20 (Point::new(40.7280, -73.9940), 1640995380), // Midtown approach
21 (Point::new(40.7330, -73.9900), 1640995440), // Midtown
22 (Point::new(40.7380, -73.9860), 1640995500), // Times Square area
23 (Point::new(40.7430, -73.9820), 1640995560), // Continue north
24 (Point::new(40.7480, -73.9780), 1640995620), // Central Park area
25 (Point::new(40.7530, -73.9740), 1640995680), // Upper West Side
26 (Point::new(40.7580, -73.9700), 1640995740), // End: Upper Manhattan
27 ];
28
29 db.insert_trajectory("vehicle:truck001", &delivery_truck_route, None)?;
30 println!(
31 "Inserted delivery truck trajectory with {} waypoints",
32 delivery_truck_route.len()
33 );
34
35 // Simulate a taxi route with more frequent updates
36 let taxi_route = vec![
37 (Point::new(40.7484, -73.9857), 1640995200), // Times Square
38 (Point::new(40.7490, -73.9850), 1640995210), // 10 seconds later
39 (Point::new(40.7496, -73.9843), 1640995220), // Moving northeast
40 (Point::new(40.7502, -73.9836), 1640995230), // Continuing
41 (Point::new(40.7508, -73.9829), 1640995240), // Heading to Central Park
42 (Point::new(40.7514, -73.9822), 1640995250), // Almost there
43 (Point::new(40.7520, -73.9815), 1640995260), // At Central Park South
44 (Point::new(40.7526, -73.9808), 1640995270), // Into the park area
45 (Point::new(40.7532, -73.9801), 1640995280), // Deeper into park
46 (Point::new(40.7538, -73.9794), 1640995290), // End point
47 ];
48
49 db.insert_trajectory("vehicle:taxi042", &taxi_route, None)?;
50 println!(
51 "Inserted taxi trajectory with {} high-frequency waypoints",
52 taxi_route.len()
53 );
54
55 // === DRONE FLIGHT PATH ===
56 println!("\n--- Drone Flight Path ---");
57
58 // Simulate a drone surveillance pattern
59 let drone_pattern = vec![
60 (Point::new(40.7589, -73.9851), 1640995300), // Start: Bryant Park
61 (Point::new(40.7600, -73.9851), 1640995330), // North
62 (Point::new(40.7600, -73.9840), 1640995360), // East
63 (Point::new(40.7589, -73.9840), 1640995390), // South
64 (Point::new(40.7589, -73.9851), 1640995420), // Back to start
65 (Point::new(40.7600, -73.9851), 1640995450), // Repeat pattern
66 (Point::new(40.7600, -73.9840), 1640995480), // East again
67 (Point::new(40.7589, -73.9840), 1640995510), // South again
68 (Point::new(40.7589, -73.9851), 1640995540), // Complete square
69 ];
70
71 db.insert_trajectory("drone:survey001", &drone_pattern, None)?;
72 println!(
73 "Inserted drone surveillance pattern with {} waypoints",
74 drone_pattern.len()
75 );
76
77 // === PEDESTRIAN TRACKING ===
78 println!("\n--- Pedestrian Tracking ---");
79
80 // Simulate a jogger's route through Central Park
81 let jogger_route = vec![
82 (Point::new(40.7679, -73.9781), 1640995600), // Enter at 72nd St
83 (Point::new(40.7700, -73.9770), 1640995660), // Move into park
84 (Point::new(40.7720, -73.9750), 1640995720), // North along path
85 (Point::new(40.7740, -73.9730), 1640995780), // Continue north
86 (Point::new(40.7760, -73.9710), 1640995840), // Reservoir area
87 (Point::new(40.7780, -73.9730), 1640995900), // Around reservoir
88 (Point::new(40.7800, -73.9750), 1640995960), // North side
89 (Point::new(40.7820, -73.9770), 1640996020), // Continue around
90 (Point::new(40.7800, -73.9790), 1640996080), // West side
91 (Point::new(40.7780, -73.9810), 1640996140), // Complete loop
92 ];
93
94 let ttl_opts = Some(SetOptions::with_ttl(Duration::from_secs(3600))); // 1 hour TTL
95 db.insert_trajectory("pedestrian:jogger123", &jogger_route, ttl_opts)?;
96 println!(
97 "Inserted jogger trajectory with {} waypoints (1-hour TTL)",
98 jogger_route.len()
99 );
100
101 // === TRAJECTORY QUERIES ===
102 println!("\n--- Trajectory Queries ---");
103
104 // Query full trajectories
105 let truck_path = db.query_trajectory("vehicle:truck001", 1640995200, 1640995740)?;
106 println!("Retrieved truck trajectory: {} points", truck_path.len());
107
108 let taxi_path = db.query_trajectory("vehicle:taxi042", 1640995200, 1640995290)?;
109 println!("Retrieved taxi trajectory: {} points", taxi_path.len());
110
111 // Query partial trajectories (time windows)
112 let truck_midjourney = db.query_trajectory("vehicle:truck001", 1640995320, 1640995560)?;
113 println!(
114 "Truck mid-journey segment: {} points",
115 truck_midjourney.len()
116 );
117
118 let taxi_start = db.query_trajectory("vehicle:taxi042", 1640995200, 1640995240)?;
119 println!("Taxi first 40 seconds: {} points", taxi_start.len());
120
121 // === TRAJECTORY ANALYSIS ===
122 println!("\n--- Trajectory Analysis ---");
123
124 // Calculate trajectory distances
125 println!("Calculating trajectory metrics...");
126
127 // Truck route analysis
128 let mut truck_total_distance = 0.0;
129 for i in 1..delivery_truck_route.len() {
130 let distance = delivery_truck_route[i - 1]
131 .0
132 .distance_to(&delivery_truck_route[i].0);
133 truck_total_distance += distance;
134 }
135 let truck_duration =
136 delivery_truck_route.last().unwrap().1 - delivery_truck_route.first().unwrap().1;
137 let truck_avg_speed = (truck_total_distance / truck_duration as f64) * 3.6; // km/h
138
139 println!("Delivery Truck Analysis:");
140 println!(" Total distance: {:.2} km", truck_total_distance / 1000.0);
141 println!(" Duration: {} seconds", truck_duration);
142 println!(" Average speed: {:.1} km/h", truck_avg_speed);
143
144 // Taxi route analysis
145 let mut taxi_total_distance = 0.0;
146 for i in 1..taxi_route.len() {
147 let distance = taxi_route[i - 1].0.distance_to(&taxi_route[i].0);
148 taxi_total_distance += distance;
149 }
150 let taxi_duration = taxi_route.last().unwrap().1 - taxi_route.first().unwrap().1;
151 let taxi_avg_speed = (taxi_total_distance / taxi_duration as f64) * 3.6; // km/h
152
153 println!("\nTaxi Analysis:");
154 println!(" Total distance: {:.2} km", taxi_total_distance / 1000.0);
155 println!(" Duration: {} seconds", taxi_duration);
156 println!(" Average speed: {:.1} km/h", taxi_avg_speed);
157
158 // === REAL-TIME TRACKING SIMULATION ===
159 println!("\n--- Real-Time Tracking Simulation ---");
160
161 // Simulate a bike messenger with real-time updates
162 let current_time = 1640996200u64;
163 let bike_positions = [
164 Point::new(40.7505, -73.9934), // Start
165 Point::new(40.7510, -73.9930), // Moving
166 Point::new(40.7515, -73.9926), // Moving
167 Point::new(40.7520, -73.9922), // Moving
168 Point::new(40.7525, -73.9918), // End
169 ];
170
171 for (i, position) in bike_positions.iter().enumerate() {
172 let timestamp = current_time + (i as u64 * 30); // 30-second intervals
173 let single_point_trajectory = vec![(*position, timestamp)];
174
175 // In real-time, you would append to existing trajectory
176 db.insert_trajectory(
177 &format!("vehicle:bike007:segment_{}", i),
178 &single_point_trajectory,
179 Some(SetOptions::with_ttl(Duration::from_secs(1800))), // 30-minute TTL
180 )?;
181 }
182 println!("Inserted real-time bike messenger updates");
183
184 // === GEOFENCING AND ALERTS ===
185 println!("\n--- Geofencing and Alerts ---");
186
187 // Define a restricted zone (e.g., around a hospital)
188 let restricted_center = Point::new(40.7614, -73.9776); // Near Central Park
189 let restricted_radius = 200.0; // 200 meters
190
191 println!("Checking trajectories for geofence violations...");
192 println!(
193 "Restricted zone: {:.4}°N, {:.4}°E (radius: {}m)",
194 restricted_center.lat, restricted_center.lon, restricted_radius
195 );
196
197 // Check each trajectory for violations
198 let trajectories = [
199 ("vehicle:truck001", &delivery_truck_route),
200 ("vehicle:taxi042", &taxi_route),
201 ("drone:survey001", &drone_pattern),
202 ("pedestrian:jogger123", &jogger_route),
203 ];
204
205 for (vehicle_id, trajectory) in &trajectories {
206 let mut violations = 0;
207 for (point, timestamp) in trajectory.iter() {
208 let distance = point.distance_to(&restricted_center);
209 if distance <= restricted_radius {
210 violations += 1;
211 if violations == 1 {
212 println!(
213 "WARNING: {} entered restricted zone at timestamp {}",
214 vehicle_id, timestamp
215 );
216 }
217 }
218 }
219 if violations == 0 {
220 println!("{} stayed outside restricted zone", vehicle_id);
221 } else {
222 println!(
223 " {} had {} geofence violations total",
224 vehicle_id, violations
225 );
226 }
227 }
228
229 // === TRAJECTORY INTERSECTIONS ===
230 println!("\n--- Trajectory Intersections ---");
231
232 // Find where vehicles came close to each other
233 println!("Analyzing trajectory intersections (within 100m)...");
234
235 let proximity_threshold = 100.0; // meters
236 let mut intersections_found = 0;
237
238 for (truck_point, truck_time) in &delivery_truck_route {
239 for (taxi_point, taxi_time) in &taxi_route {
240 let distance = truck_point.distance_to(taxi_point);
241 let time_diff = truck_time.abs_diff(*taxi_time);
242
243 if distance <= proximity_threshold && time_diff <= 60 {
244 intersections_found += 1;
245 println!(
246 " Truck and taxi within {:.0}m at times {} and {} ({}s apart)",
247 distance, truck_time, taxi_time, time_diff
248 );
249 }
250 }
251 }
252
253 if intersections_found == 0 {
254 println!(" No close encounters found between truck and taxi");
255 }
256
257 // === DATABASE STATISTICS ===
258 println!("\n--- Database Statistics ---");
259
260 let stats = db.stats()?;
261
262 println!("Total database keys: {}", stats.key_count);
263
264 // Note: In a real application, you could track trajectory keys separately
265 println!("Trajectory-related operations completed successfully");
266
267 println!("\nTrajectory tracking example completed successfully!");
268 println!("\nKey capabilities demonstrated:");
269 println!("- Multi-vehicle trajectory storage and retrieval");
270 println!("- Time-windowed trajectory queries");
271 println!("- Real-time position updates with TTL");
272 println!("- Trajectory analysis (distance, speed, duration)");
273 println!("- Geofencing and violation detection");
274 println!("- Trajectory intersection analysis");
275 println!("- Mixed vehicle types (truck, taxi, drone, pedestrian, bike)");
276
277 Ok(())
278}Sourcepub fn with_expiration(expires_at: SystemTime) -> Self
pub fn with_expiration(expires_at: SystemTime) -> Self
Create options with absolute expiration time
Sourcepub fn effective_expires_at(&self) -> Option<SystemTime>
pub fn effective_expires_at(&self) -> Option<SystemTime>
Get the effective expiration time
Trait Implementations§
Source§impl Clone for SetOptions
impl Clone for SetOptions
Source§fn clone(&self) -> SetOptions
fn clone(&self) -> SetOptions
Returns a duplicate of the value. Read more
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source. Read moreSource§impl Debug for SetOptions
impl Debug for SetOptions
Source§impl Default for SetOptions
impl Default for SetOptions
Source§fn default() -> SetOptions
fn default() -> SetOptions
Returns the “default value” for a type. Read more
Auto Trait Implementations§
impl Freeze for SetOptions
impl RefUnwindSafe for SetOptions
impl Send for SetOptions
impl Sync for SetOptions
impl Unpin for SetOptions
impl UnwindSafe for SetOptions
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
Converts
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
Converts
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more