[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