josiahcarlson / redis-in-action

Example code from the book

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

questions about listing 2.9

KayWu opened this issue · comments

# listing 2.9
def update_token(conn, token, user, item=None):
    timestamp = time.time()
    conn.hset('login:', token, user)
    conn.zadd('recent:', token, timestamp)
    if item:
        conn.zadd('viewed:' + token, item, timestamp)
        conn.zremrangebyrank('viewed:' + token, 0, -26)
        conn.zincrby('viewed:', item, -1)

conn.zincrby('viewed:', item, -1) means more views will lead to a lower score.

# listing 2.10
def rescale_viewed(conn):
    while not QUIT:
        conn.zremrangebyrank('viewed:', 0, -20001)
        conn.zinterstore('viewed:', {'viewed:': .5})
        time.sleep(300)

conn.zremrangebyrank('viewed:', 0, -20001) will keep the last 20000 items,
The order is from small to big, so items with few views will get a high score and be kept.
Guess conn.zincrby('viewed:', item, 1) or conn.zremrangebyrank('viewed:', 20001, -1) will work.

I was going to say, "known errata, fixed years ago". Then I looked again.

Let's go through this piece by piece. Everything viewed gets ZINCRBY -1; so if something is seen 1000000 times, they will have a score of -1000000. If something is seen 10 times, it will have a score of -10. So the "highest viewed items" will be at index 0, and the lowest viewed items will be at index -1.

In listing 2.10, the old code (from before 2014-05-04) read:

def rescale_viewed(conn):
    while not QUIT:
        conn.zremrangebyrank('viewed:', 20000, -1)
        conn.zinterstore('viewed:', {'viewed:': .5})
        time.sleep(300)

Which deleted things at index 20k to -1, so items with the lowest actual views. On 2014.-05-04, I took a correction from someone, because apparently I wasn't reading my own code, and turned that into what you see above:

def rescale_viewed(conn):
    while not QUIT:
        conn.zremrangebyrank('viewed:', 0, -20001)
        conn.zinterstore('viewed:', {'viewed:': .5})
        time.sleep(300)

... which deletes everything except the least-used 20k items. You are right.

I'm going to switch the code back, update the errata, and get back to you. Thank you.

Thank you for the question!