xs_set.h 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /* copyright (c) 2022 grunfink - MIT license */
  2. #ifndef _XS_SET_H
  3. #define _XS_SET_H
  4. typedef struct _xs_set {
  5. int elems; /* number of hash entries */
  6. int used; /* number of used hash entries */
  7. d_char *list; /* list of stored data */
  8. int hash[0]; /* hashed offsets */
  9. } xs_set;
  10. xs_set *xs_set_new(int elems);
  11. void xs_set_free(xs_set *s);
  12. int xs_set_add(xs_set *s, char *data);
  13. #ifdef XS_IMPLEMENTATION
  14. xs_set *xs_set_new(int elems)
  15. /* creates a new set with a maximum of size hashed data */
  16. {
  17. int sz = sizeof(struct _xs_set) + sizeof(int) * elems;
  18. xs_set *s = calloc(sz, 1);
  19. /* initialize */
  20. s->elems = elems;
  21. s->list = xs_list_new();
  22. return s;
  23. }
  24. void xs_set_free(xs_set *s)
  25. /* frees a set */
  26. {
  27. free(s->list);
  28. free(s);
  29. }
  30. unsigned int _xs_set_hash(char *data, int size)
  31. {
  32. unsigned int hash = 0x666;
  33. int n;
  34. for (n = 0; n < size; n++) {
  35. hash ^= data[n];
  36. hash *= 111111111;
  37. }
  38. return hash ^ hash >> 16;
  39. }
  40. int xs_set_add(xs_set *s, char *data)
  41. /* adds the data to the set */
  42. /* returns: 1 if added, 0 if already there, -1 if it's full */
  43. {
  44. unsigned int hash, i;
  45. int sz = xs_size(data);
  46. hash = _xs_set_hash(data, sz);
  47. while (s->hash[(i = hash % s->elems)]) {
  48. /* get the pointer to the stored data */
  49. char *p = &s->list[s->hash[i]];
  50. /* already here? */
  51. if (memcmp(p, data, sz) == 0)
  52. return 0;
  53. /* try next value */
  54. hash++;
  55. }
  56. /* is it full? fail */
  57. if (s->used == s->elems / 2)
  58. return -1;
  59. /* store the position */
  60. s->hash[i] = xs_size(s->list);
  61. /* add the data */
  62. s->list = xs_list_append_m(s->list, data, sz);
  63. s->used++;
  64. return 1;
  65. }
  66. #endif /* XS_IMPLEMENTATION */
  67. #endif /* XS_SET_H */