sway icon indicating copy to clipboard operation
sway copied to clipboard

Cast `Vec` to `StorageVec`

Open bitzoic opened this issue 3 years ago • 5 comments

There is currently no relation between the Vec and StorageVec in the standard library. There should be a way to cast a Vec to a StorageVec and vice versa.

An example where this is needed would be passing a Vec to a function and then storing the given Vec. Or returning a stored StorageVec as a Vec to the SDK.

We should also consider the case of utility methods within Vec as described by #2014 and whether these should be duplicated in StorageVec or the end user should cast back and forth to perform certain operations.

bitzoic avatar Aug 01 '22 18:08 bitzoic

StorageVec is really just a StorageMap with a length and where the keys are 0, 1, 2, .... The only way a cast would work here is trough a method that simply copies the data from a StorageVec to a Vec or vice versa. For example, returning a StorageVec as Vec would first require that we read all the elements of the StorageVec and store them in a local Vec at the same indices. We then return the resulting Vec as we usually do (once this is supported of course). Is this what you have in mind?

mohammadfawaz avatar Aug 01 '22 19:08 mohammadfawaz

This is what I had in mind initially as I see developers needing to do this often. The only problem being that this could get quite expensive.

I bring this up as I have a need for this in my English Auction application. I have a Vec of token ids that I will need to store. I may also need something similar when implementing a strings library.

bitzoic avatar Aug 01 '22 20:08 bitzoic

Yeah this is going to be expensive. Now two things:

  • Storing the elements of Vec in a StorageVec is going to be as expensive as manually copying the elements one by one, and I don't think there's a way around that.
  • Returning a StorageVec to the SDK may be possible without having to go through Vec<T>. We could potentially return the storage keys themselves and have the SDK rebuild the StorageVec once its able to access storage slots. At least this moves the burden of reading from the contract to the SDK.

mohammadfawaz avatar Aug 03 '22 17:08 mohammadfawaz

The fact that it will be very expensive is pointing toward this not being used often.

adlerjohn avatar Aug 11 '22 13:08 adlerjohn

Bumping this issue, as we have some possible use cases while updating the Vec and StorageVec API's (issue #2014).

While the utility of sorting algorithm implementations for storage vectors are limited, it would be good to match API's between the memory and storage vectors. However, any algorithm that requires more than N reads or writes on a storage vector of length N could benefit from being converted into memory vectors first. So StorageVec::sort would ideally create a memory vector, load each value into the memory vector, sort them, then write them to storage.

This may be useful for the following:

  • sort
  • sort_unstable
  • split_off
  • split_at

(for more on the splits, see discussion here)

jtriley2p avatar Jan 31 '23 00:01 jtriley2p