Skip to content

Commit ba6da6b

Browse files
authored
Merge pull request #119 from vectorlessflow/dev
Dev
2 parents 39a2086 + e0a76d5 commit ba6da6b

59 files changed

Lines changed: 4245 additions & 2138 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Cargo.toml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ members = [
44
"crates/vectorless-document",
55
"crates/vectorless-config",
66
"crates/vectorless-utils",
7-
"crates/vectorless-scoring",
87
"crates/vectorless-graph",
98
"crates/vectorless-events",
109
"crates/vectorless-metrics",
@@ -18,7 +17,7 @@ members = [
1817
resolver = "2"
1918

2019
[workspace.package]
21-
version = "0.1.12"
20+
version = "0.1.13"
2221
description = "Knowing by reasoning, not vectors."
2322
edition = "2024"
2423
authors = ["zTgx <beautifularea@gmail.com>"]
@@ -32,7 +31,6 @@ documentation = "https://docs.rs/vectorless"
3231
tokio = { version = "1", features = ["full"] }
3332
async-trait = "0.1"
3433
futures = "0.3"
35-
3634
# Serialization
3735
serde = { version = "1.0", features = ["derive"] }
3836
serde_json = "1.0"

crates/vectorless-compiler/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ vectorless-document = { path = "../vectorless-document" }
1414
vectorless-error = { path = "../vectorless-error" }
1515
vectorless-llm = { path = "../vectorless-llm" }
1616
vectorless-metrics = { path = "../vectorless-metrics" }
17-
vectorless-scoring = { path = "../vectorless-scoring" }
1817
vectorless-storage = { path = "../vectorless-storage" }
1918
vectorless-utils = { path = "../vectorless-utils" }
2019
tokio = { workspace = true }

crates/vectorless-compiler/src/incremental/detector.rs

Lines changed: 20 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
//! enabling precise identification of changed nodes without full reprocessing.
88
99
use std::collections::HashMap;
10-
use std::hash::{Hash, Hasher};
1110
use std::path::Path;
1211
use std::time::SystemTime;
1312

@@ -208,17 +207,10 @@ impl ChangeDetector {
208207
self
209208
}
210209

211-
/// Compute hash of content (simple u64 hash).
212-
fn hash_content(content: &str) -> u64 {
213-
let mut hasher = std::collections::hash_map::DefaultHasher::new();
214-
content.hash(&mut hasher);
215-
hasher.finish()
216-
}
217-
218-
/// Check if a file needs reindexing based on mtime.
219-
pub fn needs_reindex_by_mtime(&self, doc_id: &str, path: &Path) -> bool {
210+
/// Check if a file needs recompilation based on mtime.
211+
pub fn needs_recompile_by_mtime(&self, doc_id: &str, path: &Path) -> bool {
220212
let Some(recorded_mtime) = self.mtimes.get(doc_id) else {
221-
return true; // Never indexed
213+
return true; // Never compiled
222214
};
223215

224216
let Ok(metadata) = std::fs::metadata(path) else {
@@ -232,8 +224,8 @@ impl ChangeDetector {
232224
current_mtime > *recorded_mtime
233225
}
234226

235-
/// Check if content needs reindexing based on fingerprint.
236-
pub fn needs_reindex_by_hash(&self, doc_id: &str, content: &str) -> bool {
227+
/// Check if content needs recompilation based on fingerprint.
228+
pub fn needs_recompile_by_hash(&self, doc_id: &str, content: &str) -> bool {
237229
let current_fp = Fingerprint::from_str(content);
238230

239231
match self.content_fps.get(doc_id) {
@@ -242,23 +234,23 @@ impl ChangeDetector {
242234
}
243235
}
244236

245-
/// Check if document needs reindexing based on fingerprint.
246-
pub fn needs_reindex_by_fingerprint(&self, doc_id: &str, new_fp: &Fingerprint) -> bool {
237+
/// Check if document needs recompilation based on fingerprint.
238+
pub fn needs_recompile_by_fingerprint(&self, doc_id: &str, new_fp: &Fingerprint) -> bool {
247239
match self.content_fps.get(doc_id) {
248240
Some(recorded_fp) => recorded_fp != new_fp,
249241
None => true,
250242
}
251243
}
252244

253245
/// Check if processing version has changed.
254-
pub fn needs_reindex_by_version(&self, doc_id: &str) -> bool {
246+
pub fn needs_recompile_by_version(&self, doc_id: &str) -> bool {
255247
match self.processing_versions.get(doc_id) {
256248
Some(recorded_version) => *recorded_version < self.current_processing_version,
257249
None => true,
258250
}
259251
}
260252

261-
/// Record document state after indexing.
253+
/// Record document state after compiling.
262254
pub fn record(&mut self, doc_id: &str, content: &str, path: Option<&Path>) {
263255
self.record_with_tree(doc_id, content, None, path);
264256
}
@@ -415,7 +407,7 @@ impl ChangeDetector {
415407
let mut needs_reprocess = Vec::new();
416408

417409
// If processing version changed, all nodes need reprocessing
418-
if self.needs_reindex_by_version(doc_id) {
410+
if self.needs_recompile_by_version(doc_id) {
419411
return Some(new_fps.keys().cloned().collect());
420412
}
421413

@@ -501,20 +493,6 @@ pub fn compute_tree_fingerprint(tree: &DocumentTree) -> Fingerprint {
501493
root_fp.subtree
502494
}
503495

504-
/// Compute content fingerprint for a single node.
505-
fn compute_node_content_fp(tree: &DocumentTree, node_id: NodeId) -> Fingerprint {
506-
let node = match tree.get(node_id) {
507-
Some(n) => n,
508-
None => return Fingerprint::zero(),
509-
};
510-
511-
Fingerprinter::new()
512-
.with_str(&node.title)
513-
.with_str(&node.content)
514-
.with_option_str(node.node_id.as_deref())
515-
.into_fingerprint()
516-
}
517-
518496
/// Compute fingerprint for a node and its subtree.
519497
fn compute_node_fingerprint(tree: &DocumentTree, node_id: NodeId) -> NodeFingerprint {
520498
let node = match tree.get(node_id) {
@@ -578,20 +556,20 @@ mod tests {
578556
}
579557

580558
#[test]
581-
fn test_needs_reindex_by_hash() {
559+
fn test_needs_recompile_by_hash() {
582560
let mut detector = ChangeDetector::new();
583561

584-
// First time: always needs reindex
585-
assert!(detector.needs_reindex_by_hash("doc1", "content"));
562+
// First time: always needs recompilation
563+
assert!(detector.needs_recompile_by_hash("doc1", "content"));
586564

587565
// Record the content
588566
detector.record("doc1", "content", None);
589567

590-
// Same content: no reindex needed
591-
assert!(!detector.needs_reindex_by_hash("doc1", "content"));
568+
// Same content: no recompilation needed
569+
assert!(!detector.needs_recompile_by_hash("doc1", "content"));
592570

593-
// Different content: needs reindex
594-
assert!(detector.needs_reindex_by_hash("doc1", "new content"));
571+
// Different content: needs recompilation
572+
assert!(detector.needs_recompile_by_hash("doc1", "new content"));
595573
}
596574

597575
#[test]
@@ -614,12 +592,12 @@ mod tests {
614592
let mut detector = ChangeDetector::new().with_processing_version(2);
615593
detector.record("doc1", "content", None);
616594

617-
// Version matches, no reindex needed
618-
assert!(!detector.needs_reindex_by_version("doc1"));
595+
// Version matches, no recompilation needed
596+
assert!(!detector.needs_recompile_by_version("doc1"));
619597

620598
// Create new detector with higher version
621599
let detector2 = ChangeDetector::new().with_processing_version(3);
622-
assert!(detector2.needs_reindex_by_version("doc1"));
600+
assert!(detector2.needs_recompile_by_version("doc1"));
623601
}
624602

625603
#[test]

crates/vectorless-compiler/src/incremental/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
1717
mod detector;
1818
mod resolver;
19-
mod updater;
2019

2120
pub use detector::ChangeDetector;
2221
pub use resolver::{IndexAction, SkipInfo, resolve_action};

crates/vectorless-compiler/src/incremental/resolver.rs

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@
1111
use tracing::info;
1212

1313
use crate::config::PipelineOptions;
14-
use vectorless_document::DocumentFormat;
15-
use vectorless_document::DocumentTree;
16-
use vectorless_storage::PersistedDocument;
14+
use vectorless_document::{Document, DocumentFormat, DocumentTree};
1715
use vectorless_utils::fingerprint::Fingerprint;
1816

1917
/// Action to take for a source during indexing.
@@ -64,42 +62,55 @@ pub struct SkipInfo {
6462
/// with the old tree for partial reprocessing.
6563
pub fn resolve_action(
6664
file_bytes: &[u8],
67-
stored_doc: &PersistedDocument,
65+
stored_doc: &Document,
6866
pipeline_options: &PipelineOptions,
6967
format: DocumentFormat,
7068
) -> IndexAction {
7169
let current_fp = Fingerprint::from_bytes(file_bytes);
70+
let current_fp_hex = current_fp.to_string();
71+
72+
// Get the stored DocumentMeta (if present)
73+
let stored_meta = match stored_doc.meta.as_ref() {
74+
Some(m) => m,
75+
None => {
76+
// No meta → must be a very old format, full reprocess
77+
return IndexAction::FullIndex {
78+
existing_id: Some(stored_doc.doc_id.clone()),
79+
};
80+
}
81+
};
7282

7383
// Layer 1: File-level content fingerprint
74-
if !stored_doc
75-
.meta
76-
.needs_reprocessing(&current_fp, pipeline_options.processing_version)
77-
{
84+
if !stored_meta.needs_reprocessing(&current_fp_hex, pipeline_options.processing_version) {
7885
info!("File fingerprint unchanged, skipping");
7986
return IndexAction::Skip(SkipInfo {
80-
doc_id: stored_doc.meta.id.clone(),
81-
name: stored_doc.meta.name.clone(),
87+
doc_id: stored_doc.doc_id.clone(),
88+
name: stored_doc.name.clone(),
8289
format,
83-
description: stored_doc.meta.description.clone(),
84-
page_count: stored_doc.meta.page_count,
90+
description: if stored_doc.summary.is_empty() {
91+
None
92+
} else {
93+
Some(stored_doc.summary.clone())
94+
},
95+
page_count: stored_doc.page_count,
8596
});
8697
}
8798

8899
// Layer 2: Logic fingerprint (pipeline config changed?)
89100
let current_logic_fp = pipeline_options.logic_fingerprint();
90-
if stored_doc.meta.logic_fingerprint != current_logic_fp
91-
&& !stored_doc.meta.logic_fingerprint.is_zero()
101+
if stored_meta.logic_fingerprint != current_logic_fp.to_string()
102+
&& !stored_meta.logic_fingerprint.is_empty()
92103
{
93104
info!("Logic fingerprint changed, full reprocess required");
94105
return IndexAction::FullIndex {
95-
existing_id: Some(stored_doc.meta.id.clone()),
106+
existing_id: Some(stored_doc.doc_id.clone()),
96107
};
97108
}
98109

99110
// Layer 3: Content changed, pipeline unchanged → incremental update
100111
info!("Content changed, pipeline unchanged → incremental update");
101112
IndexAction::IncrementalUpdate {
102113
old_tree: stored_doc.tree.clone(),
103-
existing_id: stored_doc.meta.id.clone(),
114+
existing_id: stored_doc.doc_id.clone(),
104115
}
105116
}

0 commit comments

Comments
 (0)