| 114 | assert indirect_entry_struct.size == 9 |
| 115 | |
| 116 | def __init__(self, decrypted_repository): |
| 117 | self.decrypted_repository = decrypted_repository |
| 118 | # self.meta, the "meta-array" is a densely packed array of metadata about where items can be found. |
| 119 | # It is indexed by the inode number minus self.offset. (This is in a way eerily similar to how the first |
| 120 | # unices did this). |
| 121 | # The meta-array contains chunk IDs and item entries (described in iter_archive_items). |
| 122 | # The chunk IDs are referenced by item entries through relative offsets, |
| 123 | # which are bounded by the metadata chunk size. |
| 124 | self.meta = bytearray() |
| 125 | # The current write offset in self.meta |
| 126 | self.write_offset = 0 |
| 127 | |
| 128 | # Offset added to meta-indices, resulting in inodes, |
| 129 | # or subtracted from inodes, resulting in meta-indices. |
| 130 | # XXX: Merge FuseOperations.items and ItemCache to avoid |
| 131 | # this implicit limitation / hack (on the number of synthetic inodes, degenerate |
| 132 | # cases can inflate their number far beyond the number of archives). |
| 133 | self.offset = 1000000 |
| 134 | |
| 135 | # A temporary file that contains direct items, i.e. items directly cached in this layer. |
| 136 | # These are items that span more than one chunk and thus cannot be efficiently cached |
| 137 | # by the object cache (self.decrypted_repository), which would require variable-length structures; |
| 138 | # possible but not worth the effort, see iter_archive_items. |
| 139 | self.fd = tempfile.TemporaryFile(prefix="borg-tmp") |
| 140 | |
| 141 | # A small LRU cache for chunks requested by ItemCache.get() from the object cache, |
| 142 | # this significantly speeds up directory traversal and similar operations which |
| 143 | # tend to re-read the same chunks over and over. |
| 144 | # The capacity is kept low because increasing it does not provide any significant advantage, |
| 145 | # but makes LRUCache's square behaviour noticeable and consumes more memory. |
| 146 | self.chunks = LRUCache(capacity=10) |
| 147 | |
| 148 | # Instrumentation |
| 149 | # Count of indirect items, i.e. data is cached in the object cache, not directly in this cache |
| 150 | self.indirect_items = 0 |
| 151 | # Count of direct items, i.e. data is in self.fd |
| 152 | self.direct_items = 0 |
| 153 | |
| 154 | def get(self, inode): |
| 155 | offset = inode - self.offset |