drasi_core/interface/index_backend.rs
1// Copyright 2025 The Drasi Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Index Backend Plugin Trait
16//!
17//! This module defines the `IndexBackendPlugin` trait that external index backends
18//! (like RocksDB, Garnet/Redis) must implement to integrate with Drasi.
19//!
20//! # Architecture
21//!
22//! The index plugin system follows pure dependency inversion:
23//! - **Core** provides index traits (`ElementIndex`, `ResultIndex`, etc.) and a default
24//! in-memory implementation
25//! - **Lib** uses this plugin trait but has no knowledge of specific implementations
26//! - **External plugins** (in `components/indexes/`) implement this trait
27//! - **Applications** optionally inject plugins; if none provided, the in-memory default is used
28
29use async_trait::async_trait;
30use std::sync::Arc;
31
32use super::{ElementArchiveIndex, ElementIndex, FutureQueue, IndexError, ResultIndex};
33
34/// Plugin trait for external index storage backends.
35///
36/// Each storage backend (RocksDB, Garnet, etc.) implements this trait to provide
37/// the four index types needed for query evaluation.
38///
39/// # Thread Safety
40///
41/// Implementations must be `Send + Sync` to allow use across async tasks.
42///
43/// # Example
44///
45/// ```ignore
46/// use drasi_core::interface::IndexBackendPlugin;
47///
48/// pub struct MyIndexProvider {
49/// // configuration fields
50/// }
51///
52/// #[async_trait]
53/// impl IndexBackendPlugin for MyIndexProvider {
54/// async fn create_element_index(&self, query_id: &str) -> Result<Arc<dyn ElementIndex>, IndexError> {
55/// // Create and return your element index implementation
56/// }
57/// // ... other methods
58/// }
59/// ```
60#[async_trait]
61pub trait IndexBackendPlugin: Send + Sync {
62 /// Create an ElementIndex instance for the given query.
63 ///
64 /// The element index manages the current graph elements (nodes and relationships)
65 /// for a specific query. Each query gets its own isolated index instance.
66 async fn create_element_index(
67 &self,
68 query_id: &str,
69 ) -> Result<Arc<dyn ElementIndex>, IndexError>;
70
71 /// Create an ElementArchiveIndex instance for the given query.
72 ///
73 /// The archive index supports point-in-time queries and version history,
74 /// enabling the `past()` function in Cypher queries.
75 async fn create_archive_index(
76 &self,
77 query_id: &str,
78 ) -> Result<Arc<dyn ElementArchiveIndex>, IndexError>;
79
80 /// Create a ResultIndex instance for the given query.
81 ///
82 /// The result index stores accumulated query results and aggregations,
83 /// supporting efficient incremental computation.
84 async fn create_result_index(&self, query_id: &str)
85 -> Result<Arc<dyn ResultIndex>, IndexError>;
86
87 /// Create a FutureQueue instance for the given query.
88 ///
89 /// The future queue manages temporal queries and scheduled operations,
90 /// enabling time-based query features.
91 async fn create_future_queue(&self, query_id: &str)
92 -> Result<Arc<dyn FutureQueue>, IndexError>;
93
94 /// Returns true if this backend is volatile (data lost on restart).
95 ///
96 /// Volatile backends (like in-memory) require re-bootstrapping after restart,
97 /// while persistent backends (like RocksDB) retain data.
98 fn is_volatile(&self) -> bool;
99}