[Sheepdog] [PATCH 3/4] object list cache: move it out of store.c

Liu Yuan namei.unix at gmail.com
Mon Apr 30 18:16:25 CEST 2012


From: Liu Yuan <tailai.ly at taobao.com>


Signed-off-by: Liu Yuan <tailai.ly at taobao.com>
---
 sheep/Makefile.am         |    2 +-
 sheep/object_list_cache.c |  151 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 152 insertions(+), 1 deletions(-)
 create mode 100644 sheep/object_list_cache.c

diff --git a/sheep/Makefile.am b/sheep/Makefile.am
index 507a497..7448ae1 100644
--- a/sheep/Makefile.am
+++ b/sheep/Makefile.am
@@ -26,7 +26,7 @@ sbin_PROGRAMS		= sheep
 
 sheep_SOURCES		= sheep.c group.c sdnet.c store.c vdi.c work.c \
 			  journal.c ops.c recovery.c cluster/local.c strbuf.c \
-			  simple_store.c object_cache.c
+			  simple_store.c object_cache.c object_list_cache.c
 
 if BUILD_COROSYNC
 sheep_SOURCES		+= cluster/corosync.c
diff --git a/sheep/object_list_cache.c b/sheep/object_list_cache.c
new file mode 100644
index 0000000..73a395a
--- /dev/null
+++ b/sheep/object_list_cache.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2011 Taobao Inc.
+ *
+ * Levin Li <xingke.lwp at taobao.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <pthread.h>
+
+#include "sheep_priv.h"
+#include "strbuf.h"
+#include "util.h"
+
+struct objlist_cache_entry {
+	uint64_t oid;
+	struct rb_node node;
+};
+
+struct objlist_cache obj_list_cache;
+
+int init_objlist_cache(void)
+{
+	int i;
+	struct siocb iocb = { 0 };
+	uint64_t *buf;
+
+	pthread_rwlock_init(&obj_list_cache.lock, NULL);
+	obj_list_cache.root = RB_ROOT;
+	obj_list_cache.cache_size = 0;
+
+	if (sd_store) {
+		buf = zalloc(1 << 22);
+		if (!buf) {
+			eprintf("no memory to allocate.\n");
+			return -1;
+		}
+
+		iocb.length = 0;
+		iocb.buf = buf;
+		sd_store->get_objlist(&iocb);
+
+		for (i = 0; i < iocb.length; i++)
+			check_and_insert_objlist_cache(buf[i]);
+
+		free(buf);
+	}
+
+	return 0;
+}
+
+static struct objlist_cache_entry *objlist_cache_rb_insert(struct rb_root *root,
+		struct objlist_cache_entry *new)
+{
+	struct rb_node **p = &root->rb_node;
+	struct rb_node *parent = NULL;
+	struct objlist_cache_entry *entry;
+
+	while (*p) {
+		parent = *p;
+		entry = rb_entry(parent, struct objlist_cache_entry, node);
+
+		if (new->oid < entry->oid)
+			p = &(*p)->rb_left;
+		else if (new->oid > entry->oid)
+			p = &(*p)->rb_right;
+		else
+			return entry; /* already has this entry */
+	}
+	rb_link_node(&new->node, parent, p);
+	rb_insert_color(&new->node, root);
+
+	return NULL; /* insert successfully */
+}
+
+int objlist_cache_rb_remove(struct rb_root *root, uint64_t oid)
+{
+	struct rb_node **p = &root->rb_node;
+	struct rb_node *parent = NULL;
+	struct objlist_cache_entry *entry;
+
+	while (*p) {
+		parent = *p;
+		entry = rb_entry(parent, struct objlist_cache_entry, node);
+
+		if (oid < entry->oid)
+			p = &(*p)->rb_left;
+		else if (oid > entry->oid)
+			p = &(*p)->rb_right;
+		else {
+			rb_erase(parent, root);
+			return 0;
+		}
+	}
+
+	return -1; /* fail to remove */
+}
+
+int check_and_insert_objlist_cache(uint64_t oid)
+{
+	struct objlist_cache_entry *entry, *p;
+
+	entry = zalloc(sizeof(*entry));
+
+	if (!entry) {
+		eprintf("no memory to allocate cache entry.\n");
+		return -1;
+	}
+
+	entry->oid = oid;
+	rb_init_node(&entry->node);
+
+	pthread_rwlock_wrlock(&obj_list_cache.lock);
+	p = objlist_cache_rb_insert(&obj_list_cache.root, entry);
+	if (p)
+		free(entry);
+	else
+		obj_list_cache.cache_size++;
+	pthread_rwlock_unlock(&obj_list_cache.lock);
+
+	return 0;
+}
+
+int get_obj_list(const struct sd_list_req *hdr, struct sd_list_rsp *rsp, void *data)
+{
+	uint64_t *list = (uint64_t *)data;
+	int nr = 0;
+	int res = SD_RES_SUCCESS;
+	struct objlist_cache_entry *entry;
+	struct rb_node *p;
+
+	pthread_rwlock_rdlock(&obj_list_cache.lock);
+	for (p = rb_first(&obj_list_cache.root); p; p = rb_next(p)) {
+		entry = rb_entry(p, struct objlist_cache_entry, node);
+		list[nr++] = entry->oid;
+	}
+	pthread_rwlock_unlock(&obj_list_cache.lock);
+
+	rsp->data_length = nr * sizeof(uint64_t);
+
+	return res;
+}
-- 
1.7.8.2




More information about the sheepdog mailing list