Universal scan: reads from the correct engine for `collection` and returns `(doc_id, msgpack_bytes)` pairs in standard msgpack map format. Routing order: 1. KV engine (if collection has KV entries) 2. Columnar storage (timeseries memtable or plain/spatial engine) 3. Sparse/document engine (default) All results are normalized to standard msgpack maps so callers (aggregate, join, sort, filter) nev
(
&self,
tid: u64,
collection: &str,
limit: usize,
)
| 27 | /// All results are normalized to standard msgpack maps so callers |
| 28 | /// (aggregate, join, sort, filter) never need engine-specific code. |
| 29 | pub fn scan_collection( |
| 30 | &self, |
| 31 | tid: u64, |
| 32 | collection: &str, |
| 33 | limit: usize, |
| 34 | ) -> crate::Result<Vec<(String, Vec<u8>)>> { |
| 35 | // 1. KV engine |
| 36 | let kv_docs = self.scan_kv(tid, collection, limit); |
| 37 | if !kv_docs.is_empty() { |
| 38 | return Ok(kv_docs); |
| 39 | } |
| 40 | |
| 41 | // 2. Columnar memtable |
| 42 | let col_docs = self.scan_columnar(tid, collection, limit); |
| 43 | if !col_docs.is_empty() { |
| 44 | return Ok(col_docs); |
| 45 | } |
| 46 | |
| 47 | // 3. Sparse/document engine (schemaless + strict) |
| 48 | self.scan_sparse(tid, collection, limit) |
| 49 | } |
| 50 | |
| 51 | /// Scan KV engine entries → standard msgpack. |
| 52 | /// Injects the `key` field directly into the msgpack map — no JSON roundtrip. |