qunique.h 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. /*-------------------------------------------------------------------------
  2. *
  3. * qunique.h
  4. * inline array unique functions
  5. * Portions Copyright (c) 2019-2022, PostgreSQL Global Development Group
  6. *
  7. * IDENTIFICATION
  8. * src/include/lib/qunique.h
  9. *-------------------------------------------------------------------------
  10. */
  11. #ifndef QUNIQUE_H
  12. #define QUNIQUE_H
  13. /*
  14. * Remove duplicates from a pre-sorted array, according to a user-supplied
  15. * comparator. Usually the array should have been sorted with qsort() using
  16. * the same arguments. Return the new size.
  17. */
  18. static inline size_t
  19. qunique(void *array, size_t elements, size_t width,
  20. int (*compare) (const void *, const void *))
  21. {
  22. char *bytes = (char *) array;
  23. size_t i,
  24. j;
  25. if (elements <= 1)
  26. return elements;
  27. for (i = 1, j = 0; i < elements; ++i)
  28. {
  29. if (compare(bytes + i * width, bytes + j * width) != 0 &&
  30. ++j != i)
  31. memcpy(bytes + j * width, bytes + i * width, width);
  32. }
  33. return j + 1;
  34. }
  35. /*
  36. * Like qunique(), but takes a comparator with an extra user data argument
  37. * which is passed through, for compatibility with qsort_arg().
  38. */
  39. static inline size_t
  40. qunique_arg(void *array, size_t elements, size_t width,
  41. int (*compare) (const void *, const void *, void *),
  42. void *arg)
  43. {
  44. char *bytes = (char *) array;
  45. size_t i,
  46. j;
  47. if (elements <= 1)
  48. return elements;
  49. for (i = 1, j = 0; i < elements; ++i)
  50. {
  51. if (compare(bytes + i * width, bytes + j * width, arg) != 0 &&
  52. ++j != i)
  53. memcpy(bytes + j * width, bytes + i * width, width);
  54. }
  55. return j + 1;
  56. }
  57. #endif /* QUNIQUE_H */