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.
This commit is contained in:
antirez 2013-07-12 12:02:36 +02:00
parent 81e55ec0f3
commit cf1579a798
2 changed files with 15 additions and 3 deletions

View File

@ -891,6 +891,7 @@ struct redisServer {
int sort_desc; int sort_desc;
int sort_alpha; int sort_alpha;
int sort_bypattern; int sort_bypattern;
int sort_store;
/* Zip structure config, see redis.conf for more information */ /* Zip structure config, see redis.conf for more information */
size_t hash_max_ziplist_entries; size_t hash_max_ziplist_entries;
size_t hash_max_ziplist_value; size_t hash_max_ziplist_value;

View File

@ -163,12 +163,22 @@ int sortCompare(const void *s1, const void *s2) {
else else
cmp = 1; cmp = 1;
} else { } else {
/* We have both the objects, use strcoll */ /* 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); cmp = strcoll(so1->u.cmpobj->ptr,so2->u.cmpobj->ptr);
} }
}
} else { } else {
/* Compare elements directly. */ /* Compare elements directly. */
if (server.sort_store) {
cmp = compareStringObjects(so1->obj,so2->obj); cmp = compareStringObjects(so1->obj,so2->obj);
} else {
cmp = collateStringObjects(so1->obj,so2->obj);
}
} }
} }
return server.sort_desc ? -cmp : cmp; return server.sort_desc ? -cmp : cmp;
@ -432,6 +442,7 @@ void sortCommand(redisClient *c) {
server.sort_desc = desc; server.sort_desc = desc;
server.sort_alpha = alpha; server.sort_alpha = alpha;
server.sort_bypattern = sortby ? 1 : 0; server.sort_bypattern = sortby ? 1 : 0;
server.sort_store = storekey ? 1 : 0;
if (sortby && (start != 0 || end != vectorlen-1)) if (sortby && (start != 0 || end != vectorlen-1))
pqsort(vector,vectorlen,sizeof(redisSortObject),sortCompare, start,end); pqsort(vector,vectorlen,sizeof(redisSortObject),sortCompare, start,end);
else else