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

zrange with scores gives confusing results when duplicate scores are present #85

Open
david-macmahon opened this issue Nov 1, 2021 · 4 comments

Comments

@david-macmahon
Copy link

When all the elements of a zset have unique scores, the OrderedCollections.OrderedSet returned by zrange(conn, zsetname, 0, n, :withscores) makes sense:

julia> zadd(r, "zsettest", 1, "one")
1

julia> zadd(r, "zsettest", 2, "two")
1

julia> zrange(r, "zsettest", 0, 1, :withscores)
OrderedCollections.OrderedSet{AbstractString} with 4 elements:
  "one"
  "1"
  "two"
  "2"

But when there are multiple entries with the same score, the duplicate scores are not duplicated in the returned OrderedCollections.OrderedSet (because it is a set after all):

julia> zadd(r, "zsettest", 1, "three")
1

julia> zrange(r, "zsettest", 0, 2, :withscores)
OrderedCollections.OrderedSet{AbstractString} with 5 elements:
  "one"
  "1"
  "three"
  "two"
  "2"

One way to fix this would be for the elements of the OrderedSet to be value => score or pairs or (value, score) tuples. I think that would allow the return type still to be OrderedSet while not creating ambiguity about which is value and which is score (e.g. when values and scores look alike), but it would definitely be a breaking change compared to the current (arguably broken) behavior. FWIW, this is what redis-cli returns:

$ redis-cli
127.0.0.1:6379> ZRANGE zsettest 0 2 withscores
1) "one"
2) "1"
3) "three"
4) "1"
5) "two"
6) "2"
@jkaye2012
Copy link
Collaborator

Yeah, withscores definitely makes OrderedSet{String} not the correct structure. I think it should probably be AbstractDict{String, Float64} or something. Should just be able to add the applicable overload to commands.jl and it should work it out. We already have a major version bump pending right now, so this is something we could get in there.

I haven't bumped it yet because I haven't really been using Julia for years now other than to maintain this lib. Would be happy to do so, though a PR would be ideal since I'm not so familiar with the ecosystem these days.

OrderedSet{String} I think is correct for all operations that don't use withscores, so this would only affect uses with that option.

@david-macmahon
Copy link
Author

I guess maybe OrderedDict would be the concrete type, but that would change the return type based on input options. Maybe an OrderedSet{Pair{AbstractString, Float64}} would be preferable since it's still an OrderedSet, but could be used to easily create a Dict or OrderedDict.

@jkaye2012
Copy link
Collaborator

jkaye2012 commented Nov 2, 2021 via email

@david-macmahon
Copy link
Author

Hmm, I'm not sure whether a return type of Union{OrderedSet{AbstractString}, OrderedDict{AbstractString,Float64}} is better/worse/same as OrderedSet{Union{AbstractString, Pair{AbstractString,Float64}} in terms of type stability. I guess the second way would more correctly be Union{OrderedSet{AbstractString}, OrderedSet{Pair{AbstractString,Float64}}} so yeah, I think your idea is better.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants