21
21
#include "memcached.h"
22
22
23
23
24
- /*
25
- * NOTE: we assume here for simplicity that slab ids are <=32. That's true in
26
- * the powers-of-2 implementation, but if that changes this should be changed too
27
- */
28
-
29
- #define LARGEST_ID 32
24
+ #define LARGEST_ID 255
30
25
static item * heads [LARGEST_ID ];
31
26
static item * tails [LARGEST_ID ];
32
27
unsigned int sizes [LARGEST_ID ];
@@ -41,14 +36,31 @@ void item_init(void) {
41
36
}
42
37
43
38
44
- item * item_alloc (char * key , int flags , time_t exptime , int nbytes ) {
45
- int ntotal , len ;
39
+ /*
40
+ * Generates the variable-sized part of the header for an object.
41
+ *
42
+ * suffix - Buffer for the "VALUE" line suffix (flags, size).
43
+ * nsuffix - The length of the suffix is stored here.
44
+ * keylen - The length of the key plus any padding required to word-align the
45
+ * "VALUE" suffix (which is done to speed up copying.)
46
+ *
47
+ * Returns the total size of the header.
48
+ */
49
+ int item_make_header (char * key , int flags , int nbytes ,
50
+ char * suffix , int * nsuffix , int * keylen ) {
51
+ * keylen = strlen (key ) + 1 ; if (* keylen % 4 ) * keylen += 4 - (* keylen % 4 );
52
+ * nsuffix = sprintf (suffix , " %u %u\r\n" , flags , nbytes - 2 );
53
+ return sizeof (item ) + * keylen + * nsuffix + nbytes ;
54
+ }
55
+
56
+ item * item_alloc (char * key , int flags , rel_time_t exptime , int nbytes ) {
57
+ int nsuffix , ntotal , len ;
46
58
item * it ;
47
59
unsigned int id ;
60
+ char suffix [40 ];
48
61
49
- len = strlen (key ) + 1 ; if (len % 4 ) len += 4 - (len % 4 );
50
- ntotal = sizeof (item ) + len + nbytes ;
51
-
62
+ ntotal = item_make_header (key , flags , nbytes , suffix , & nsuffix , & len );
63
+
52
64
id = slabs_clsid (ntotal );
53
65
if (id == 0 )
54
66
return 0 ;
@@ -97,7 +109,8 @@ item *item_alloc(char *key, int flags, time_t exptime, int nbytes) {
97
109
it -> nbytes = nbytes ;
98
110
strcpy (ITEM_key (it ), key );
99
111
it -> exptime = exptime ;
100
- it -> flags = flags ;
112
+ memcpy (ITEM_suffix (it ), suffix , nsuffix );
113
+ it -> nsuffix = nsuffix ;
101
114
return it ;
102
115
}
103
116
@@ -114,6 +127,18 @@ void item_free(item *it) {
114
127
slabs_free (it , ntotal );
115
128
}
116
129
130
+ /*
131
+ * Returns true if an item will fit in the cache (its size does not exceed
132
+ * the maximum for a cache entry.)
133
+ */
134
+ int item_size_ok (char * key , int flags , int nbytes ) {
135
+ char prefix [40 ];
136
+ int keylen , nsuffix ;
137
+
138
+ return slabs_clsid (item_make_header (key , flags , nbytes ,
139
+ prefix , & nsuffix , & keylen )) != 0 ;
140
+ }
141
+
117
142
void item_link_q (item * it ) { /* item is the new head */
118
143
item * * head , * * tail ;
119
144
assert (it -> slabs_clsid <= LARGEST_ID );
@@ -159,7 +184,7 @@ int item_link(item *it) {
159
184
assert ((it -> it_flags & (ITEM_LINKED |ITEM_SLABBED )) == 0 );
160
185
assert (it -> nbytes < 1048576 );
161
186
it -> it_flags |= ITEM_LINKED ;
162
- it -> time = time ( 0 ) ;
187
+ it -> time = current_time ;
163
188
assoc_insert (ITEM_key (it ), it );
164
189
165
190
stats .curr_bytes += ITEM_ntotal (it );
@@ -195,7 +220,7 @@ void item_update(item *it) {
195
220
assert ((it -> it_flags & ITEM_SLABBED ) == 0 );
196
221
197
222
item_unlink_q (it );
198
- it -> time = time ( 0 ) ;
223
+ it -> time = current_time ;
199
224
item_link_q (it );
200
225
}
201
226
@@ -224,7 +249,7 @@ char *item_cachedump(unsigned int slabs_clsid, unsigned int limit, unsigned int
224
249
bufcurr = 0 ;
225
250
226
251
while (it && (!limit || shown < limit )) {
227
- len = sprintf (temp , "ITEM %s [%u b; %lu s]\r\n" , ITEM_key (it ), it -> nbytes - 2 , it -> time );
252
+ len = sprintf (temp , "ITEM %s [%u b; %lu s]\r\n" , ITEM_key (it ), it -> nbytes - 2 , it -> time + stats . started );
228
253
if (bufcurr + len + 6 > memlimit ) /* 6 is END\r\n\0 */
229
254
break ;
230
255
strcpy (buffer + bufcurr , temp );
@@ -243,7 +268,7 @@ char *item_cachedump(unsigned int slabs_clsid, unsigned int limit, unsigned int
243
268
void item_stats (char * buffer , int buflen ) {
244
269
int i ;
245
270
char * bufcurr = buffer ;
246
- time_t now = time ( 0 ) ;
271
+ rel_time_t now = current_time ;
247
272
248
273
if (buflen < 4096 ) {
249
274
strcpy (buffer , "SERVER_ERROR out of memory" );
@@ -252,7 +277,7 @@ void item_stats(char *buffer, int buflen) {
252
277
253
278
for (i = 0 ; i < LARGEST_ID ; i ++ ) {
254
279
if (tails [i ])
255
- bufcurr += sprintf (bufcurr , "STAT items:%u:number %u\r\nSTAT items:%u:age %lu \r\n" ,
280
+ bufcurr += sprintf (bufcurr , "STAT items:%u:number %u\r\nSTAT items:%u:age %u \r\n" ,
256
281
i , sizes [i ], i , now - tails [i ]-> time );
257
282
}
258
283
strcpy (bufcurr , "END" );
@@ -262,7 +287,7 @@ void item_stats(char *buffer, int buflen) {
262
287
/* dumps out a list of objects of each size, with granularity of 32 bytes */
263
288
char * item_stats_sizes (int * bytes ) {
264
289
int num_buckets = 32768 ; /* max 1MB object, divided into 32 bytes size buckets */
265
- unsigned int * histogram = (int * ) malloc (num_buckets * sizeof (int ));
290
+ unsigned int * histogram = (unsigned int * ) malloc (num_buckets * sizeof (int ));
266
291
char * buf = (char * ) malloc (1024 * 1024 * 2 * sizeof (char ));
267
292
int i ;
268
293
0 commit comments