Skip to content

Commit

Permalink
fix slab allocator
Browse files Browse the repository at this point in the history
Summary: slab allocator build was broken by last checkin (allowing keys to be split across chunks in flat allocator)

Reviewed By: marc

Test Plan: ran stress test for about 1 hour

Revert: OK


git-svn-id: http://svn.facebook.com/svnroot/projects/memcached/trunk@118842 2c7ba8d8-a2f7-0310-a573-de162e16dcc7
  • Loading branch information
ttung committed Aug 28, 2008
1 parent 4c72069 commit e8cee26
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 13 deletions.
2 changes: 1 addition & 1 deletion flat_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -617,7 +617,7 @@ static inline item* ITEM(item_ptr_t iptr) { return get_item_from_chun
static inline item_ptr_t ITEM_PTR(item* it) { return (item_ptr_t) get_chunkptr(get_chunk_from_item(it)); }
static inline bool ITEM_PTR_IS_NULL(item_ptr_t iptr) { return iptr != NULL_ITEM_PTR; }

static inline uint8_t ITEM_nkey(item* it) { return it->empty_header.nkey; }
static inline uint8_t ITEM_nkey(const item* it) { return it->empty_header.nkey; }
static inline int ITEM_nbytes(item* it) { return it->empty_header.nbytes; }
static inline size_t ITEM_ntotal(item* it) {
if (is_item_large_chunk(it)) {
Expand Down
31 changes: 20 additions & 11 deletions slabs_items.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,15 @@ void item_memcpy_from(void* dst, const item* it, size_t offset, size_t nbytes,
}


int item_key_compare(const item* it, const char* key, const size_t nkey) {
if (nkey != ITEM_nkey(it)) {
return ITEM_nkey(it) - nkey;
}

return memcmp(ITEM_key_const(it), key, nkey);
}


void do_try_item_stamp(item* it, const rel_time_t now, const struct in_addr addr) {
int slackspace;
size_t offset = 0;
Expand Down Expand Up @@ -164,9 +173,9 @@ item *do_item_alloc(const char *key, const size_t nkey, const int flags, const r
stats.evictions++;
slabs_add_eviction(id);
STATS_UNLOCK();
do_item_unlink(search, UNLINK_IS_EVICT);
do_item_unlink(search, UNLINK_IS_EVICT, key);
} else {
do_item_unlink(search, UNLINK_IS_EXPIRED);
do_item_unlink(search, UNLINK_IS_EXPIRED, key);
}
break;
}
Expand Down Expand Up @@ -276,13 +285,13 @@ static void item_unlink_q(item *it) {
return;
}

int do_item_link(item *it) {
int do_item_link(item *it, const char* key) {
assert((it->it_flags & (ITEM_LINKED|ITEM_SLABBED)) == 0);
assert(it->nbytes < (1024 * 1024)); /* 1MB max size */
it->it_flags |= ITEM_LINKED;
it->it_flags &= ~ITEM_VISITED;
it->time = current_time;
assoc_insert(it);
assoc_insert(it, key);

STATS_LOCK();
stats.item_total_size += it->nkey + it->nbytes; /* cr-lf shouldn't count */
Expand All @@ -295,7 +304,7 @@ int do_item_link(item *it) {
return 1;
}

void do_item_unlink(item *it, long flags) {
void do_item_unlink(item *it, long flags, const char* key) {
do_item_unlink_impl(it, flags, true);
}

Expand Down Expand Up @@ -347,11 +356,11 @@ void do_item_update(item *it) {
}
}

int do_item_replace(item *it, item *new_it) {
int do_item_replace(item *it, item *new_it, const char* key) {
assert((it->it_flags & ITEM_SLABBED) == 0);

do_item_unlink(it, UNLINK_NORMAL);
return do_item_link(new_it);
do_item_unlink(it, UNLINK_NORMAL, key);
return do_item_link(new_it, key);
}

/*@null@*/
Expand Down Expand Up @@ -488,11 +497,11 @@ item *do_item_get_notedeleted(const char *key, const size_t nkey, bool *delete_l
}
if (it != NULL && settings.oldest_live != 0 && settings.oldest_live <= current_time &&
it->time <= settings.oldest_live) {
do_item_unlink(it, UNLINK_IS_EXPIRED); /* MTSAFE - cache_lock held */
do_item_unlink(it, UNLINK_IS_EXPIRED, key); /* MTSAFE - cache_lock held */
it = NULL;
}
if (it != NULL && it->exptime != 0 && it->exptime <= current_time) {
do_item_unlink(it, UNLINK_IS_EXPIRED); /* MTSAFE - cache_lock held */
do_item_unlink(it, UNLINK_IS_EXPIRED, key); /* MTSAFE - cache_lock held */
it = NULL;
}

Expand Down Expand Up @@ -540,7 +549,7 @@ void do_item_flush_expired(void) {
if (iter->time >= settings.oldest_live) {
next = iter->next;
if ((iter->it_flags & ITEM_SLABBED) == 0) {
do_item_unlink(iter, UNLINK_IS_EXPIRED);
do_item_unlink(iter, UNLINK_IS_EXPIRED, NULL);
}
} else {
/* We've hit the first old item. Continue to the next queue. */
Expand Down
1 change: 1 addition & 0 deletions slabs_items.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ static inline item* ITEM(item_ptr_t iptr) { return (item*) iptr; }
static inline item_ptr_t ITEM_PTR(item* it) { return (item_ptr_t) it; }
static inline bool ITEM_PTR_IS_NULL(item_ptr_t iptr) { return (iptr != NULL); }
static inline char* ITEM_key(item* it) { return &(it->end); }
static inline const char* ITEM_key_const(const item* it){ return &(it->end); }
static inline uint8_t ITEM_nkey(const item* it) { return it->nkey; }
static inline int ITEM_nbytes(const item* it) { return it->nbytes; }
static inline size_t ITEM_ntotal(const item* it) { return stritem_length + it->nkey + it->nbytes; }
Expand Down
7 changes: 6 additions & 1 deletion slabs_items_support.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@
#define ITEM_data(item) ((char*) &((item)->end) + (item)->nkey)


static inline int add_item_to_iov(conn *c, const item* it, bool send_cr_lf) {
static inline int add_item_key_to_iov(conn *c, const item* it) {
return add_iov(c, ITEM_key_const(it), ITEM_nkey(it), false);
}


static inline int add_item_value_to_iov(conn *c, const item* it, bool send_cr_lf) {
if (send_cr_lf) {
return (add_iov(c, ITEM_data(it), it->nbytes, false) ||
add_iov(c, "\r\n", 2, false));
Expand Down

0 comments on commit e8cee26

Please sign in to comment.