void *_sparse_bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*cmpfn)(const void *, const void *), bool (*validfn)(const void *)) { ssize_t start = 0, end = nmemb - 1; const char *p = base; while (start <= end) { ssize_t next = (start + end) / 2; int result; while (!validfn(p + next * size)) { /* Try the next one along. */ next++; if (next > end) { /* Hmm, none of these were valid. */ next = (start + end) / 2; goto trim; } } result = cmpfn(key, p + next * size); if (result == 0) return (void *)(p + next * size); else if (result > 0) start = next + 1; else { trim: end = next - 1; } } return NULL; }
static bool check_sorted (void *base, size_t members, size_t membersize, int (*cmpfn)(const void*, const void*)) { const char *p = base; size_t i; for (i=1u; i<members; ++i) { int result = cmpfn (p+i*membersize, p+(i-1)*membersize); if (result < 0) return false; result = cmpfn (p+(i-1)*membersize, p+i*membersize); assert (result <= 0); } return true; }
void mapInsert(mmap* m, char* key, void* value, int (*cmpfn)(void* v1, void* v2), void (*freefn)(void*)) { /* NULL values allow for set emulation */ int fnd = findIndex(m, key); if(fnd == -1) { /* key not found */ append(m->keys, key); if(value != NULL) { vectr* v = newVectr(); append(v, value); append(m->vals, v); } } else { /* key found */ free(key); /* dodgy design - assumes that key is strdup-ed */ if(value != NULL) { vectr* valvctr = get(m->vals, fnd); if(cmpfn != NULL) { int vctr = valvctr->elements; while(--vctr >= 0) { if(cmpfn(value, get(valvctr, vctr)) == 0) { freefn(value); return; } } } append(valvctr, value); } } }
void *dl_delete (DataList *dl, const void *element, CMPFN cmpfn, FREEFN freefn) { int i; void *save; PR_ASSERT (dl); PR_ASSERT (element); PR_ASSERT (cmpfn); for (i = 0; i < dl->element_count; i++) { if (cmpfn (dl->elements[i], element) == 0) { /* if we have destructor - free the data; otherwise, return it to the client */ if (freefn) { freefn (&dl->elements[i]); save = NULL; } else save = dl->elements[i]; if (i != dl->element_count - 1) { memmove (&dl->elements[i], &dl->elements[i+1], (dl->element_count - i - 1) * sizeof (void*)); } dl->element_count --; return save; } } return NULL; }
void *dl_replace(const DataList *dl, const void *elementOld, void *elementNew, CMPFN cmpfn, FREEFN freefn) { int i; void *save; PR_ASSERT (dl); PR_ASSERT (elementOld); PR_ASSERT (elementNew); PR_ASSERT (cmpfn); for (i = 0; i < dl->element_count; i++) { if (cmpfn (dl->elements[i], elementOld) == 0) { /* if we have destructor - free the data; otherwise, return it to the client */ if (freefn) { freefn (&dl->elements[i]); save = NULL; } else save = dl->elements[i]; dl->elements[i] = elementNew; return save; } } return NULL; }
int32_t oscap_bfind_i(void *ptr, size_t nmemb, size_t size, void *key, int cmpfn(void *, void *), size_t *save) { size_t w, s; int cmp; uint8_t *p; w = nmemb; s = 0; p = (uint8_t *) ptr; while (w > 0) { cmp = cmpfn(key, p + (size * (s + w / 2))); if (cmp > 0) { s += w / 2 + 1; w = w - w / 2 - 1; } else if (cmp < 0) { w = w / 2; } else { assert((s + w / 2) <= INT32_MAX); return ((int32_t) (s + w / 2)); } } if (save != NULL) *save = s; return INT32_C(-1); }
void* lsearch(void *key, void *base, int n, int elemSize, int (*cmpfn)(void *, void *)) { for (int i = 0; i < n; i++) { void *elemAddr = (char*) base + i * elemSize; if (cmpfn(key, elemAddr) == 0) return elemAddr; } return NULL; }
void* lsearch(void *key, void *base, int n, int size, int (*cmpfn)(void*, void*)) { int i; for(i = 0; i < n; ++i) { void *elemp = (char*)base + i * size; if(cmpfn(key, elemp) == 0) return elemp; } return NULL; }
void *bsearch(void *key, void *base, int n, int elemsize, int (*cmpfn)(void *, void *)) { int low = 0, high = n -1; int mid; void *elemAddr; while (low <= high) { mid = (low + high) / 2; elemAddr = (char *)base + mid * elemsize; if (cmpfn(key, elemAddr) == 0) return elemAddr; if (cmpfn(key, elemAddr) < 0) high = mid -1; if (cmpfn(key, elemAddr) > 0) low = mid + 1; } return NULL; }
/* put elem into list in correct pos */ static void put_in_order(struct List *newitem, struct StatList *list, int (*cmpfn)(struct List *, struct List *)) { int res; struct List *item; statlist_for_each(item, list) { res = cmpfn(item, newitem); if (res == 0) { fatal("put_in_order: found existing elem"); } else if (res > 0) { statlist_put_before(list, newitem, item); return; } }
void *dl_get (const DataList *dl, const void *element, CMPFN cmpfn) { int i; PR_ASSERT (dl); PR_ASSERT (element); PR_ASSERT (cmpfn); for (i = 0; i < dl->element_count; i++) { if (cmpfn (dl->elements[i], element) == 0) { return dl->elements[i]; } } return NULL; }
/* int cmpfn_str_asc(const void *ptr1, const void *ptr2) { return strcmp(ptr1, ptr2); } int cmpfn_str_dsc(const void *ptr1, const void *ptr2) { return !cmpfn_str_asc(ptr1, ptr2); } */ List *sort_list(List *L, lcomparer cmpfn) { List *tmpPtr = L; List *tmpNxt = L->next; void * tmp; while(tmpNxt != NULL){ while(tmpNxt != tmpPtr){ if( cmpfn( tmpNxt->data , tmpPtr->data) < 0){ tmp = tmpPtr->data; tmpPtr->data = tmpNxt->data; tmpNxt->data = tmp; } tmpPtr = tmpPtr->next; } tmpPtr = L; tmpNxt = tmpNxt->next; } return tmpPtr; }
void *oscap_bfind(void *ptr, size_t nmemb, size_t size, void *key, int cmpfn(void *, void *)) { size_t w, s; int cmp; uint8_t *p; w = nmemb; s = 0; p = (uint8_t *) ptr; while (w > 0) { cmp = cmpfn(key, p + (size * (s + w / 2))); if (cmp > 0) { s += w / 2 + 1; w = w - w / 2 - 1; } else if (cmp < 0) { w = w / 2; } else { return ((void *)(p + (size * (s + w / 2)))); } } return (NULL); }
// index of darray static inline int cmp_ids(darray *pda, int lid, int rid, int (*cmpfn)(const void *, const void *)) { return cmpfn(dgetp(pda, lid), dgetp(pda, rid)); }