Remove extra data copy from several Rocks get() methods (#27693)
Several of the get() methods return a deserialized object (as opposed to a Vec<u8>) by first getting a byte array out of Rocks, and then using bincode::deserialize() to get the underlying type. However, deserialize() only requires a u8 slice, not an owned Vec<u8>. So, we can use get_pinned_cf() to reference memory owned by Rocks and avoid an unnecessary copy.
This commit is contained in:
parent
798975ffa5
commit
4e8e0cda7e
|
@ -386,6 +386,11 @@ impl Rocks {
|
||||||
Ok(opt)
|
Ok(opt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_pinned_cf(&self, cf: &ColumnFamily, key: &[u8]) -> Result<Option<DBPinnableSlice>> {
|
||||||
|
let opt = self.db.get_pinned_cf(cf, key)?;
|
||||||
|
Ok(opt)
|
||||||
|
}
|
||||||
|
|
||||||
fn put_cf(&self, cf: &ColumnFamily, key: &[u8], value: &[u8]) -> Result<()> {
|
fn put_cf(&self, cf: &ColumnFamily, key: &[u8], value: &[u8]) -> Result<()> {
|
||||||
self.db.put_cf(cf, key, value)?;
|
self.db.put_cf(cf, key, value)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -1017,9 +1022,11 @@ impl Database {
|
||||||
where
|
where
|
||||||
C: TypedColumn + ColumnName,
|
C: TypedColumn + ColumnName,
|
||||||
{
|
{
|
||||||
if let Some(serialized_value) = self.backend.get_cf(self.cf_handle::<C>(), &C::key(key))? {
|
if let Some(pinnable_slice) = self
|
||||||
let value = deserialize(&serialized_value)?;
|
.backend
|
||||||
|
.get_pinned_cf(self.cf_handle::<C>(), &C::key(key))?
|
||||||
|
{
|
||||||
|
let value = deserialize(pinnable_slice.as_ref())?;
|
||||||
Ok(Some(value))
|
Ok(Some(value))
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
|
@ -1287,9 +1294,8 @@ where
|
||||||
self.column_options.rocks_perf_sample_interval,
|
self.column_options.rocks_perf_sample_interval,
|
||||||
&self.read_perf_status,
|
&self.read_perf_status,
|
||||||
);
|
);
|
||||||
if let Some(serialized_value) = self.backend.get_cf(self.handle(), &C::key(key))? {
|
if let Some(pinnable_slice) = self.backend.get_pinned_cf(self.handle(), &C::key(key))? {
|
||||||
let value = deserialize(&serialized_value)?;
|
let value = deserialize(pinnable_slice.as_ref())?;
|
||||||
|
|
||||||
result = Ok(Some(value))
|
result = Ok(Some(value))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1356,7 +1362,7 @@ where
|
||||||
self.column_options.rocks_perf_sample_interval,
|
self.column_options.rocks_perf_sample_interval,
|
||||||
&self.read_perf_status,
|
&self.read_perf_status,
|
||||||
);
|
);
|
||||||
let result = self.backend.get_cf(self.handle(), &C::key(key));
|
let result = self.backend.get_pinned_cf(self.handle(), &C::key(key));
|
||||||
if let Some(op_start_instant) = is_perf_enabled {
|
if let Some(op_start_instant) = is_perf_enabled {
|
||||||
report_rocksdb_read_perf(
|
report_rocksdb_read_perf(
|
||||||
C::NAME,
|
C::NAME,
|
||||||
|
@ -1366,10 +1372,10 @@ where
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(serialized_value) = result? {
|
if let Some(pinnable_slice) = result? {
|
||||||
let value = match C::Type::decode(&serialized_value[..]) {
|
let value = match C::Type::decode(pinnable_slice.as_ref()) {
|
||||||
Ok(value) => value,
|
Ok(value) => value,
|
||||||
Err(_) => deserialize::<T>(&serialized_value)?.into(),
|
Err(_) => deserialize::<T>(pinnable_slice.as_ref())?.into(),
|
||||||
};
|
};
|
||||||
Ok(Some(value))
|
Ok(Some(value))
|
||||||
} else {
|
} else {
|
||||||
|
@ -1382,7 +1388,7 @@ where
|
||||||
self.column_options.rocks_perf_sample_interval,
|
self.column_options.rocks_perf_sample_interval,
|
||||||
&self.read_perf_status,
|
&self.read_perf_status,
|
||||||
);
|
);
|
||||||
let result = self.backend.get_cf(self.handle(), &C::key(key));
|
let result = self.backend.get_pinned_cf(self.handle(), &C::key(key));
|
||||||
if let Some(op_start_instant) = is_perf_enabled {
|
if let Some(op_start_instant) = is_perf_enabled {
|
||||||
report_rocksdb_read_perf(
|
report_rocksdb_read_perf(
|
||||||
C::NAME,
|
C::NAME,
|
||||||
|
@ -1392,8 +1398,8 @@ where
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(serialized_value) = result? {
|
if let Some(pinnable_slice) = result? {
|
||||||
Ok(Some(C::Type::decode(&serialized_value[..])?))
|
Ok(Some(C::Type::decode(pinnable_slice.as_ref())?))
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue