Example #1
0
static void *
skiplist_get(struct qb_map *map, const char *key)
{
	struct skiplist *list = (struct skiplist *)map;
	struct skiplist_node *n = skiplist_lookup(list, key);
	if (n) {
		return n->value;
	}

	return NULL;
}
Example #2
0
static int32_t
skiplist_notify_add(qb_map_t * m, const char *key,
		    qb_map_notify_fn fn, int32_t events, void *user_data)
{
	struct skiplist *t = (struct skiplist *)m;
	struct qb_map_notifier *f;
	struct skiplist_node *n;
	struct qb_list_head *list;
	int add_to_tail = QB_FALSE;

	if (key) {
		n = skiplist_lookup(t, key);
	} else {
		n = t->header;
	}
	if (events & QB_MAP_NOTIFY_FREE) {
		add_to_tail = QB_TRUE;
	}
	if (n) {
		for (list = n->notifier_head.next;
		     list != &n->notifier_head; list = list->next) {
			f = qb_list_entry(list, struct qb_map_notifier, list);

			if (events & QB_MAP_NOTIFY_FREE &&
			    f->events == events) {
				/* only one free notifier */
				return -EEXIST;
			}
			if (f->events == events &&
			    f->callback == fn &&
			    f->user_data == user_data) {
				return -EEXIST;
			}
		}

		f = malloc(sizeof(struct qb_map_notifier));
		if (f == NULL) {
			return -errno;
		}
		f->events = events;
		f->user_data = user_data;
		f->callback = fn;
		qb_list_init(&f->list);
		if (add_to_tail) {
			qb_list_add_tail(&f->list, &n->notifier_head);
		} else {
			qb_list_add(&f->list, &n->notifier_head);
		}
		return 0;
	}
	return -EINVAL;
}
Example #3
0
static int32_t
skiplist_notify_del(qb_map_t * m, const char *key,
		    qb_map_notify_fn fn, int32_t events,
		    int32_t cmp_userdata, void *user_data)
{
	struct skiplist *t = (struct skiplist *)m;
	struct skiplist_node *n;
	struct qb_map_notifier *f;
	struct qb_list_head *head = NULL;
	struct qb_list_head *list;
	struct qb_list_head *next;
	int32_t found = QB_FALSE;

	if (key) {
		n = skiplist_lookup(t, key);
		if (n) {
			head = &n->notifier_head;
		}
	} else {
		head = &t->header->notifier_head;
	}
	if (head == NULL) {
		return -ENOENT;
	}
	for (list = head->next;
	     list != head; list = next) {
		f = qb_list_entry(list, struct qb_map_notifier, list);
		next = list->next;

		if (f->events == events && f->callback == fn) {
			if (cmp_userdata && (f->user_data == user_data)) {
				found = QB_TRUE;
				qb_list_del(&f->list);
				free(f);
			} else if (!cmp_userdata) {
				found = QB_TRUE;
				qb_list_del(&f->list);
				free(f);
			}
		}
	}
	if (found) {
		return 0;
	} else {
		return -ENOENT;
	}
}
Example #4
0
int index_get(struct index *idx, struct slice *sk, struct slice *sv)
{
	int ret = 0, value_len, result;
	uint64_t value_off = 0UL;

	struct skipnode *node;
	struct skiplist *cur_list;
	struct skiplist *merge_list;

	/* 
	 * 0) Get from bloomfilter, if bloom_get return 1, next 
	 * 1) First lookup from active memtable 
	 * 2) Then from merge memtable 
	 * 3) Last from sst on-disk indexes 
	 */

	cur_list = idx->list;
	node = skiplist_lookup(cur_list, sk->data);

	if(node) {
		if(node->opt == DEL) {
			ret = -1;
			goto out_get;
		}
		value_off =node->val;
	} else {
		merge_list = idx->park->list;
		if(merge_list) {
			node = skiplist_lookup(merge_list, sk->data);
			if(node && node->opt == ADD)
				value_off = node->val;
		}
	}
	if(value_off == 0UL)
		value_off = sst_getoff(idx->sst, sk);

	if(value_off != 0UL) {
		__be32 be32len;
		lseek(idx->db_rfd, value_off, SEEK_SET);
		result = read(idx->db_rfd, &be32len, sizeof(int));
		if(FILE_ERR(result)) {
			ret = -1;
			goto out_get;
		}

		value_len = from_be32(be32len);
		if(result == sizeof(int)) {
			char *data = malloc(value_len + 1);
			memset(data, 0, value_len+1);
			result = read(idx->db_rfd, data, value_len);
			if(FILE_ERR(result)) {
				free(data);
				ret = -1;
				goto out_get;
			}
			sv->len = value_len;
			sv->data = data;
			return 1;
		}
	} else {
		return 0;
	}
out_get:
	return ret;
}