Browse Source

blockstore: Defer multi_get_bytes() allocation to caller (#4674)

multi_get_bytes() currently returns owned memory (Vec<u8>). But, the
callers of multi_get_bytes() only require borrowed memory (&[u8]).

So, update multi_get_bytes() to return a reference to rocksdb owned
memory; the caller can copy to owned memory if they require it
steviez 9 months ago
parent
commit
c59d2c1eb2
1 changed files with 29 additions and 3 deletions
  1. 29 3
      ledger/src/blockstore_db.rs

+ 29 - 3
ledger/src/blockstore_db.rs

@@ -1422,6 +1422,33 @@ pub struct WriteBatch {
     write_batch: RWriteBatch,
     write_batch: RWriteBatch,
 }
 }
 
 
+pub(crate) struct BlockstoreByteReference<'a> {
+    slice: DBPinnableSlice<'a>,
+}
+
+impl<'a> From<DBPinnableSlice<'a>> for BlockstoreByteReference<'a> {
+    #[inline]
+    fn from(slice: DBPinnableSlice<'a>) -> Self {
+        Self { slice }
+    }
+}
+
+impl std::ops::Deref for BlockstoreByteReference<'_> {
+    type Target = [u8];
+
+    #[inline]
+    fn deref(&self) -> &[u8] {
+        &self.slice
+    }
+}
+
+impl AsRef<[u8]> for BlockstoreByteReference<'_> {
+    #[inline]
+    fn as_ref(&self) -> &[u8] {
+        self
+    }
+}
+
 impl WriteBatch {
 impl WriteBatch {
     fn put_cf<K: AsRef<[u8]>>(&mut self, cf: &ColumnFamily, key: K, value: &[u8]) -> Result<()> {
     fn put_cf<K: AsRef<[u8]>>(&mut self, cf: &ColumnFamily, key: K, value: &[u8]) -> Result<()> {
         self.write_batch.put_cf(cf, key, value);
         self.write_batch.put_cf(cf, key, value);
@@ -1476,7 +1503,7 @@ where
     pub(crate) fn multi_get_bytes<'a, K>(
     pub(crate) fn multi_get_bytes<'a, K>(
         &'a self,
         &'a self,
         keys: impl IntoIterator<Item = &'a K> + 'a,
         keys: impl IntoIterator<Item = &'a K> + 'a,
-    ) -> impl Iterator<Item = Result<Option<Vec<u8>>>> + 'a
+    ) -> impl Iterator<Item = Result<Option<BlockstoreByteReference<'a>>>> + 'a
     where
     where
         K: AsRef<[u8]> + 'a + ?Sized,
         K: AsRef<[u8]> + 'a + ?Sized,
     {
     {
@@ -1488,10 +1515,9 @@ where
         let result = self
         let result = self
             .backend
             .backend
             .multi_get_cf(self.handle(), keys)
             .multi_get_cf(self.handle(), keys)
-            .map(|out| Ok(out?.as_deref().map(<[u8]>::to_vec)));
+            .map(|out| Ok(out?.map(BlockstoreByteReference::from)));
 
 
         if let Some(op_start_instant) = is_perf_enabled {
         if let Some(op_start_instant) = is_perf_enabled {
-            // use multi-get instead
             report_rocksdb_read_perf(
             report_rocksdb_read_perf(
                 C::NAME,
                 C::NAME,
                 PERF_METRIC_OP_NAME_MULTI_GET,
                 PERF_METRIC_OP_NAME_MULTI_GET,