|
| 1 | +.. Copyright 2026-present Alibaba Inc. |
| 2 | +
|
| 3 | +.. Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | +.. you may not use this file except in compliance with the License. |
| 5 | +.. You may obtain a copy of the License at |
| 6 | +
|
| 7 | +.. http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | +
|
| 9 | +.. Unless required by applicable law or agreed to in writing, software |
| 10 | +.. distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | +.. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | +.. See the License for the specific language governing permissions and |
| 13 | +.. limitations under the License. |
| 14 | +
|
| 15 | +Manifest Entry Cache |
| 16 | +==================== |
| 17 | + |
| 18 | +Overview |
| 19 | +-------- |
| 20 | + |
| 21 | +Large tables may contain many manifest entries, while a scan may only need a |
| 22 | +small subset after bucket, partition, and statistics pruning. The snapshot live |
| 23 | +manifest entry cache reduces repeated manifest decoding cost for successive full |
| 24 | +scans that target the same bucket. |
| 25 | + |
| 26 | +The cache stores decoded and merged live manifest entries by table path, branch, |
| 27 | +and bucket for ``ScanMode::ALL``. Each cache value can retain several snapshot |
| 28 | +results for that bucket. Exact snapshot hits are served from the cache; cache |
| 29 | +misses rebuild the target snapshot bucket from the target snapshot's data |
| 30 | +manifests and store the rebuilt live entries. |
| 31 | + |
| 32 | +Request-specific filters are not stored in the cache. Partition, level, and |
| 33 | +predicate filters are still evaluated for each scan, so cached entries can be |
| 34 | +reused safely across different scan predicates for the same bucket. |
| 35 | + |
| 36 | +Configuration |
| 37 | +------------- |
| 38 | + |
| 39 | +Manifest entry caching reuses the cache instance provided by |
| 40 | +``ScanContextBuilder::WithCache()`` and stores bucket-scoped snapshot entries |
| 41 | +under |
| 42 | +``CacheKind::SNAPSHOT_LIVE_MANIFEST``: |
| 43 | + |
| 44 | +.. code-block:: cpp |
| 45 | +
|
| 46 | + auto cache = std::make_shared<LruCache>(128 * 1024 * 1024); |
| 47 | + ScanContextBuilder context_builder(table_path); |
| 48 | + PAIMON_ASSIGN_OR_RAISE( |
| 49 | + std::unique_ptr<ScanContext> scan_context, |
| 50 | + context_builder |
| 51 | + .WithCache(cache) |
| 52 | + .AddOption(Options::SCAN_MANIFEST_ENTRY_CACHE_MAX_SNAPSHOTS, "3") |
| 53 | + .Finish()); |
| 54 | +
|
| 55 | +Cache entries are scoped by table path, branch, and bucket, so they can be |
| 56 | +reused across newly created ``TableScan`` and ``FileStoreScan`` instances as |
| 57 | +long as they share the same cache object and scan the same bucket. |
| 58 | + |
| 59 | +``Options::SCAN_MANIFEST_ENTRY_CACHE_MAX_SNAPSHOTS`` controls how many snapshot |
| 60 | +results are retained in each table/branch/bucket cache value. Older snapshots in |
| 61 | +the same bucket are evicted first. The default value is ``0``, which disables |
| 62 | +the cache path. Set it to a positive value to enable the cache when |
| 63 | +``ScanContextBuilder::WithCache()`` is also configured. Physical cache eviction |
| 64 | +is still controlled by the configured ``Cache`` implementation, for example the |
| 65 | +capacity of ``LruCache``. |
| 66 | + |
| 67 | +If no cache is provided through ``ScanContextBuilder::WithCache()``, this |
| 68 | +optimization is skipped. The snapshot manifest entry cache shares the same |
| 69 | +``Cache`` interface with raw manifest and data-file footer caches, but it uses a |
| 70 | +dedicated ``CacheKind`` and a table/branch/bucket key instead of file byte |
| 71 | +ranges. |
| 72 | + |
| 73 | +Limitations |
| 74 | +----------- |
| 75 | + |
| 76 | +The cache is currently used only for ``ScanMode::ALL`` scans that can determine |
| 77 | +a single target bucket. It is skipped for scans without a bucket filter because |
| 78 | +reading or deserializing all buckets would be too expensive for selective |
| 79 | +queries. It is also skipped for row-range scans because row-range pruning is |
| 80 | +applied at manifest-meta level. |
| 81 | + |
| 82 | +Metrics |
| 83 | +------- |
| 84 | + |
| 85 | +The scan metrics expose existing counters for the last scan: |
| 86 | + |
| 87 | +- ``lastScannedManifests``: how many manifest files were loaded during this |
| 88 | + scan before manifest entry decoding. |
0 commit comments