From cf1579a798f3dbc6274b2d0b662e3254465707fb Mon Sep 17 00:00:00 2001 From: antirez Date: Fri, 12 Jul 2013 12:02:36 +0200 Subject: [PATCH] SORT ALPHA: use collation instead of binary comparison. Note that we only do it when STORE is not used, otherwise we want an absolutely locale independent and binary safe sorting in order to ensure AOF / replication consistency. This is probably an unexpected behavior violating the least surprise rule, but there is currently no other simple / good alternative. --- src/redis.h | 1 + src/sort.c | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/redis.h b/src/redis.h index 0fb8e3028..b067fdf45 100644 --- a/src/redis.h +++ b/src/redis.h @@ -891,6 +891,7 @@ struct redisServer { int sort_desc; int sort_alpha; int sort_bypattern; + int sort_store; /* Zip structure config, see redis.conf for more information */ size_t hash_max_ziplist_entries; size_t hash_max_ziplist_value; diff --git a/src/sort.c b/src/sort.c index 4b5040250..a4b062645 100644 --- a/src/sort.c +++ b/src/sort.c @@ -163,12 +163,22 @@ int sortCompare(const void *s1, const void *s2) { else cmp = 1; } else { - /* We have both the objects, use strcoll */ - cmp = strcoll(so1->u.cmpobj->ptr,so2->u.cmpobj->ptr); + /* We have both the objects, compare them. */ + if (server.sort_store) { + cmp = compareStringObjects(so1->u.cmpobj,so2->u.cmpobj); + } else { + /* Here we can use strcoll() directly as we are sure that + * the objects are decoded string objects. */ + cmp = strcoll(so1->u.cmpobj->ptr,so2->u.cmpobj->ptr); + } } } else { /* Compare elements directly. */ - cmp = compareStringObjects(so1->obj,so2->obj); + if (server.sort_store) { + cmp = compareStringObjects(so1->obj,so2->obj); + } else { + cmp = collateStringObjects(so1->obj,so2->obj); + } } } return server.sort_desc ? -cmp : cmp; @@ -432,6 +442,7 @@ void sortCommand(redisClient *c) { server.sort_desc = desc; server.sort_alpha = alpha; server.sort_bypattern = sortby ? 1 : 0; + server.sort_store = storekey ? 1 : 0; if (sortby && (start != 0 || end != vectorlen-1)) pqsort(vector,vectorlen,sizeof(redisSortObject),sortCompare, start,end); else