indexedlog: fix try_clone external key buffer handling

Summary:
In both cases (clone with or without dirty content), the external key buffers
used by indexes should be re-created, since mem_buf location has changed.

Reviewed By: DurhamG

Differential Revision: D19432657

fbshipit-source-id: fe6f76e7ccfd16ccd2f5c1d89866687a3503603e
This commit is contained in:
Jun Wu 2020-01-17 03:52:22 -08:00 committed by Facebook Github Bot
parent 85d7253edd
commit 733961456f
2 changed files with 22 additions and 17 deletions

View File

@ -346,23 +346,23 @@ impl Log {
let mem_buf = if copy_dirty {
self.mem_buf.clone()
} else {
let mem_buf = Box::pin(Vec::new());
{
// Update external key buffer of indexes to point to the new mem_buf.
let mem_buf: &Vec<u8> = &mem_buf;
let mem_buf: *const Vec<u8> = mem_buf as *const Vec<u8>;
let index_key_buf = Arc::new(ExternalKeyBuffer {
disk_buf: disk_buf.clone(),
disk_len: self.meta.primary_len,
mem_buf,
});
for index in indexes.iter_mut() {
index.key_buf = index_key_buf.clone();
}
}
mem_buf
Box::pin(Vec::new())
};
{
// Update external key buffer of indexes to point to the new mem_buf.
let mem_buf: &Vec<u8> = &mem_buf;
let mem_buf: *const Vec<u8> = mem_buf as *const Vec<u8>;
let index_key_buf = Arc::new(ExternalKeyBuffer {
disk_buf: disk_buf.clone(),
disk_len: self.meta.primary_len,
mem_buf,
});
for index in indexes.iter_mut() {
index.key_buf = index_key_buf.clone();
}
}
// Create the new Log.
let mut log = Log {
dir: self.dir.clone(),

View File

@ -1268,13 +1268,18 @@ fn test_clone() {
log.sync().unwrap();
log.append([b'b'; 10]).unwrap();
let log2 = log.try_clone().unwrap();
let mut log2 = log.try_clone().unwrap();
assert_eq!(log2.iter().collect::<Result<Vec<_>, _>>().unwrap().len(), 2);
assert_eq!(log2.lookup_range(0, ..).unwrap().count(), 2);
// Check the external key buffer works after clone.
log2.append(&[b'c'; 40960][..]).unwrap();
log2.append(&[b'd'; 40960][..]).unwrap();
let log2 = log.try_clone_without_dirty().unwrap();
let mut log2 = log.try_clone_without_dirty().unwrap();
assert_eq!(log2.iter().collect::<Result<Vec<_>, _>>().unwrap().len(), 1);
assert_eq!(log2.lookup_range(0, ..).unwrap().count(), 1);
log2.append(&[b'e'; 40960][..]).unwrap();
log2.append(&[b'f'; 40960][..]).unwrap();
}
}