SetOptions

Struct SetOptions 

Source
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

Source

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
Hide additional 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}
Source

pub fn with_expiration(expires_at: SystemTime) -> Self

Create options with absolute expiration time

Source

pub fn effective_expires_at(&self) -> Option<SystemTime>

Get the effective expiration time

Trait Implementations§

Source§

impl Clone for SetOptions

Source§

fn clone(&self) -> SetOptions

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for SetOptions

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for SetOptions

Source§

fn default() -> SetOptions

Returns the “default value” for a type. Read more

Auto Trait Implementations§

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. 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> IntoEither for T

Source§

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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

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
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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.
Source§

impl<G1, G2> Within<G2> for G1
where G2: Contains<G1>,

Source§

fn is_within(&self, b: &G2) -> bool