0
- * NOTE: we assume here for simplicity that slab ids are <=32. That's true in
0
- * the powers-of-2 implementation, but if that changes this should be changed too
0
static item *heads[LARGEST_ID];
0
static item *tails[LARGEST_ID];
0
unsigned int sizes[LARGEST_ID];
0
@@ -41,14 +36,31 @@ void item_init(void) {
0
-item *item_alloc(char *key, int flags, time_t exptime, int nbytes) {
0
+ * Generates the variable-sized part of the header for an object.
0
+ * suffix - Buffer for the "VALUE" line suffix (flags, size).
0
+ * nsuffix - The length of the suffix is stored here.
0
+ * keylen - The length of the key plus any padding required to word-align the
0
+ * "VALUE" suffix (which is done to speed up copying.)
0
+ * Returns the total size of the header.
0
+int item_make_header(char *key, int flags, int nbytes,
0
+ char *suffix, int *nsuffix, int *keylen) {
0
+ *keylen = strlen(key) + 1; if(*keylen % 4) *keylen += 4 - (*keylen % 4);
0
+ *nsuffix = sprintf(suffix, " %u %u\r\n", flags, nbytes - 2);
0
+ return sizeof(item) + *keylen + *nsuffix + nbytes;
0
+item *item_alloc(char *key, int flags, rel_time_t exptime, int nbytes) {
0
+ int nsuffix, ntotal, len;
0
- len = strlen(key) + 1; if(len % 4) len += 4 - (len % 4);
0
- ntotal = sizeof(item) + len + nbytes;
0
+ ntotal = item_make_header(key, flags, nbytes, suffix, &nsuffix, &len);
0
id = slabs_clsid(ntotal);
0
@@ -97,7 +109,8 @@ item *item_alloc(char *key, int flags, time_t exptime, int nbytes) {
0
strcpy(ITEM_key(it), key);
0
+ memcpy(ITEM_suffix(it), suffix, nsuffix);
0
+ it->nsuffix = nsuffix;
0
@@ -114,6 +127,18 @@ void item_free(item *it) {
0
slabs_free(it, ntotal);
0
+ * Returns true if an item will fit in the cache (its size does not exceed
0
+ * the maximum for a cache entry.)
0
+int item_size_ok(char *key, int flags, int nbytes) {
0
+ return slabs_clsid(item_make_header(key, flags, nbytes,
0
+ prefix, &nsuffix, &keylen)) != 0;
0
void item_link_q(item *it) { /* item is the new head */
0
assert(it->slabs_clsid <= LARGEST_ID);
0
@@ -159,7 +184,7 @@ int item_link(item *it) {
0
assert((it->it_flags & (ITEM_LINKED|ITEM_SLABBED)) == 0);
0
assert(it->nbytes < 1048576);
0
it->it_flags |= ITEM_LINKED;
0
+ it->time =
current_time;
0
assoc_insert(ITEM_key(it), it);
0
stats.curr_bytes += ITEM_ntotal(it);
0
@@ -195,7 +220,7 @@ void item_update(item *it) {
0
assert((it->it_flags & ITEM_SLABBED) == 0);
0
+ it->time =
current_time;
0
@@ -224,7 +249,7 @@ char *item_cachedump(unsigned int slabs_clsid, unsigned int limit, unsigned int
0
while (it && (!limit || shown < limit)) {
0
- len = sprintf(temp, "ITEM %s [%u b; %lu s]\r\n", ITEM_key(it), it->nbytes - 2, it->time
);
0
+ len = sprintf(temp, "ITEM %s [%u b; %lu s]\r\n", ITEM_key(it), it->nbytes - 2, it->time
+ stats.started);
0
if (bufcurr + len + 6 > memlimit) /* 6 is END\r\n\0 */
0
strcpy(buffer + bufcurr, temp);
0
@@ -243,7 +268,7 @@ char *item_cachedump(unsigned int slabs_clsid, unsigned int limit, unsigned int
0
void item_stats(char *buffer, int buflen) {
0
char *bufcurr = buffer;
0
+
rel_time_t now = current_time;
0
strcpy(buffer, "SERVER_ERROR out of memory");
0
@@ -252,7 +277,7 @@ void item_stats(char *buffer, int buflen) {
0
for (i=0; i<LARGEST_ID; i++) {
0
- bufcurr += sprintf(bufcurr, "STAT items:%u:number %u\r\nSTAT items:%u:age %
lu\r\n",
0
+ bufcurr += sprintf(bufcurr, "STAT items:%u:number %u\r\nSTAT items:%u:age %
u\r\n",
0
i, sizes[i], i, now - tails[i]->time);
0
strcpy(bufcurr, "END");
0
@@ -262,7 +287,7 @@ void item_stats(char *buffer, int buflen) {
0
/* dumps out a list of objects of each size, with granularity of 32 bytes */
0
char* item_stats_sizes(int *bytes) {
0
int num_buckets = 32768; /* max 1MB object, divided into 32 bytes size buckets */
0
- unsigned int *histogram = (
int*) malloc(num_buckets * sizeof(int));
0
+ unsigned int *histogram = (
unsigned int*) malloc(num_buckets * sizeof(int));
0
char *buf = (char*) malloc(1024*1024*2*sizeof(char));