Skip to content

Commit 6b7c9b3

Browse files
committed
ChunkGrouper.create_chunk_groups only needs chunk group id for those existing chunks
so get_chunk_group_ids_by_hashes_opt
1 parent 50d97e6 commit 6b7c9b3

2 files changed

Lines changed: 31 additions & 9 deletions

File tree

prime_backup/action/helpers/chunk_grouper.py

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@
77
from prime_backup.constants import chunk_constants
88
from prime_backup.db import schema
99
from prime_backup.db.session import DbSession
10-
from prime_backup.utils import chunk_utils, collection_utils
10+
from prime_backup.utils import chunk_utils
1111
from prime_backup.utils.time_cost_stats import TimeCostStats
1212

13-
1413
_dummy_chunk_costs: TimeCostStats[CreateBackupTimeCostKey] = TimeCostStats()
1514

1615

@@ -81,30 +80,39 @@ def create_chunk_groups(self, blob: schema.Blob, blob_chunks: Dict[int, ChunkLik
8180

8281
# create new chunk groups
8382
with self.__time_costs.measure_time_cost(CreateBackupTimeCostKey.kind_db):
84-
known_chunk_groups = collection_utils.no_none_dict(self.session.get_chunk_groups_by_hashes([rcg.hash for rcg in raw_chunk_groups]))
83+
known_chunk_group_hash_to_id = self.session.get_chunk_group_ids_by_hashes_opt([rcg.hash for rcg in raw_chunk_groups])
84+
new_chunk_groups: List[schema.ChunkGroup] = []
8585
new_chunk_group_hashes: List[str] = []
8686
for cg_hash, cg_chunks in chunk_group_hashes_to_chunks.items():
87-
if cg_hash not in known_chunk_groups:
87+
if known_chunk_group_hash_to_id[cg_hash] is None:
8888
new_chunk_group = self.session.create_and_add_chunk_group(
8989
hash=cg_hash,
9090
chunk_count=len(cg_chunks),
9191
chunk_raw_size_sum=sum(chunk.raw_size for chunk in cg_chunks),
9292
chunk_stored_size_sum=sum({chunk.hash: chunk.stored_size for chunk in cg_chunks}.values()),
9393
)
94-
known_chunk_groups[cg_hash] = new_chunk_group
94+
new_chunk_groups.append(new_chunk_group)
9595
new_chunk_group_hashes.append(new_chunk_group.hash)
9696
if len(new_chunk_group_hashes) > 0:
9797
with self.__time_costs.measure_time_cost(CreateBackupTimeCostKey.kind_db):
9898
self.session.flush() # creates chunk_group.id
99+
known_chunk_group_hash_to_id.update({
100+
new_chunk_group.hash: new_chunk_group.id
101+
for new_chunk_group in new_chunk_groups
102+
})
103+
for cg_hash, cg_id in known_chunk_group_hash_to_id.items():
104+
if cg_id is None:
105+
raise AssertionError('chunk group id for hash {} still not exists'.format(cg_hash))
99106

100107
# create bindings for new chunk groups
101108
chunk_group_chunk_binding_rows: List[DbSession.CreateChunkGroupChunkBindingKwargs] = []
102109
for cg_hash in new_chunk_group_hashes:
103-
new_chunk_group = known_chunk_groups[cg_hash]
110+
chunk_group_id = known_chunk_group_hash_to_id[cg_hash]
111+
assert chunk_group_id is not None
104112
offset = 0
105113
for chunk in chunk_group_hashes_to_chunks[cg_hash]:
106114
chunk_group_chunk_binding_rows.append({
107-
'chunk_group_id': new_chunk_group.id,
115+
'chunk_group_id': chunk_group_id,
108116
'chunk_offset': offset,
109117
'chunk_id': chunk.id,
110118
})
@@ -113,11 +121,12 @@ def create_chunk_groups(self, blob: schema.Blob, blob_chunks: Dict[int, ChunkLik
113121

114122
# create binding for the blob
115123
for raw_chunk_group in raw_chunk_groups:
116-
db_chunk_group = known_chunk_groups[raw_chunk_group.hash]
124+
chunk_group_id = known_chunk_group_hash_to_id[raw_chunk_group.hash]
125+
assert chunk_group_id is not None
117126
self.session.create_and_add_blob_chunk_group_binding(
118127
blob_id=blob.id,
119128
chunk_group_offset=raw_chunk_group.offset,
120-
chunk_group_id=db_chunk_group.id,
129+
chunk_group_id=chunk_group_id,
121130
)
122131

123132
# end

prime_backup/db/session.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,19 @@ def get_chunk_groups_by_hashes(self, hashes: List[str]) -> Dict[str, Optional[sc
733733
result[chunk_group.hash] = chunk_group
734734
return result
735735

736+
def get_chunk_group_ids_by_hashes_opt(self, hashes: List[str]) -> Dict[str, Optional[int]]:
737+
"""
738+
:return: a dict, hash -> optional chunk group id. All given hashes are in the dict
739+
"""
740+
result: Dict[str, Optional[int]] = {h: None for h in hashes}
741+
for view in collection_utils.slicing_iterate(hashes, self.__safe_var_limit):
742+
for chunk_group_hash, chunk_group_id in self.session.execute(
743+
select(schema.ChunkGroup.hash, schema.ChunkGroup.id).
744+
where(schema.ChunkGroup.hash.in_(view))
745+
).all():
746+
result[chunk_group_hash] = chunk_group_id
747+
return result
748+
736749
def list_chunk_groups(self, limit: Optional[int] = None, offset: Optional[int] = None) -> List[schema.ChunkGroup]:
737750
s = select(schema.ChunkGroup)
738751
if limit is not None:

0 commit comments

Comments
 (0)