sparse_bsearch.c 854 B

1234567891011121314151617181920212223242526272829303132333435363738
  1. /* Licensed under LGPLv2+ - see LICENSE file for details */
  2. #include <sys/types.h> //for ssize_t definition
  3. #include "sparse_bsearch.h"
  4. void *_sparse_bsearch(const void *key, const void *base,
  5. size_t nmemb, size_t size,
  6. int (*cmpfn)(const void *, const void *),
  7. bool (*validfn)(const void *))
  8. {
  9. ssize_t start = 0, end = nmemb - 1;
  10. const char *p = base;
  11. while (start <= end) {
  12. ssize_t next = (start + end) / 2;
  13. int result;
  14. while (!validfn(p + next * size)) {
  15. /* Try the next one along. */
  16. next++;
  17. if (next > end) {
  18. /* Hmm, none of these were valid. */
  19. next = (start + end) / 2;
  20. goto trim;
  21. }
  22. }
  23. result = cmpfn(key, p + next * size);
  24. if (result == 0)
  25. return (void *)(p + next * size);
  26. else if (result > 0)
  27. start = next + 1;
  28. else {
  29. trim:
  30. end = next - 1;
  31. }
  32. }
  33. return NULL;
  34. }