Explorar el Código

Reduces the index's ref count type to 32-bits (#7975)

Brooks hace 2 meses
padre
commit
095746e8a6

+ 9 - 3
accounts-db/src/accounts_index.rs

@@ -35,7 +35,7 @@ use {
         ops::{Bound, Range, RangeBounds},
         path::PathBuf,
         sync::{
-            atomic::{AtomicBool, AtomicU64, AtomicUsize, Ordering},
+            atomic::{AtomicBool, AtomicU32, AtomicU64, AtomicUsize, Ordering},
             Arc, Mutex, RwLock,
         },
     },
@@ -71,8 +71,14 @@ pub const ACCOUNTS_INDEX_CONFIG_FOR_BENCHMARKS: AccountsIndexConfig = AccountsIn
 };
 pub type ScanResult<T> = Result<T, ScanError>;
 pub type SlotList<T> = Vec<(Slot, T)>;
-pub type RefCount = u64;
-pub type AtomicRefCount = AtomicU64;
+
+// The ref count cannot be higher than the total number of storages, and we should never have more
+// than 1 million storages. A 32-bit ref count should be *significantly* more than enough.
+// (We already effectively limit the number of storages to 2^32 since the storage ID type is a u32.)
+// The majority of accounts should only exist in one storage, so the most common ref count is '1'.
+// Heavily updated accounts should still have a ref count that is < 100.
+pub type RefCount = u32;
+pub type AtomicRefCount = AtomicU32;
 
 /// values returned from `insert_new_if_missing_into_primary_index()`
 #[derive(Default, Debug, PartialEq, Eq)]

+ 9 - 6
accounts-db/src/accounts_index/in_mem_accounts_index.rs

@@ -272,7 +272,10 @@ impl<T: IndexValue, U: DiskIndexValue + From<T> + Into<T>> InMemAccountsIndex<T,
                     Self::update_stat(&self.stats().load_disk_missing_count, 1);
                 }
             }
-            entry_disk
+            entry_disk.map(|(slot_list, ref_count)| {
+                // SAFETY: ref_count must've come from in-mem first, so converting back is safe.
+                (slot_list, ref_count as RefCount)
+            })
         })
     }
 
@@ -667,7 +670,7 @@ impl<T: IndexValue, U: DiskIndexValue + From<T> + Into<T>> InMemAccountsIndex<T,
     /// - If UpsertReclaim is ReclaimOldSlots, remove all uncached entries older than `slot`
     ///   and add them to reclaims
     ///
-    /// Returns the reference count change as an `i64`. The reference count change
+    /// Returns the reference count change as an `i32`. The reference count change
     /// is the number of entries added (1) - the number of uncached entries removed
     /// or replaced
     fn update_slot_list(
@@ -677,7 +680,7 @@ impl<T: IndexValue, U: DiskIndexValue + From<T> + Into<T>> InMemAccountsIndex<T,
         other_slot: Option<Slot>,
         reclaims: &mut SlotList<T>,
         reclaim: UpsertReclaim,
-    ) -> i64 {
+    ) -> i32 {
         let mut ref_count_change = 1;
 
         // Cached accounts are not expected by this function, use cache_entry_at_slot instead
@@ -1243,7 +1246,7 @@ impl<T: IndexValue, U: DiskIndexValue + From<T> + Into<T>> InMemAccountsIndex<T,
                                                 .iter()
                                                 .map(|(slot, info)| (*slot, (*info).into()))
                                                 .collect::<Vec<_>>(),
-                                            ref_count,
+                                            ref_count.into(), // ref count on disk is u64
                                         ),
                                     )
                                 };
@@ -1685,7 +1688,7 @@ mod tests {
                     expected.push((new_slot, info));
 
                     // Calculate the expected ref count change. It is expected to be 1 - the number of reclaims
-                    let expected_result = 1 - expected_reclaims.len() as i64;
+                    let expected_result = 1 - expected_reclaims.len() as i32;
                     assert_eq!(
                         expected_result, result,
                         "return value different. other: {other_slot:?}, {expected:?}, \
@@ -2088,7 +2091,7 @@ mod tests {
                     expected.push((new_slot, info));
 
                     // Calculate the expected ref count change. It is expected to be 1 - the number of reclaims
-                    let expected_result = 1 - expected_reclaims.len() as i64;
+                    let expected_result = 1 - expected_reclaims.len() as i32;
                     assert_eq!(
                         expected_result, result,
                         "return value different. other: {other_slot:?}, {expected:?}, \