优化 LanceDB 存储:compact 碎片整理 + prune 旧版本清理 # 功能 1. **Compact**: 物理合并且删除已标记为删除的行,回收磁盘空间 2. **Prune**: 清理旧的版本文件 # 何时调用 - `vectorize_directory()` 批量处理完成后自动调用 - 当 `pending_delete_count` 达到阈值时自动调用
(&self)
| 778 | /// - `vectorize_directory()` 批量处理完成后自动调用 |
| 779 | /// - 当 `pending_delete_count` 达到阈值时自动调用 |
| 780 | pub async fn optimize_lancedb(&self) -> anyhow::Result<()> { |
| 781 | info!("Starting LanceDB storage optimization (compact + prune)"); |
| 782 | |
| 783 | let table = self.connection.open_table(&self.table_name).execute().await |
| 784 | .map_err(|e| anyhow::anyhow!("Failed to open LanceDB table for optimization: {e}"))?; |
| 785 | |
| 786 | // ── Step 1: Compact ── |
| 787 | // 合并小文件碎片,物理删除被标记为已删除的行 |
| 788 | let compact_options = CompactionOptions { |
| 789 | target_rows_per_fragment: 1024 * 1024, // ~1M 行每文件 |
| 790 | max_rows_per_group: 1024, // 1K 行每组 |
| 791 | materialize_deletions: true, // 强制物理删除软删除的行 |
| 792 | materialize_deletions_threshold: 0.1, // 10% 删除阈值作为后备 |
| 793 | num_threads: 4, // 4 线程并行 |
| 794 | }; |
| 795 | |
| 796 | let _compact_stats = table |
| 797 | .optimize(OptimizeAction::Compact { |
| 798 | options: compact_options, |
| 799 | remap_options: None, |
| 800 | }) |
| 801 | .await |
| 802 | .map_err(|e| anyhow::anyhow!("LanceDB compact failed: {e}"))?; |
| 803 | |
| 804 | info!("LanceDB compact completed"); |
| 805 | |
| 806 | // ── Step 2: Prune ── |
| 807 | // 清理 compact 后遗留的旧版本文件 |
| 808 | let _prune_stats = table |
| 809 | .optimize(OptimizeAction::Prune { |
| 810 | older_than: TimeDelta::zero(), // 立即清理所有非最新版本 |
| 811 | delete_unverified: Some(false), // 安全:只删除已验证的版本 |
| 812 | }) |
| 813 | .await |
| 814 | .map_err(|e| anyhow::anyhow!("LanceDB prune failed: {e}"))?; |
| 815 | |
| 816 | info!("LanceDB prune completed"); |
| 817 | |
| 818 | // 重置 pending 删除计数 |
| 819 | self.pending_delete_count.store(0, Ordering::Relaxed); |
| 820 | |
| 821 | Ok(()) |
| 822 | } |
| 823 | |
| 824 | /// Search for code blocks using semantic search |
| 825 | pub async fn search(&self, query: &str, limit: usize) -> Result<Vec<SearchResult>, anyhow::Error> { |
no outgoing calls
no test coverage detected