o->encoding = REDIS_ENCODING_RAW;
o->ptr = ptr;
o->refcount = 1;
- if (server.vm_enabled) {
- /* Note that this code may run in the context of an I/O thread
- * and accessing server.lruclock in theory is an error
- * (no locks). But in practice this is safe, and even if we read
- * garbage Redis will not fail. */
- o->lru = server.lruclock;
- o->storage = REDIS_VM_MEMORY;
- }
+ /* Set the LRU to the current lruclock (minutes resolution).
+ * We do this regardless of the fact VM is active as LRU is also
+ * used for the maxmemory directive when Redis is used as cache.
+ *
+ * Note that this code may run in the context of an I/O thread
+ * and accessing server.lruclock in theory is an error
+ * (no locks). But in practice this is safe, and even if we read
+ * garbage Redis will not fail. */
+ o->lru = server.lruclock;
+ /* The following is only needed if VM is active, but since the conditional
+ * is probably more costly than initializing the field it's better to
+ * have every field properly initialized anyway. */
+ o->storage = REDIS_VM_MEMORY;
return o;
}
double value;
if (getDoubleFromObject(o, &value) != REDIS_OK) {
if (msg != NULL) {
- addReplySds(c, sdscatprintf(sdsempty(), "-ERR %s\r\n", msg));
+ addReplyError(c,(char*)msg);
} else {
- addReplySds(c, sdsnew("-ERR value is not a double\r\n"));
+ addReplyError(c,"value is not a double");
}
return REDIS_ERR;
}
if (o->encoding == REDIS_ENCODING_RAW) {
value = strtoll(o->ptr, &eptr, 10);
if (eptr[0] != '\0') return REDIS_ERR;
+ if (errno == ERANGE && (value == LLONG_MIN || value == LLONG_MAX))
+ return REDIS_ERR;
} else if (o->encoding == REDIS_ENCODING_INT) {
value = (long)o->ptr;
} else {
long long value;
if (getLongLongFromObject(o, &value) != REDIS_OK) {
if (msg != NULL) {
- addReplySds(c, sdscatprintf(sdsempty(), "-ERR %s\r\n", msg));
+ addReplyError(c,(char*)msg);
} else {
- addReplySds(c, sdsnew("-ERR value is not an integer\r\n"));
+ addReplyError(c,"value is not an integer or out of range");
}
return REDIS_ERR;
}
if (getLongLongFromObjectOrReply(c, o, &value, msg) != REDIS_OK) return REDIS_ERR;
if (value < LONG_MIN || value > LONG_MAX) {
if (msg != NULL) {
- addReplySds(c, sdscatprintf(sdsempty(), "-ERR %s\r\n", msg));
+ addReplyError(c,(char*)msg);
} else {
- addReplySds(c, sdsnew("-ERR value is out of range\r\n"));
+ addReplyError(c,"value is out of range");
}
return REDIS_ERR;
}
default: return "unknown";
}
}
+
+/* Given an object returns the min number of seconds the object was never
+ * requested, using an approximated LRU algorithm. */
+unsigned long estimateObjectIdleTime(robj *o) {
+ if (server.lruclock >= o->lru) {
+ return (server.lruclock - o->lru) * 60;
+ } else {
+ return ((REDIS_LRU_CLOCK_MAX - o->lru) + server.lruclock) * 60;
+ }
+}