vole_document/field/
session.rs1use std::path::Path;
6
7#[cfg(not(feature = "entropyfs-store"))]
8use crate::error::Error;
9use crate::error::Result;
10use crate::limits::Limits;
11use crate::store::IoSnapshot;
12
13use super::index::FsIndexStore;
14use super::observe::{
15 ModelMemo, ObserveRequest, ObserveStats, observe_session, open_session_index,
16};
17use super::promote::PromotePolicy;
18use super::provenance::FieldAnswer;
19use super::{Field, FieldId, FieldStore};
20
21pub const DEFAULT_MODEL_MEMO_BYTES: u64 = 64 * 1024 * 1024;
23
24#[derive(Debug, Clone, Copy)]
26pub struct SessionOptions {
27 pub entropyfs: bool,
29 pub model_memo_bytes: u64,
31 pub promote: PromotePolicy,
33}
34
35impl Default for SessionOptions {
36 fn default() -> Self {
37 SessionOptions {
38 entropyfs: false,
39 model_memo_bytes: DEFAULT_MODEL_MEMO_BYTES,
40 promote: PromotePolicy::default(),
41 }
42 }
43}
44
45pub struct DocumentFieldSession {
55 store: FieldStore,
56 field: Field,
57 field_id: FieldId,
58 index: FsIndexStore,
61 models: ModelMemo,
62 pending_open_io: Option<IoSnapshot>,
65}
66
67impl DocumentFieldSession {
68 pub fn open(store_dir: &Path, field_hex: &str, opts: SessionOptions) -> Result<Self> {
72 let mut store = if opts.entropyfs {
73 #[cfg(feature = "entropyfs-store")]
74 {
75 FieldStore::open_entropyfs(store_dir)?
76 }
77 #[cfg(not(feature = "entropyfs-store"))]
78 {
79 return Err(Error::unsupported_feature(
80 "--entropyfs requires a build with the entropyfs-store feature",
81 ));
82 }
83 } else {
84 FieldStore::open(store_dir)?
85 };
86 store.set_promote(opts.promote);
87 let field_id = FieldId::from_hex(field_hex)?;
88 let field = Field::open(&store, &field_id, Limits::DEFAULT)?;
89 let open_io = field.open_io();
90 let index = open_session_index(&store)?;
92 Ok(Self {
93 store,
94 field,
95 field_id,
96 index,
97 models: ModelMemo::with_budget(opts.model_memo_bytes),
98 pending_open_io: Some(open_io),
99 })
100 }
101
102 pub fn field_id(&self) -> FieldId {
104 self.field_id
105 }
106
107 pub fn observe(
110 &mut self,
111 req: &ObserveRequest,
112 limits: Limits,
113 ) -> Result<(FieldAnswer, ObserveStats, FieldId)> {
114 let open_io = self.pending_open_io.take().unwrap_or_default();
115 observe_session(
116 &mut self.store,
117 &self.field,
118 &self.index,
119 open_io,
120 req,
121 limits,
122 self.models.clone(),
123 )
124 }
125
126 pub fn observe_batch(
128 &mut self,
129 reqs: &[ObserveRequest],
130 limits: Limits,
131 ) -> Vec<Result<(FieldAnswer, ObserveStats, FieldId)>> {
132 reqs.iter().map(|r| self.observe(r, limits)).collect()
133 }
134
135 pub fn sync(&self) -> Result<()> {
137 self.store.sync()
138 }
139}