Skip to content

Commit 94c774e

Browse files
committed
optimize CreateBackupAction cache_previous_chunks_for_fixed_auto prettychunk querying
1 parent 7d38021 commit 94c774e

2 files changed

Lines changed: 47 additions & 4 deletions

File tree

prime_backup/action/create_backup_action.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ def __cache_previous_chunks_for_fixed_auto(self, session: DbSession, scan_result
227227
):
228228
return
229229

230+
wanted_file_blobs: List[Tuple[Path, int]] = [] # list of (file path, blob id)
230231
for file_entry in scan_result.all_files:
231232
if not file_entry.is_file() or file_entry.path in self.__pre_calc_result.reused_files:
232233
continue
@@ -243,11 +244,15 @@ def __cache_previous_chunks_for_fixed_auto(self, session: DbSession, scan_result
243244
):
244245
continue
245246

247+
blob_id = previous_file.blob_id
248+
assert blob_id is not None
249+
wanted_file_blobs.append((file_entry.path, blob_id))
250+
251+
if len(wanted_file_blobs) > 0:
246252
with self.__time_costs.measure_time_cost(CreateBackupTimeCostKey.kind_db):
247-
previous_file_chunks[file_entry.path] = [
248-
PrettyChunk(offset_chunk.offset, offset_chunk.chunk.raw_size, offset_chunk.chunk.hash)
249-
for offset_chunk in session.get_blob_chunks(previous_file.blob_id)
250-
]
253+
chunks_by_blob_id = session.batch_get_blob_pretty_chunks([blob_id for _, blob_id in wanted_file_blobs])
254+
for file_path, blob_id in wanted_file_blobs:
255+
previous_file_chunks[file_path] = chunks_by_blob_id[blob_id]
251256

252257
@classmethod
253258
def _pre_calculate_hash_worker(

prime_backup/db/session.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
if TYPE_CHECKING:
2323
from sqlalchemy.sql.type_api import TypeEngine
24+
from prime_backup.types.chunker import PrettyChunk
2425

2526

2627
_T = TypeVar('_T')
@@ -1097,6 +1098,43 @@ def get_blob_chunks(self, blob_id: int, *, limit: Optional[int] = None) -> List[
10971098
result: Sequence[Row[Tuple[int, schema.Chunk]]] = self.session.execute(stmt).all()
10981099
return [OffsetChunk(offset, chunk) for offset, chunk in result]
10991100

1101+
def batch_get_blob_pretty_chunks(self, blob_ids: List[int]) -> Dict[int, List['PrettyChunk']]:
1102+
"""
1103+
The result contains all given blob ids. Chunk lists are sorted.
1104+
"""
1105+
from prime_backup.types.chunker import PrettyChunk
1106+
1107+
blob_ids = collection_utils.deduplicated_list(blob_ids)
1108+
result: Dict[int, List['PrettyChunk']] = {blob_id: [] for blob_id in blob_ids}
1109+
if len(blob_ids) == 0:
1110+
return result
1111+
1112+
absolute_offset = (schema.BlobChunkGroupBinding.chunk_group_offset + schema.ChunkGroupChunkBinding.chunk_offset).label('absolute_offset')
1113+
for view in collection_utils.slicing_iterate(blob_ids, self.__safe_var_limit):
1114+
stmt = (
1115+
select(
1116+
schema.BlobChunkGroupBinding.blob_id,
1117+
absolute_offset,
1118+
schema.Chunk.raw_size,
1119+
schema.Chunk.hash,
1120+
).
1121+
select_from(schema.BlobChunkGroupBinding).
1122+
join(
1123+
schema.ChunkGroupChunkBinding,
1124+
schema.BlobChunkGroupBinding.chunk_group_id == schema.ChunkGroupChunkBinding.chunk_group_id
1125+
).
1126+
join(
1127+
schema.Chunk,
1128+
schema.ChunkGroupChunkBinding.chunk_id == schema.Chunk.id
1129+
).
1130+
where(schema.BlobChunkGroupBinding.blob_id.in_(view)).
1131+
order_by(schema.BlobChunkGroupBinding.blob_id, absolute_offset)
1132+
)
1133+
rows: Sequence[Row[Tuple[int, int, int, str]]] = self.session.execute(stmt).all()
1134+
for blob_id, offset, raw_size, chunk_hash in rows:
1135+
result[blob_id].append(PrettyChunk(offset, raw_size, chunk_hash))
1136+
return result
1137+
11001138
@dataclasses.dataclass(frozen=True)
11011139
class ListBlobChunkGroupBindingsItem:
11021140
binding: schema.BlobChunkGroupBinding

0 commit comments

Comments
 (0)