eventloop_t *el_loop_create(int size) { eventloop_t *el; int i; if ((el = rr_malloc(sizeof(*el))) == NULL) goto err; el->events = rr_malloc(sizeof(event_t)*size); el->fired = rr_malloc(sizeof(fired_event_t)*size); el->timers = minheap_create(1, sizeof(ev_timer_t), timer_cmp, timer_cpy, timer_swp); if (el->events == NULL || el->fired == NULL || el->timers == NULL) goto err; el->size = size; el->stop = 0; el->maxfd = -1; el->before_polling = NULL; if (el_context_create(el) == -1) goto err; for (i = 0; i < size; i++) el->events[i].mask = RR_EV_NONE; return el; err: if (el) { rr_free(el->events); rr_free(el->fired); minheap_free(el->timers); rr_free(el); } return NULL; }
static void el_context_free(eventloop_t *el) { el_context_t *context = el->context; close(context->epfd); rr_free(context->events); rr_free(context); }
void el_loop_free(eventloop_t *el) { el_context_free(el); minheap_free(el->timers); rr_free(el->events); rr_free(el->fired); rr_free(el); }
static dict_t *search_with_bm25_score(fts_t *fts, robj *query) { int i, len, nonstopwords; sds *terms; /* dict of (title, fts_doc_score_t) */ dict_t *scores = dict_create(); dict_set_freecb(scores, dict_doc_score_free); dict_t *queried_terms = dict_create(); terms = sds_tokenize(query->ptr, &len, &nonstopwords); if (!terms) return scores; for (i = 0; i < len; i++) { sds term = terms[i]; list *idx; if (sdslen(term) == 0) { sdsfree(term); continue; } if (dict_contains(queried_terms, term)) goto free_term; dict_set(queried_terms, term, (void *)1); idx = dict_get(fts->index, term); if (!idx) goto free_term; calculate_bm25(fts, idx, scores); free_term: sdsfree(term); } dict_free(queried_terms); rr_free(terms); return scores; }
static void fts_index_del(fts_t *fts, fts_doc_t *doc) { int i, len, nonstopwords; sds *terms; terms = sds_tokenize(doc->doc->ptr, &len, &nonstopwords); if (!terms) return; for (i = 0; i < len; i++) { sds term = terms[i]; list *idx; listNode *ln; if (sdslen(term) == 0) { sdsfree(term); continue; } idx = dict_get(fts->index, term); assert(idx); ln = listSearchKey(idx, doc); assert(ln); index_item_t *idi = ln->value; idi->tf--; if (!idi->tf) listDelNode(idx, ln); sdsfree(term); } rr_free(terms); fts->len -= doc->len; }
static int el_context_create(eventloop_t *el) { el_context_t *context = rr_malloc(sizeof(el_context_t)); if (!context) return -1; context->events = rr_malloc(sizeof(struct epoll_event)*el->size); if (!context->events) { rr_free(context); return -1; } context->epfd = epoll_create(1024); /* 1024 is just a hint for the kernel */ if (context->epfd == -1) { rr_free(context->events); rr_free(context); return -1; } el->context = context; return 0; }
void mdns_free(struct rr_entry *entries) { struct rr_entry *entry; while ((entry = entries)) { entries = entries->next; rr_free(entry); free(entry); } }
void minheap_free(minheap_t *heap) { if (heap->free_cb) { unsigned long i; for (i = 0; i < heap->len; i++) { heap->free_cb(ARRAY_AT(heap->array, i)); } } array_free(heap->array); rr_free(heap); }
void decrRefCount(robj *o) { if (o->refcount == 1) { switch(o->type) { case OBJ_STRING: freeStringObject(o); break; case OBJ_HASH: freeHashObject(o); break; case OBJ_HEAPQ: freeHeapqObject(o); break; case OBJ_FTS: freeFTSObject(o); break; default: rr_log(RR_LOG_ERROR, "Unknown object type"); break; } rr_free(o); } else { if (o->refcount <= 0) rr_log(RR_LOG_ERROR, "decrRefCount against refcount <= 0"); if (o->refcount != OBJ_SHARED_REFCOUNT) o->refcount--; } }
struct minheap_t * minheap_create(unsigned long n, size_t size, compare pfcmp, copy pfcpy, swap pfswp) { minheap_t *heap; heap = rr_malloc(sizeof(minheap_t)); if (heap == NULL) return NULL; heap->comp = pfcmp; heap->cpy = pfcpy; heap->swp = pfswp; heap->free_cb = NULL; heap->len = 0; heap->array = array_create(n, size); if (heap->array == NULL) { rr_free(heap); return NULL; } return heap; }
static bool fts_index_add(fts_t *fts, fts_doc_t *doc) { int i, len, nonstopwords; sds *terms; terms = sds_tokenize(doc->doc->ptr, &len, &nonstopwords); if (!terms) return false; for (i = 0; i < len; i++) { sds term = terms[i]; list *idx; listNode *ln; if (sdslen(term) == 0) { sdsfree(term); continue; } idx = dict_get(fts->index, term); if (!idx) { idx = index_list_create(); dict_set(fts->index, term, idx); } ln = listSearchKey(idx, doc); if (ln) { index_item_t *idi = ln->value; idi->tf++; } else { index_item_t *idi = rr_malloc(sizeof(*idi)); idi->doc = doc; idi->tf = 1; listAddNodeHead(idx, idi); } sdsfree(term); } rr_free(terms); doc->len = nonstopwords; fts->len += doc->len; return true; }
void fts_free(fts_t *fts) { dict_free(fts->docs); dict_free(fts->index); rr_free(fts); }
static void dict_doc_score_free(void *data) { rr_free(data); }
static void index_item_free(void *idx) { rr_free(idx); }
void fts_iter_free(struct fts_iterator_t *it) { minheap_free(it->docs); rr_free(it); }
static void fts_doc_free(void *data) { fts_doc_t *d = (fts_doc_t *) data; decrRefCount(d->title); decrRefCount(d->doc); rr_free(d); }