Redis Sorted Sets – Getting same rank for same scores



I’ve been using Redis extensively in a project in the last couple of weeks. And this post is on a small trick I had to resort to while using sorted sets. If you don’t already know, the rank of an element in a Redis sorted set is its index in the sorted order. And rank starts at 0.

Let’s create a sorted set of three members A, B, C with scores 40, 10 and 40.

redis.zadd 'myset', 40, 'A'
redis.zadd 'myset', 10, 'B'
redis.zadd 'myset', 40, 'C'

And when you do redis.zrange 'myset', 0, -1, you get ["B", "A", "C"] and you can see that B is ranked first (rank 0), followed by A (rank 1) and then C (rank 2). This can also be verified by calling zrank on each item.

redis.zrank 'myset', 'A'
=> 1
redis.zrank 'myset', 'B'
=> 0
redis.zrank 'myset', 'C'
=> 2

My use case required the same rank for same scores and this is how I made Redis do what I wanted:

  • I created a sorted set with the scores being the members themselves.

redis.zadd 'newset', 10, 10
redis.zadd 'newset', 40, 40

  • Then I saved the member-score mapping in a hash separately.

redis.hset 'myhash', 'A', 40
redis.hset 'myhash', 'B', 10
redis.hset 'myhash', 'C', 40

  • Now, when I need the rank of a member, I just need to look up the member’s score in the hash and find the rank of that score from the new sorted set.

r = redis.hget 'myhash', 'A'
=> "40"
redis.zrank 'newset', r
=> 1
r = redis.hget 'myhash', 'B'
=> "10"
redis.zrank 'newset', r
=> 0
r = redis.hget 'myhash', 'C'
=> "40"
redis.zrank 'newset', r
=> 1

That is, rank(A) and rank(C) are equal to rank(40) and rank(B) is equal to rank(10). This gives rank 1 for A and C and rank 0 for B which is exactly what I wanted. Yay!


2012 is here


In 2011,

  1. Made no resolutions and achieved none – pending resolutions from 2010 are still pending!
  2. Quit one job.
  3. Loved every moment of India’s World Cup win and mourned the England tour.
  4. Became a Ruby on Rails committer. Hell yeah.
  5. Spent too much time on Hacker News, Twitter and GitHub.
  6. Wrote all of four posts to make 2011 the most dormant year for the blog. Yet, this is its most popular year. Crazy, I know.

Happy New Year everyone!

GitHub Feed Filter


, , , , , , ,

There was a time when all was well with my GitHub News Feed. Then came this commit in Rails. For the next few days, the feed was absolutely useless. And it’s time to clean it up! 🙂

GitHub Feed Filter, available as a Google Chrome Extension and as a Greasemonkey User Script, reads through the visible feeds in the News Feed section and lists them in the page just like Your Repos or Watched Repos. Clicking on a repository will filter out your News Feed to only include feeds from that repository. This filtering can be further extended to show only the feeds for commits, comments or issues made in that repository.

Install and have fun!

Converting DBF to CSV


, , , , ,

I was searching for a tool to convert dbf files to csv files today. This post pretty much solved the problem. However, there was a small confusion!

There is dbfdump available from the shapelib package on Ubuntu. And then there is dbf_dump which is available when you install the libdbd-xbase-perl package (Credit: A commenter on the article linked above).

The dbfdump command is pretty simple as seen from the available options and then there is no option to make csv files which makes it useless for most cases. The perl based dbf_dump though is powerful; it allows us to specify the fields that we want to dump from the dbf files, the field separator etc.