[memcached] sgrimm,
r318: If a client tries to store an object tha...
commits at code.sixapart.com
commits at code.sixapart.com
Wed Aug 23 19:33:44 UTC 2006
If a client tries to store an object that's too large for the cache (the
maximum is currently 1MB), print a more accurate error message than "out
of memory."
U branches/facebook/items.c
U branches/facebook/memcached.c
U branches/facebook/memcached.h
Modified: branches/facebook/items.c
===================================================================
--- branches/facebook/items.c 2006-08-23 19:30:01 UTC (rev 317)
+++ branches/facebook/items.c 2006-08-23 19:33:43 UTC (rev 318)
@@ -36,15 +36,30 @@
}
+/*
+ * Generates the variable-sized part of the header for an object.
+ *
+ * suffix - Buffer for the "VALUE" line suffix (flags, size).
+ * nsuffix - The length of the suffix is stored here.
+ * keylen - The length of the key plus any padding required to word-align the
+ * "VALUE" suffix (which is done to speed up copying.)
+ *
+ * Returns the total size of the header.
+ */
+int item_make_header(char *key, int flags, int nbytes,
+ char *suffix, int *nsuffix, int *keylen) {
+ *keylen = strlen(key) + 1; if(*keylen % 4) *keylen += 4 - (*keylen % 4);
+ *nsuffix = sprintf(suffix, " %u %u\r\n", flags, nbytes - 2);
+ return sizeof(item) + *keylen + *nsuffix + nbytes;
+}
+
item *item_alloc(char *key, int flags, rel_time_t exptime, int nbytes) {
int nsuffix, ntotal, len;
item *it;
unsigned int id;
char suffix[40];
- len = strlen(key) + 1; if(len % 4) len += 4 - (len % 4);
- nsuffix = sprintf(suffix, " %u %u\r\n", flags, nbytes - 2);
- ntotal = sizeof(item) + len + nsuffix + nbytes;
+ ntotal = item_make_header(key, flags, nbytes, suffix, &nsuffix, &len);
id = slabs_clsid(ntotal);
if (id == 0)
@@ -112,6 +127,18 @@
slabs_free(it, ntotal);
}
+/*
+ * Returns true if an item will fit in the cache (its size does not exceed
+ * the maximum for a cache entry.)
+ */
+int item_size_ok(char *key, int flags, int nbytes) {
+ char prefix[40];
+ int keylen, nsuffix;
+
+ return slabs_clsid(item_make_header(key, flags, nbytes,
+ prefix, &nsuffix, &keylen)) != 0;
+}
+
void item_link_q(item *it) { /* item is the new head */
item **head, **tail;
assert(it->slabs_clsid <= LARGEST_ID);
Modified: branches/facebook/memcached.c
===================================================================
--- branches/facebook/memcached.c 2006-08-23 19:30:01 UTC (rev 317)
+++ branches/facebook/memcached.c 2006-08-23 19:33:43 UTC (rev 318)
@@ -817,7 +817,10 @@
it = item_alloc(key, flags, realtime(expire), len+2);
if (it == 0) {
- out_string(c, "SERVER_ERROR out of memory");
+ if (! item_size_ok(key, flags, len + 2))
+ out_string(c, "SERVER_ERROR object too large for cache");
+ else
+ out_string(c, "SERVER_ERROR out of memory");
/* swallow the data line */
c->write_and_go = conn_swallow;
c->sbytes = len+2;
Modified: branches/facebook/memcached.h
===================================================================
--- branches/facebook/memcached.h 2006-08-23 19:30:01 UTC (rev 317)
+++ branches/facebook/memcached.h 2006-08-23 19:33:43 UTC (rev 318)
@@ -268,6 +268,7 @@
void item_init(void);
item *item_alloc(char *key, int flags, rel_time_t exptime, int nbytes);
void item_free(item *it);
+int item_size_ok(char *key, int flags, int nbytes);
int item_link(item *it); /* may fail if transgresses limits */
void item_unlink(item *it);
More information about the memcached-commits
mailing list