(self)
| 154 | return missing_chunks, total_files, total_size, num_archives |
| 155 | |
| 156 | def report_and_delete(self): |
| 157 | if self.missing_chunks: |
| 158 | logger.error(f"Repository has {len(self.missing_chunks)} missing objects!") |
| 159 | for id in sorted(self.missing_chunks): |
| 160 | logger.debug(f"Missing object {bin_to_hex(id)}") |
| 161 | set_ec(EXIT_ERROR) |
| 162 | |
| 163 | logger.info("Cleaning archives directory from soft-deleted archives...") |
| 164 | archive_infos = self.manifest.archives.list(sort_by=["ts"], deleted=True) |
| 165 | for archive_info in archive_infos: |
| 166 | name, id, hex_id = archive_info.name, archive_info.id, bin_to_hex(archive_info.id) |
| 167 | try: |
| 168 | self.manifest.archives.nuke_by_id(id) |
| 169 | except self.repository.ObjectNotFound: |
| 170 | logger.warning(f"Soft-deleted archive {name} {hex_id} not found.") |
| 171 | |
| 172 | repo_size_before = self.repository_size |
| 173 | logger.info("Determining unused objects...") |
| 174 | unused = set() |
| 175 | for id, entry in self.chunks.iteritems(): |
| 176 | if not (entry.flags & ChunkIndex.F_USED): |
| 177 | unused.add(id) |
| 178 | logger.info(f"Deleting {len(unused)} unused objects...") |
| 179 | pi = ProgressIndicatorPercent( |
| 180 | total=len(unused), msg="Deleting unused objects %3.1f%%", step=0.1, msgid="compact.report_and_delete" |
| 181 | ) |
| 182 | for i, id in enumerate(unused): |
| 183 | pi.show(i) |
| 184 | self.repository.delete(id) |
| 185 | del self.chunks[id] |
| 186 | pi.finish() |
| 187 | repo_size_after = self.repository_size |
| 188 | |
| 189 | count = len(self.chunks) |
| 190 | logger.info(f"Overall statistics, considering all {self.archives_count} archives in this repository:") |
| 191 | logger.info( |
| 192 | f"Source data size was {format_file_size(self.total_size, precision=0, iec=self.iec)} " |
| 193 | f"in {self.total_files} files." |
| 194 | ) |
| 195 | if self.stats: |
| 196 | logger.info( |
| 197 | f"Repository size is {format_file_size(repo_size_after, precision=0, iec=self.iec)} " |
| 198 | f"in {count} objects." |
| 199 | ) |
| 200 | logger.info( |
| 201 | f"Compaction saved " |
| 202 | f"{format_file_size(repo_size_before - repo_size_after, precision=0, iec=self.iec)}." |
| 203 | ) |
| 204 | else: |
| 205 | logger.info(f"Repository has data stored in {count} objects.") |
| 206 | |
| 207 | |
| 208 | class CompactMixIn: |
no test coverage detected