55from pathlib import Path
66from typing import Any , Optional
77
8- from knowcode .storage .chunk_repository import InMemoryChunkRepository
8+ from knowcode .storage .chunk_repository import ChunkRepository , InMemoryChunkRepository
99from knowcode .indexing .chunker import Chunker
1010from knowcode .indexing .graph_builder import GraphBuilder
1111from knowcode .indexing .scanner import Scanner
@@ -26,7 +26,7 @@ class Indexer:
2626 def __init__ (
2727 self ,
2828 embedding_provider : EmbeddingProviderProtocol ,
29- chunk_repo : Optional [InMemoryChunkRepository ] = None ,
29+ chunk_repo : Optional [ChunkRepository ] = None ,
3030 vector_store : Optional [VectorStoreProtocol ] = None ,
3131 ) -> None :
3232 """Initialize an indexer with optional storage backends.
@@ -37,7 +37,7 @@ def __init__(
3737 vector_store: Optional vector store (defaults to FAISS-backed store).
3838 """
3939 self .embedding_provider = embedding_provider
40- self .chunk_repo = chunk_repo or InMemoryChunkRepository ()
40+ self .chunk_repo : ChunkRepository = chunk_repo or InMemoryChunkRepository ()
4141 self .vector_store = vector_store or VectorStore (dimension = embedding_provider .config .dimension )
4242 self .chunker = Chunker ()
4343 self .manifest : dict [str , Any ] = {}
@@ -93,34 +93,20 @@ def save(self, path: str | Path) -> None:
9393 Args:
9494 path: Directory path to write index files into.
9595 """
96+ import json
97+ import time
98+ from dataclasses import asdict
99+
96100 path = Path (path )
97101 path .mkdir (parents = True , exist_ok = True )
98-
102+
99103 # Save vector store
100104 self .vector_store .save (path / "vectors" )
101-
102- # Save chunk metadata (BM25 tokens and content)
103- import json
104- metadata = {
105- "schema_version" : self .SCHEMA_VERSION ,
106- "chunks" : [
107- {
108- "id" : c .id ,
109- "entity_id" : c .entity_id ,
110- "content" : c .content ,
111- "tokens" : c .tokens ,
112- "metadata" : c .metadata
113- }
114- for c in self .chunk_repo ._chunks .values ()
115- ]
116- }
117- with open (path / "chunks.json" , "w" ) as f :
118- json .dump (metadata , f )
119105
120- # Save index manifest for compatibility checks at query time.
121- from dataclasses import asdict
122- import time
106+ # Save chunk metadata via repository
107+ self .chunk_repo .save (path )
123108
109+ # Save index manifest for compatibility checks at query time.
124110 self .manifest = {
125111 "schema_version" : self .SCHEMA_VERSION ,
126112 "version" : 1 ,
@@ -160,22 +146,8 @@ def load(self, path: str | Path) -> None:
160146 "version" : self .LEGACY_MANIFEST_VERSION ,
161147 }
162148
163- # Load chunks
164- from knowcode .models import CodeChunk # type: ignore
165-
166- chunks_file = path / "chunks.json"
167- if chunks_file .exists ():
168- with open (chunks_file ) as f :
169- data = json .load (f )
170- if isinstance (data , dict ):
171- validated_chunks = self ._validate_and_migrate_chunks_payload (data )
172- chunk_entries = validated_chunks .get ("chunks" , [])
173- if isinstance (chunk_entries , list ):
174- for c_data in chunk_entries :
175- if not isinstance (c_data , dict ):
176- continue
177- chunk = CodeChunk (** c_data )
178- self .chunk_repo .add (chunk )
149+ # Load chunks via repository
150+ self .chunk_repo .load (path )
179151
180152 @classmethod
181153 def _validate_and_migrate_manifest (cls , manifest : dict [str , Any ]) -> dict [str , Any ]:
@@ -260,12 +232,13 @@ def remove_file(self, file_path: str | Path) -> None:
260232 file_path_str = str (Path (file_path ).resolve ())
261233 removed_ids = self .chunk_repo .remove_by_file (file_path_str )
262234 if removed_ids :
263- # Rebuild vector store with remaining chunks
264- remaining_chunks = list (self .chunk_repo ._chunks .values ())
265- self .vector_store .clear ()
266- for c in remaining_chunks :
267- if c .embedding :
268- self .vector_store .add (c .id , c .embedding )
235+ # Rebuild the vector store from remaining chunks if embeddings are available.
236+ remaining_chunks = self .chunk_repo .get_all ()
237+ if any (c .embedding for c in remaining_chunks ):
238+ self .vector_store .clear ()
239+ for c in remaining_chunks :
240+ if c .embedding :
241+ self .vector_store .add (c .id , c .embedding )
269242
270243 def index_file (self , file_path : str | Path ) -> int :
271244
0 commit comments