mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-22 16:18:28 -05:00
test for intset integer encodability test and some small refactoring
This commit is contained in:
parent
23c64fe50d
commit
ec7e138926
@ -769,6 +769,8 @@ int stringmatch(const char *pattern, const char *string, int nocase);
|
||||
long long memtoll(const char *p, int *err);
|
||||
int ll2string(char *s, size_t len, long long value);
|
||||
int isStringRepresentableAsLong(sds s, long *longval);
|
||||
int isStringRepresentableAsLongLong(sds s, long long *longval);
|
||||
int isObjectRepresentableAsLongLong(robj *o, long long *llongval);
|
||||
|
||||
/* Configuration */
|
||||
void loadServerConfig(char *filename);
|
||||
|
@ -8,7 +8,7 @@
|
||||
* an integer-encodable value, an intset will be returned. Otherwise a regular
|
||||
* hash table. */
|
||||
robj *setTypeCreate(robj *value) {
|
||||
if (getLongLongFromObject(value,NULL) == REDIS_OK)
|
||||
if (isObjectRepresentableAsLongLong(value,NULL) == REDIS_OK)
|
||||
return createIntsetObject();
|
||||
return createSetObject();
|
||||
}
|
||||
@ -21,7 +21,7 @@ int setTypeAdd(robj *subject, robj *value) {
|
||||
return 1;
|
||||
}
|
||||
} else if (subject->encoding == REDIS_ENCODING_INTSET) {
|
||||
if (getLongLongFromObject(value,&llval) == REDIS_OK) {
|
||||
if (isObjectRepresentableAsLongLong(value,&llval) == REDIS_OK) {
|
||||
uint8_t success = 0;
|
||||
subject->ptr = intsetAdd(subject->ptr,llval,&success);
|
||||
if (success) {
|
||||
@ -55,7 +55,7 @@ int setTypeRemove(robj *subject, robj *value) {
|
||||
return 1;
|
||||
}
|
||||
} else if (subject->encoding == REDIS_ENCODING_INTSET) {
|
||||
if (getLongLongFromObject(value,&llval) == REDIS_OK) {
|
||||
if (isObjectRepresentableAsLongLong(value,&llval) == REDIS_OK) {
|
||||
uint8_t success;
|
||||
subject->ptr = intsetRemove(subject->ptr,llval,&success);
|
||||
if (success) return 1;
|
||||
@ -71,7 +71,7 @@ int setTypeIsMember(robj *subject, robj *value) {
|
||||
if (subject->encoding == REDIS_ENCODING_HT) {
|
||||
return dictFind((dict*)subject->ptr,value) != NULL;
|
||||
} else if (subject->encoding == REDIS_ENCODING_INTSET) {
|
||||
if (getLongLongFromObject(value,&llval) == REDIS_OK) {
|
||||
if (isObjectRepresentableAsLongLong(value,&llval) == REDIS_OK) {
|
||||
return intsetFind((intset*)subject->ptr,llval);
|
||||
}
|
||||
} else {
|
||||
|
34
src/util.c
34
src/util.c
@ -200,24 +200,44 @@ int ll2string(char *s, size_t len, long long value) {
|
||||
return l;
|
||||
}
|
||||
|
||||
/* Check if the nul-terminated string 's' can be represented by a long
|
||||
/* Check if the sds string 's' can be represented by a long long
|
||||
* (that is, is a number that fits into long without any other space or
|
||||
* character before or after the digits).
|
||||
* character before or after the digits, so that converting this number
|
||||
* back to a string will result in the same bytes as the original string).
|
||||
*
|
||||
* If so, the function returns REDIS_OK and *longval is set to the value
|
||||
* If so, the function returns REDIS_OK and *llongval is set to the value
|
||||
* of the number. Otherwise REDIS_ERR is returned */
|
||||
int isStringRepresentableAsLong(sds s, long *longval) {
|
||||
int isStringRepresentableAsLongLong(sds s, long long *llongval) {
|
||||
char buf[32], *endptr;
|
||||
long value;
|
||||
long long value;
|
||||
int slen;
|
||||
|
||||
value = strtol(s, &endptr, 10);
|
||||
value = strtoll(s, &endptr, 10);
|
||||
if (endptr[0] != '\0') return REDIS_ERR;
|
||||
slen = ll2string(buf,32,value);
|
||||
|
||||
/* If the number converted back into a string is not identical
|
||||
* then it's not possible to encode the string as integer */
|
||||
if (sdslen(s) != (unsigned)slen || memcmp(buf,s,slen)) return REDIS_ERR;
|
||||
if (longval) *longval = value;
|
||||
if (llongval) *llongval = value;
|
||||
return REDIS_OK;
|
||||
}
|
||||
|
||||
int isStringRepresentableAsLong(sds s, long *longval) {
|
||||
long long ll;
|
||||
|
||||
if (isStringRepresentableAsLongLong(s,&ll) == REDIS_ERR) return REDIS_ERR;
|
||||
if (ll < LONG_MIN || ll > LONG_MAX) return REDIS_ERR;
|
||||
*longval = (long)ll;
|
||||
return REDIS_OK;
|
||||
}
|
||||
|
||||
int isObjectRepresentableAsLongLong(robj *o, long long *llongval) {
|
||||
redisAssert(o->type == REDIS_STRING);
|
||||
if (o->encoding == REDIS_ENCODING_INT) {
|
||||
if (llongval) *llongval = (long) o->ptr;
|
||||
return REDIS_OK;
|
||||
} else {
|
||||
return isStringRepresentableAsLongLong(o->ptr,llongval);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user