Skip to main content

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::fmt;
31use std::sync::Arc;
32
33use super::{
34    ElementArchiveIndex, ElementIndex, FutureQueue, IndexError, ResultIndex, SessionControl,
35};
36
37/// Set of indexes for a query.
38///
39/// Groups the index types and session control needed for query evaluation into
40/// a single unit.
41/// This enables backends to create all indexes from a shared underlying resource
42/// (e.g., a single RocksDB instance or Redis connection).
43pub struct IndexSet {
44    /// Element index for storing graph elements
45    pub element_index: Arc<dyn ElementIndex>,
46    /// Archive index for storing historical elements (for past() function)
47    pub archive_index: Arc<dyn ElementArchiveIndex>,
48    /// Result index for storing query results
49    pub result_index: Arc<dyn ResultIndex>,
50    /// Future queue for temporal queries
51    pub future_queue: Arc<dyn FutureQueue>,
52    /// Session control for atomic transaction lifecycle
53    pub session_control: Arc<dyn SessionControl>,
54}
55
56impl fmt::Debug for IndexSet {
57    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
58        f.debug_struct("IndexSet")
59            .field("element_index", &"<trait object>")
60            .field("archive_index", &"<trait object>")
61            .field("result_index", &"<trait object>")
62            .field("future_queue", &"<trait object>")
63            .field("session_control", &"<trait object>")
64            .finish()
65    }
66}
67
68/// Plugin trait for external index storage backends.
69///
70/// Each storage backend (RocksDB, Garnet, etc.) implements this trait to provide
71/// all index types needed for query evaluation from a single shared backend instance.
72///
73/// # Thread Safety
74///
75/// Implementations must be `Send + Sync` to allow use across async tasks.
76///
77/// # Example
78///
79/// ```ignore
80/// use drasi_core::interface::{IndexBackendPlugin, IndexSet};
81///
82/// pub struct MyIndexProvider {
83///     // configuration fields
84/// }
85///
86/// #[async_trait]
87/// impl IndexBackendPlugin for MyIndexProvider {
88///     async fn create_index_set(&self, query_id: &str) -> Result<IndexSet, IndexError> {
89///         // Create and return all indexes from a shared backend instance
90///     }
91///     fn is_volatile(&self) -> bool { false }
92/// }
93/// ```
94#[async_trait]
95pub trait IndexBackendPlugin: Send + Sync {
96    /// Create all indexes for a query from a single shared backend instance.
97    ///
98    /// This method creates the element index, archive index, result index,
99    /// future queue, and session control backed by a shared storage resource
100    /// (e.g., a single RocksDB database or Redis connection). This reduces
101    /// resource overhead and enables cross-index atomic transactions.
102    async fn create_index_set(&self, query_id: &str) -> Result<IndexSet, IndexError>;
103
104    /// Returns true if this backend is volatile (data lost on restart).
105    ///
106    /// Volatile backends (like in-memory) require re-bootstrapping after restart,
107    /// while persistent backends (like RocksDB) retain data.
108    fn is_volatile(&self) -> bool;
109}