[sheepdog] [PATCH 5/8] object cache: schedule the object cache in a lru list
levin li
levin108 at gmail.com
Mon Jul 9 08:29:19 CEST 2012
From: levin li <xingke.lwp at taobao.com>
We put all the cached object into a global lru list, when
the object cache is referenced(read/write), we move the object
to the head of the lru list, then when cache reaches the max
size we can reclaim it from the end of the lru list.
Signed-off-by: levin li <xingke.lwp at taobao.com>
---
sheep/object_cache.c | 54 +++++++++++++++++++++++++++++++++++++-------------
1 files changed, 40 insertions(+), 14 deletions(-)
diff --git a/sheep/object_cache.c b/sheep/object_cache.c
index d4313ff..17ff190 100644
--- a/sheep/object_cache.c
+++ b/sheep/object_cache.c
@@ -306,12 +306,24 @@ static void switch_dirty_tree_and_list(struct object_cache *oc,
/* Caller should hold the oc->lock */
static inline void
add_to_dirty_tree_and_list(struct object_cache *oc,
- struct dirty_cache_entry *entry)
+ struct dirty_cache_entry *dirty_entry, int merge)
{
- if (!dirty_tree_insert(oc->active_dirty_tree, entry))
- list_add(&entry->list, oc->active_dirty_list);
- else
- free(entry);
+ if (!dirty_tree_insert(oc->active_dirty_tree, dirty_entry)) {
+ list_add(&dirty_entry->list, oc->active_dirty_list);
+ } else {
+ free(dirty_entry);
+
+ if (!merge) {
+ struct object_cache_entry *entry;
+
+ entry = dirty_entry->sys_entry;
+ /* If cache isn't in reclaiming, move it
+ * to the head of lru list */
+ cds_list_del_rcu(&entry->lru_list);
+ cds_list_add_rcu(&entry->lru_list,
+ &sys_cache.cache_lru_list);
+ }
+ }
}
static void merge_dirty_tree_and_list(struct object_cache *oc,
@@ -324,17 +336,19 @@ static void merge_dirty_tree_and_list(struct object_cache *oc,
list_for_each_entry_safe(entry, t, inactive_dirty_list, list) {
del_from_dirty_tree_and_list(entry, inactive_dirty_tree);
- add_to_dirty_tree_and_list(oc, entry);
+ add_to_dirty_tree_and_list(oc, entry, 1);
}
pthread_mutex_unlock(&oc->lock);
}
static inline struct dirty_cache_entry *
-alloc_cache_entry(uint32_t idx, uint64_t bmap, int create)
+alloc_cache_entry(struct object_cache_entry *oc_entry, uint32_t idx,
+ uint64_t bmap, int create)
{
struct dirty_cache_entry *entry = xzalloc(sizeof(*entry));
+ entry->sys_entry = oc_entry;
entry->idx = idx;
entry->bmap = bmap;
entry->create = create;
@@ -377,6 +391,8 @@ static int object_cache_lookup(struct object_cache *oc, uint32_t idx,
{
struct strbuf buf;
int fd, ret = 0, flags = def_open_flags;
+ struct object_cache_entry *entry = NULL;
+ struct dirty_cache_entry *dirty_entry;
strbuf_init(&buf, PATH_MAX);
strbuf_addstr(&buf, cache_dir);
@@ -392,7 +408,6 @@ static int object_cache_lookup(struct object_cache *oc, uint32_t idx,
}
if (create) {
- struct dirty_cache_entry *entry;
unsigned data_length;
if (idx_has_vdi_bit(idx))
@@ -406,11 +421,11 @@ static int object_cache_lookup(struct object_cache *oc, uint32_t idx,
else {
uint64_t bmap = UINT64_MAX;
- add_to_object_cache(oc, idx);
+ entry = add_to_object_cache(oc, idx);
- entry = alloc_cache_entry(idx, bmap, 1);
+ dirty_entry = alloc_cache_entry(entry, idx, bmap, 1);
pthread_mutex_lock(&oc->lock);
- add_to_dirty_tree_and_list(oc, entry);
+ add_to_dirty_tree_and_list(oc, dirty_entry, 0);
pthread_mutex_unlock(&oc->lock);
}
}
@@ -516,22 +531,27 @@ static int object_cache_rw(struct object_cache *oc, uint32_t idx,
{
struct sd_req *hdr = &req->rq;
uint64_t bmap = 0;
+ struct object_cache_entry *entry;
int ret;
dprintf("%08"PRIx32", len %"PRIu32", off %"PRIu64"\n", idx,
hdr->data_length, hdr->obj.offset);
+ pthread_mutex_lock(&oc->lock);
+ entry = object_tree_search(&oc->object_tree, idx);
+ pthread_mutex_unlock(&oc->lock);
+
if (hdr->flags & SD_FLAG_CMD_WRITE) {
- struct dirty_cache_entry *entry;
+ struct dirty_cache_entry *dirty_entry;
ret = write_cache_object(oc->vid, idx, req->data,
hdr->data_length, hdr->obj.offset);
if (ret != SD_RES_SUCCESS)
goto out;
bmap = calc_object_bmap(hdr->data_length, hdr->obj.offset);
- entry = alloc_cache_entry(idx, bmap, 0);
+ dirty_entry = alloc_cache_entry(entry, idx, bmap, 0);
pthread_mutex_lock(&oc->lock);
- add_to_dirty_tree_and_list(oc, entry);
+ add_to_dirty_tree_and_list(oc, dirty_entry, 0);
pthread_mutex_unlock(&oc->lock);
} else {
ret = read_cache_object(oc->vid, idx, req->data,
@@ -539,6 +559,12 @@ static int object_cache_rw(struct object_cache *oc, uint32_t idx,
if (ret != SD_RES_SUCCESS)
goto out;
req->rp.data_length = hdr->data_length;
+
+ if (entry) {
+ cds_list_del_rcu(&entry->lru_list);
+ cds_list_add_rcu(&entry->lru_list,
+ &sys_cache.cache_lru_list);
+ }
}
out:
return ret;
--
1.7.1
More information about the sheepdog
mailing list