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; }
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; }
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; } }
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; }