core-contracts
core-contracts copied to clipboard
An optimizable point when operating nesting near-sdk::Collections
description
There is a common use pattern of near-sdk::Collections, like this:
example code from: https://github.com/near/core-contracts/blob/nft-simple/nft-simple/src/lib.rs
pub tokens_per_owner: LookupMap<AccountId, UnorderedSet<TokenId>>,
and corresponding operation code like this:
example code from: https://github.com/near/core-contracts/blob/nft-simple/nft-simple/src/internal.rs#75
pub(crate) fn internal_add_token_to_owner(
&mut self,
account_id: &AccountId,
token_id: &TokenId,
) {
let mut tokens_set = self
.tokens_per_owner
.get(account_id)
.unwrap_or_else(|| UnorderedSet::new(unique_prefix(account_id)));
tokens_set.insert(token_id);
self.tokens_per_owner.insert(account_id, &tokens_set);
}
We can see that, when we changed (modify/add/remove) the item of inner collection (UnorderedSet here), we still take two insert actions. One is to insert inner collection to reflect our goal, the other is to insert this inner collection back to outer collection.
Problem
Let's take the new and clear action of inner collection out of the table (cause they are rare to happen in common case, and can be handled seperately).
From the aspect of storage, we can easily tell that the second insert action is meaningless. Cause the inner collection itself, as a value of outer collection, is untouched.
Will this meanless insert action cause some unnecessary gas cost? After all, the read/write action of storage is one of main parts of gas consumption.
Possible solution
Is there any other code pattern we can use to directly operate the inner collection and leave the outer one untouched?