Skip to content
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

Storage.Find returns items out of order #946

Closed
ixje opened this issue Jul 22, 2019 · 6 comments · Fixed by #950
Closed

Storage.Find returns items out of order #946

ixje opened this issue Jul 22, 2019 · 6 comments · Fixed by #950
Labels
discussion Initial issue state - proposed but not yet accepted enhancement Type - Changes that may affect performance, usability or add new features to existing modules.

Comments

@ixje
Copy link
Contributor

ixje commented Jul 22, 2019

Say we store the following values

Storage.Put(Storage.CurrentContext, "AA_1", "1");
Storage.Put(Storage.CurrentContext, "AA_2", "2");
Storage.Put(Storage.CurrentContext, "AA_3", "3");

The following code

Iterator<string, byte[]> si = Storage.Find(Storage.CurrentContext, "AA_");
Runtime.Notify("Starting");
while (si.Next())
{
   Runtime.Notify(si.Key);
}
Runtime.Notify("Done");

returns AA_1, AA_2, AA_3 as expected.

Now add a Storage_Get before the Find call, like so:

Storage.Get(Storage.CurrentContext, "AA_1");
Iterator<string, byte[]> si = Storage.Find(Storage.CurrentContext, "AA_");

and the iterator now returns: AA_2, AA_3, AA_1

This is caused by line 126 of

public IEnumerable<KeyValuePair<TKey, TValue>> Find(byte[] key_prefix = null)
{
lock (dictionary)
{
foreach (var pair in FindInternal(key_prefix ?? new byte[0]))
if (!dictionary.ContainsKey(pair.Key))
yield return pair;
foreach (var pair in dictionary)
if (pair.Value.State != TrackState.Deleted && (key_prefix == null || pair.Key.ToArray().Take(key_prefix.Length).SequenceEqual(key_prefix)))
yield return new KeyValuePair<TKey, TValue>(pair.Key, pair.Value.Item);
}
}

When the key is already found in its cache it actually skips it for the time being instead of immediate processing (checking if DELETED).

I think this is unexpected behaviour. I do not think that possible data caching needs to be taken into account by the smart contract programmer. Any opinions?

@lock9 lock9 added the discussion Initial issue state - proposed but not yet accepted label Jul 22, 2019
@shargon
Copy link
Member

shargon commented Jul 22, 2019

this could be a problem in other implementations (neo-python)

@vncoelho vncoelho changed the title [Discussion?] Storage.Find returns items out of order Storage.Find returns items out of order Jul 22, 2019
@vncoelho
Copy link
Member

@ixje, maybe it is as Shargon said, I will double check asap.

In general, I have been in seen in other communities that tags do not go in the tittle.
In this sense, It would be better to keep the tittle more clear.

@vncoelho
Copy link
Member

vncoelho commented Jul 22, 2019

I just double checked my output from the previous thread and it was out of order as you said, @ixje.

Should this be adjusted or modified for Neo2X, @shargon and @igormcoelho?
For Neo3 we are going to have a manager for that anyway, right?

In fact, sometime ago I remember this discussion with @igormcoelho.

@igormcoelho
Copy link
Contributor

Order should be fully deterministic, otherwise it's hard (or impossible) to reproduce the results.
I see two possibilities:

  1. preserve insertion order (must see how to do this with current caching)
  2. sort results, but we must see how this affects Find with thousand keys.

I prefer option (2), if feasible, because key order is not easy to track in MPT or other data structures. So, sorting becomes the simplest solution I can see, at possibly big performance costs.

@lock9
Copy link
Contributor

lock9 commented Jul 23, 2019

@igormcoelho I prefer option 2 too. Can't we store it ordered and just retrieve it? I think it makes more sense to sort it when we update it. What do you think?

@vncoelho vncoelho added the enhancement Type - Changes that may affect performance, usability or add new features to existing modules. label Jul 23, 2019
@shargon
Copy link
Member

shargon commented Jul 23, 2019

I prefer sorted

erikzhang added a commit that referenced this issue Jul 24, 2019
@erikzhang erikzhang mentioned this issue Jul 24, 2019
erikzhang added a commit that referenced this issue Jul 30, 2019
Thacryba pushed a commit to simplitech/neo that referenced this issue Feb 17, 2020
* reorg

* fix links
Tommo-L pushed a commit to Tommo-L/neo that referenced this issue Jun 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion Initial issue state - proposed but not yet accepted enhancement Type - Changes that may affect performance, usability or add new features to existing modules.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants