索引流程
最後更新
watcher 如何偵測資料庫 inbox 中新增、修改與移除的檔案,並把它們轉成
file_data 資料列。輪詢與變更偵測
每個已載入的資料庫各自執行一個 watcher goroutine(
cmd/app/main.go 的 runWatcher),計時器間隔 10 秒。每次觸發時 filesystem.WalkFiles 遞迴讀取 inbox,並與前一次快照逐項比對:| 條件 | 判定 |
|---|---|
| 名稱不在快照中,或檔案/目錄類型不同 | 已變更 |
| 名稱、大小、修改時間皆相同 | 未變更,略過 |
| 名稱相同但大小或修改時間不同 | 已變更 |
| 名稱在快照中但磁碟上已不存在 | 已移除 |
子目錄一律會往下走訪,任意深度的檔案都會被索引。未變更的檔案不會重新讀取。
快照檔
每次走訪後,新的目錄樹(大小、修改時間、是否為目錄、子項目)會在背景 goroutine 寫入
<db>/record.json,並以 mutex 序列化。啟動時 watcher 會載入這份快照,因此 daemon 重啟後只會重新索引停機期間變動的檔案。沒有快照時,第一次觸發會索引所有檔案,並略過移除檢查。寫入變更的檔案
變更的檔案依副檔名分派給對應 parser(見支援的檔案格式),再由
databaseHandler.Upsert 在單一 transaction 內寫入:- 將該來源路徑所有有效資料列標記為
dismiss = TRUE。 - 每個新 chunk 依
(source, chunk)插入或更新,並設為dismiss = FALSE。
因此編輯後已不存在的 chunk 會維持 dismissed,讀取端也不會看到同一檔案新舊 chunk 混雜。
source 欄位存的是檔案在 inbox 內的絕對路徑。| 結果 | daemon.log 紀錄 |
|---|---|
| 已儲存 | saved kind=<type> path=<path> chunks=<n> |
| Parser 錯誤 | parser error=...;保留既有資料列 |
| 寫入錯誤 | store.Save error=... |
| 略過的類型 | 不寫入,除 changed 外無其他紀錄 |
解析失敗的檔案仍會以當下的大小與時間記進快照,要等檔案再次變動才會重試。
移除的檔案
上次走訪後消失的每個名稱,都由
databaseHandler.Dismiss 把該路徑所有有效資料列標記為 dismiss = TRUE。移除整個目錄時,快照中記錄在其下的所有檔案都會被 dismiss。資料列不會被實體刪除,所有搜尋查詢都會排除 dismissed 的資料列。