It appears in substrate this is O(n), but want to confirm since I believe
hashbrown just wipes control bytes, which appears O(1).
The problem I'm trying to solve is tracking a number of free calls (u16) an account gets per era.
Data structures are stored like:
type FreeCalls = u16; #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] pub struct Pallet<T>(_); /// To disable free calls, set this to `None` or leave it unitialized. #[pallet::storage] #[pallet::getter(fn free_calls_per_era)] pub type FreeCallsPerEra<T> = StorageValue<_, FreeCalls>; /// Stores how many calls a user has left for this era. /// /// `Some(n)` : user has n free calls left /// `Some(0)` : user has zero free calls left /// `None` : user has not used any free calls yet this era (so set it to FreeCallsPerEra) #[pallet::storage] #[pallet::getter(fn free_calls_left)] pub type FreeCallsLeft<T> = StorageMap<_, Blake2_128Concat, T::AccountId, FreeCalls, OptionQuery>;
As the comments in the above code explain, we can check the number of free calls an account has left by querying
None, they have
free_calls_per_era() calls left, and
Some(0) means they've used them all. To reset this, we
clear() the map, and we would do it every era.
Is there a better approach to this, or do we just deal with O(n)
clear() every era? Sure, the map value could be
(free_calls_left, era_index) and reset the free calls and current era when queried, but then we basically store every account forever until we prune it.