rebuild the files cache by reading previous archive from repository
(self)
| 465 | return self._files |
| 466 | |
| 467 | def _build_files_cache(self): |
| 468 | """rebuild the files cache by reading previous archive from repository""" |
| 469 | if "d" in self.cache_mode: # d(isabled) |
| 470 | return |
| 471 | |
| 472 | if not self.archive_name: |
| 473 | return |
| 474 | |
| 475 | from .archive import Archive |
| 476 | |
| 477 | # get the latest archive with the IDENTICAL name, supporting archive series: |
| 478 | try: |
| 479 | archives = self.manifest.archives.list(match=[self.archive_name], sort_by=["ts"], last=1) |
| 480 | except PermissionDenied: # maybe repo is in write-only mode? |
| 481 | archives = None |
| 482 | if not archives: |
| 483 | # nothing found |
| 484 | return |
| 485 | prev_archive = archives[0] |
| 486 | |
| 487 | files = {} |
| 488 | logger.debug( |
| 489 | f"Building files cache from {prev_archive.name} {prev_archive.ts} {bin_to_hex(prev_archive.id)} ..." |
| 490 | ) |
| 491 | files_cache_logger.debug("FILES-CACHE-BUILD: starting...") |
| 492 | archive = Archive(self.manifest, prev_archive.id) |
| 493 | for item in archive.iter_items(): |
| 494 | # only put regular files' infos into the files cache: |
| 495 | if stat.S_ISREG(item.mode): |
| 496 | path_hash = self.key.id_hash(safe_encode(item.path)) |
| 497 | # keep track of the key(s) for the most recent timestamp(s): |
| 498 | ctime_ns = item.ctime |
| 499 | if ctime_ns > self._newest_cmtime: |
| 500 | self._newest_cmtime = ctime_ns |
| 501 | self._newest_path_hashes = {path_hash} |
| 502 | elif ctime_ns == self._newest_cmtime: |
| 503 | self._newest_path_hashes.add(path_hash) |
| 504 | mtime_ns = item.mtime |
| 505 | if mtime_ns > self._newest_cmtime: |
| 506 | self._newest_cmtime = mtime_ns |
| 507 | self._newest_path_hashes = {path_hash} |
| 508 | elif mtime_ns == self._newest_cmtime: |
| 509 | self._newest_path_hashes.add(path_hash) |
| 510 | # add the file to the in-memory files cache |
| 511 | entry = FileCacheEntry( |
| 512 | age=0, |
| 513 | inode=item.get("inode", 0), |
| 514 | size=item.size, |
| 515 | ctime=int_to_timestamp(ctime_ns), |
| 516 | mtime=int_to_timestamp(mtime_ns), |
| 517 | chunks=item.chunks, |
| 518 | ) |
| 519 | # note: if the repo is an a valid state, next line should not fail with KeyError: |
| 520 | files[path_hash] = self.compress_entry(entry) |
| 521 | # deal with special snapshot / timestamp granularity case, see FAQ: |
| 522 | for path_hash in self._newest_path_hashes: |
| 523 | del files[path_hash] |
| 524 | files_cache_logger.debug("FILES-CACHE-BUILD: finished, %d entries loaded.", len(files)) |
no test coverage detected