pub mod buffers;
pub mod debug;
pub mod encoding;
pub mod file_lifecycle;
pub mod file_management;
pub mod file_ops;
pub mod graph_file_accessors;
pub mod graph_file_advanced;
pub mod graph_file_coordinator;
pub mod graph_file_core;
pub mod graph_file_io;
pub mod header;
pub mod io_backend;
pub mod io_operations;
pub mod memory_mapping;
pub mod memory_resource_manager;
pub mod mmap_ops;
pub mod node_edge_access;
pub mod transaction;
pub mod transaction_auditor;
pub mod validation;
use std::fs::File;
#[allow(unused_imports)]
use std::io::Read;
#[allow(unused_imports)]
use std::path::Path;
use crate::backend::native::{
persistent_header::PersistentHeaderV2,
transaction_state::TransactionState,
types::{NativeBackendError, NativeNodeId, NativeResult},
};
#[cfg(feature = "v2_experimental")]
use memmap2::MmapMut;
pub const DEFAULT_NODE_DATA_START: u64 = 1024;
pub const RESERVED_NODE_REGION_BYTES: u64 = 8 * 1024 * 1024;
pub use buffers::{ReadBuffer, WriteBuffer};
pub use debug::DebugInstrumentation;
pub use encoding::{decode_persistent_header, encode_persistent_header, get_slice_safe};
pub use file_lifecycle::FileLifecycleManager;
pub use file_management::FileManager;
pub use file_ops::{FileOperations, IOMode};
pub use graph_file_advanced::{DebugInfo, FileHealthStatus, OptimizationReport};
pub use graph_file_coordinator::{GraphFileCoordinator, TransactionCoordinatorStatistics};
pub use header::{ClusterUtilization, HeaderManager, HeaderStatistics};
pub use io_backend::{IOBackendManager, IOBackendStatistics};
pub use io_operations::IOOperationsManager;
pub use memory_mapping::MemoryMappingManager;
pub use memory_resource_manager::{
AccessPatternHint, MemoryIOMode, MemoryManagementStatistics, MemoryResourceManager, MemoryUtils,
};
pub use mmap_ops::{MMapConfig, MMapManager, MMapStatistics};
pub use node_edge_access::NodeEdgeAccessManager;
pub use transaction::{TransactionManager, TransactionStatistics};
pub use transaction_auditor::{TransactionAuditor, TransactionAuditorStatistics};
pub use validation::GraphFileValidator;
pub struct GraphFile {
file: File,
persistent_header: PersistentHeaderV2,
transaction_state: TransactionState,
file_path: std::path::PathBuf,
read_buffer: ReadBuffer,
write_buffer: WriteBuffer,
#[cfg(feature = "v2_experimental")]
mmap: Option<MmapMut>,
transaction_auditor: TransactionAuditor,
}
impl GraphFile {
pub fn finish_cluster_commit(&mut self) -> NativeResult<()> {
TransactionManager::finish_cluster_commit(&mut self.file)
}
pub fn record_node_v2_cluster_modified(&mut self, node_id: NativeNodeId) {
self.transaction_auditor
.record_node_v2_cluster_modified(node_id);
}
fn clear_v2_cluster_metadata_on_rollback(&mut self) -> NativeResult<()> {
self.transaction_auditor
.clear_v2_cluster_metadata_on_rollback()
}
pub fn header(&self) -> &PersistentHeaderV2 {
&self.persistent_header
}
pub fn header_mut(&mut self) -> &mut PersistentHeaderV2 {
&mut self.persistent_header
}
pub fn tx_state(&self) -> &TransactionState {
&self.transaction_state
}
pub fn tx_state_mut(&mut self) -> &mut TransactionState {
&mut self.transaction_state
}
pub fn persistent_header(&self) -> &PersistentHeaderV2 {
&self.persistent_header
}
pub fn persistent_header_mut(&mut self) -> &mut PersistentHeaderV2 {
&mut self.persistent_header
}
pub fn transaction_state(&self) -> &TransactionState {
&self.transaction_state
}
pub fn transaction_state_mut(&mut self) -> &mut TransactionState {
&mut self.transaction_state
}
pub fn ensure_file_len_at_least(&mut self, min_len: u64) -> NativeResult<()> {
use crate::backend::native::graph_file::io_operations::IOOperationsManager;
IOOperationsManager::ensure_file_len_at_least(&mut self.file, min_len)
}
pub fn write_header(&mut self) -> NativeResult<()> {
use crate::backend::native::graph_file::encoding::encode_persistent_header;
use std::io::{Seek, SeekFrom, Write};
let header_bytes = encode_persistent_header(&self.persistent_header)?;
self.file.seek(SeekFrom::Start(0))?;
self.file.write_all(&header_bytes)?;
self.file.flush()?;
self.file.sync_all().map_err(NativeBackendError::Io)?;
Ok(())
}
pub fn sync(&mut self) -> NativeResult<()> {
self.file.sync_all().map_err(NativeBackendError::Io)
}
pub fn file_path(&self) -> &std::path::Path {
&self.file_path
}
pub fn read_bytes(&mut self, offset: u64, buffer: &mut [u8]) -> NativeResult<()> {
use std::io::{Read, Seek, SeekFrom};
self.file.seek(SeekFrom::Start(offset))?;
self.file.read_exact(buffer)?;
Ok(())
}
pub fn write_bytes(&mut self, offset: u64, data: &[u8]) -> NativeResult<()> {
use std::io::{Seek, SeekFrom, Write};
self.file.seek(SeekFrom::Start(offset))?;
self.file.write_all(data)?;
Ok(())
}
pub fn file_size(&self) -> NativeResult<u64> {
use crate::backend::native::graph_file::file_ops::FileOperations;
FileOperations::file_size(&self.file)
}
fn file_mut(&mut self) -> &mut File {
&mut self.file
}
}
impl Drop for GraphFile {
fn drop(&mut self) {
if self.persistent_header.node_count == 0 {
return;
}
let _ = self.write_header();
let _ = self.sync();
}
}