-
Notifications
You must be signed in to change notification settings - Fork 138
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce reverseInPlace
in Variable/Fixed size Array
#2626
Open
darkdrag00nv2
wants to merge
7
commits into
onflow:master
Choose a base branch
from
darkdrag00nv2:reverse_array
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
74ca799
Introduce reverse in Variable/Fixed size Array
darkdrag00nv2 db38baf
tab to whitespace in interpreter test case
darkdrag00nv2 78bab43
Improve naming by introducing local variables.
darkdrag00nv2 e68bcf4
Remove unnecessary slice allocation
darkdrag00nv2 64bf9c1
Return Void instead of VoidValue{}
darkdrag00nv2 6cff2d2
Make return type of Reverse a Value
darkdrag00nv2 5056603
declare a constant for 'reverse'
darkdrag00nv2 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please also add test cases where the elements are structs and resources?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, thanks for pointing it out.
When I added the test case for struct, it doesn't work.
I get
error: member test is used before it has been initialized
. So it seems like usingGet
andSet
messes up the struct members.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By adding transfer call, I was able to get it to work for struct.
It doesn't work for resource because after the first
Set
call, we end up with two resources at theleftIndex
which returns the error// error: two parents are captured for the slab
.I'll look further into how we swap resources atomically. Another option might be to just not support reverse for resource typed arrays. Most of the array functions do that already.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the problem is, structs and resources behave differently when "Transferred". Structs are copied, whereas references are just 'moved'. Here what you would want to do is, instead of
v.Get
, do av.Remove
, which will "remove" the value from the array. Then instead of setting (i.e:v.Set
), do av.Insert
, because by removing earlier, we literally remove the value from the array, hence the values are shifted by one index.Now one thing to note is that, because the remaining values are shifted by one index by removing, if you try to remove the first element (leftValue) first, and then try to remove the last element (rightElement), it will mess-up the indexing for the second/right value removal. (could get an array-out-of-bound error / or could end up removing the wrong value) because after the first removal, the size of the array is (n-1).
So, you'll have to swap the removals, to first remove from the rear-end (right index) first, and then remove from the front (the left index).
i.e:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also no need for an additional "Transfer" because
Remove
andInsert
already do a transfer underneath.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This feels too expensive to me; transfers here are not necessary, Why move stuff to stack and then move again to strange with totally new storageID and slab tree?
We are 100% sure that storage address will not change in this operation. Why not add
swap
toatree.Array
? @fxamacker can confirm, but I think this way, all array is read and written again.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought so as well and asked Bastian about adding support for
reverse
in atree on #2605 (comment). Didn't ask aboutswap
but that will work nicely as well.We can also think about adding it using
Remove
andInsert
and later optimizing it using support in atree.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alternatively, as it has been briefly discussed in issue #2605, maybe we could start with the function that returns a new array with entries reversed, which should be easy to implement. And then later add this as the "optimized" version which does the same in-place. So the functionality is there, if someone needs it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@SupunS Makes sense, opened up #2654 for copy-based reversal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point 👍 . I opened onflow/atree#326 to add
Array.Swap
.