Skip to content

Commit cf4f86d

Browse files
committed
optimize write_meta
1 parent 598326e commit cf4f86d

File tree

3 files changed

+25
-31
lines changed

3 files changed

+25
-31
lines changed

src/cas/fjall_store.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -221,29 +221,28 @@ impl MetaStore for FjallStore {
221221
block_hash: BlockID,
222222
data_len: usize,
223223
key_has_block: bool,
224-
) -> Result<bool, MetaError> {
224+
) -> Result<(bool, Block), MetaError> {
225225
let blocks = self.block_partition.clone();
226226
let paths = self.path_partition.clone();
227227

228228
let mut tx = self.keyspace.write_tx();
229-
let should_write = match tx.get(&blocks, block_hash) {
229+
let res = match tx.get(&blocks, block_hash) {
230230
Ok(Some(block_data)) => {
231231
// Block already exists
232232

233+
let mut block =
234+
Block::try_from(&*block_data).expect("Only valid blocks are stored");
235+
233236
// if the key already has this block, the block doesn't got more references
234237
// and we don't need to write it back.
235238
if !key_has_block {
236239
// bump refcount on the block
237-
let mut block =
238-
Block::try_from(&*block_data).expect("Only valid blocks are stored");
239-
240240
block.increment_refcount();
241241
// write block back
242242
// TODO: this could be done in an `update_and_fetch`
243243
tx.insert(&blocks, block_hash, block.to_vec());
244244
}
245-
246-
Ok(false)
245+
Ok((false, block))
247246
}
248247
Ok(None) => {
249248
let mut idx = 0;
@@ -267,12 +266,12 @@ impl MetaStore for FjallStore {
267266
let block = Block::new(data_len, block_hash[..idx].to_vec());
268267

269268
tx.insert(&blocks, block_hash, block.to_vec());
270-
Ok(true)
269+
Ok((true, block))
271270
}
272271
Err(e) => Err(MetaError::OtherDBError(e.to_string())),
273272
};
274273
self.commit_persist(tx)?;
275-
should_write
274+
res
276275
}
277276
}
278277

src/cas/fs.rs

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,6 @@ impl CasFS {
243243
Err(_) => None,
244244
};
245245
let old_obj_meta = Arc::new(old_obj_meta);
246-
let block_map = Arc::new(self.meta_store.get_block_tree()?);
247246

248247
let (tx, rx) = unbounded();
249248
let mut content_hash = Md5::new();
@@ -262,11 +261,11 @@ impl CasFS {
262261
self.metrics.bytes_received(bytes.len());
263262
}
264263
})
265-
.zip(stream::repeat((tx, block_map, old_obj_meta)))
264+
.zip(stream::repeat((tx, old_obj_meta)))
266265
.enumerate()
267266
.for_each_concurrent(
268267
5,
269-
|(idx, (maybe_chunk, (mut tx, block_map, old_obj_meta)))| async move {
268+
|(idx, (maybe_chunk, (mut tx, old_obj_meta)))| async move {
270269
if let Err(e) = maybe_chunk {
271270
if let Err(e) = tx
272271
.send(Err(std::io::Error::new(e.kind(), e.to_string())))
@@ -290,41 +289,33 @@ impl CasFS {
290289
false
291290
};
292291

293-
let should_write = self
294-
.meta_store
295-
.write_block(block_hash, data_len, key_has_block);
292+
let write_meta_result =
293+
self.meta_store
294+
.write_block(block_hash, data_len, key_has_block);
296295

297296
let mut pm = PendingMarker::new(self.metrics.clone());
298-
match should_write {
297+
298+
let block = match write_meta_result {
299299
Err(e) => {
300300
if let Err(e) = tx.send(Err(e.into())).await {
301301
error!("Could not send transaction error: {}", e);
302302
}
303303
return;
304304
}
305-
Ok(false) => {
305+
Ok((false, _)) => {
306306
pm.block_ignored();
307307
if let Err(e) = tx.send(Ok((idx, block_hash))).await {
308308
error!("Could not send block id: {}", e);
309309
}
310310
return;
311311
}
312-
Ok(true) => pm.block_pending(),
313-
};
314-
315-
// write the actual block
316-
// first load the block again from the DB
317-
let block = match block_map.get_block(&block_hash) {
318-
Ok(block) => block,
319-
Err(e) => {
320-
if let Err(e) = tx.send(Err(e.into())).await {
321-
pm.block_write_error();
322-
error!("Could not send db error: {}", e);
323-
}
324-
return;
312+
Ok((true, block)) => {
313+
pm.block_pending();
314+
block
325315
}
326316
};
327317

318+
// write the actual block to disk
328319
let block_path = block.disk_path(self.root.clone());
329320
if let Err(e) = async_fs::create_dir_all(block_path.parent().unwrap()).await {
330321
if let Err(e) = tx.send(Err(e)).await {

src/cas/meta_store.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ pub trait MetaStore: Send + Sync + Debug + 'static {
6666
// data_len is the length of the block data.
6767
// key_has_block is true if the coresponding key already has the block
6868
//
69+
// It returns a tuple of bool and Block:
70+
// - bool is true if the block is new, hence need to be written to the disk
71+
// - Block is the block object
72+
//
6973
// It should do at least the following:
7074
// - Check if the hash is present in the block map
7175
// - if exists and key_has_block is false: increment the refcount
@@ -81,7 +85,7 @@ pub trait MetaStore: Send + Sync + Debug + 'static {
8185
block_hash: BlockID,
8286
data_len: usize,
8387
key_has_block: bool,
84-
) -> Result<bool, MetaError>;
88+
) -> Result<(bool, Block), MetaError>;
8589
}
8690

8791
pub trait BaseMetaTree: Send + Sync {

0 commit comments

Comments
 (0)