7 void _set_init(Set
* set
, size_t dataSize
, size_t hashSize
,
8 UInt (*getHash
)(void*, size_t))
10 set
->hashSize
= hashSize
;
11 set
->dataSize
= dataSize
;
12 set
->head
= safe_malloc(hashSize
* sizeof(SetCell
*));
13 for (UInt i
= 0; i
< hashSize
; i
++)
16 set
->getHash
= getHash
; //may be NULL
19 Set
* _set_new(size_t dataSize
, size_t hashSize
, UInt (*getHash
)(void*, size_t))
21 Set
* set
= (Set
*) safe_malloc(sizeof(Set
));
22 _set_init(set
, dataSize
, hashSize
, getHash
);
26 Set
* set_copy(Set
* set
)
28 Set
* setCopy
= _set_new(set
->dataSize
, set
->hashSize
, set
->getHash
);
29 setCopy
->size
= set
->size
;
30 for (UInt i
= 0; i
< set
->hashSize
; i
++)
32 SetCell
*cell
= set
->head
[i
],
33 *cellCopy
= setCopy
->head
[i
],
37 // cellCopy == NULL (from empty list)
38 cellCopy
= (SetCell
*) safe_malloc(sizeof(SetCell
));
39 cellCopy
->item
= safe_malloc(set
->dataSize
);
40 memcpy(cellCopy
->item
, cell
->item
, set
->dataSize
);
42 setCopy
->head
[i
] = cellCopy
;
44 prev
->next
= cellCopy
;
48 if (cellCopy
!= NULL
) cellCopy
->next
= NULL
;
53 bool set_empty(Set
* set
)
55 return (set
->size
== 0);
58 UInt
set_size(Set
* set
)
63 // Function (string) key --> (integer) hash [internal usage]
64 // Default function. Can be changed (see hashtable_new())
65 UInt
_set_compute_hash(void* key
, size_t dataSize
, size_t hashSize
)
68 // Interpret the bytes in key as a piece of string
69 unsigned char* keyStr
= (unsigned char*)key
;
70 for (size_t i
= 0; i
< dataSize
; i
++)
71 // NOTE: '31' from here https://stackoverflow.com/a/4384446
72 res
= (*(keyStr
+i
) + 31 * res
) % hashSize
;
76 // Get hash index from key [internal usage]
77 UInt
_set_get_hindex(Set
* set
, void* key
)
79 if (set
->getHash
== NULL
)
80 return _set_compute_hash(key
, set
->dataSize
, set
->hashSize
);
81 return set
->getHash(key
, set
->hashSize
);
84 bool set_has(Set
* set
, void* item
)
86 UInt hashIdx
= _set_get_hindex(set
, item
);
87 SetCell
* cell
= set
->head
[hashIdx
];
90 if (memcmp(cell
->item
, item
, set
->dataSize
) == 0)
97 void _set_add(Set
* set
, void* item
)
99 UInt hashIdx
= _set_get_hindex(set
, item
);
100 SetCell
*cell
= set
->head
[hashIdx
],
104 if (memcmp(cell
->item
, item
, set
->dataSize
) == 0)
105 // Already here: nothing to do
110 // New element: insert after prev (which may be NULL)
111 SetCell
* newCell
= (SetCell
*) safe_malloc(sizeof(SetCell
));
112 newCell
->item
= safe_malloc(set
->dataSize
);
113 memcpy(newCell
->item
, item
, set
->dataSize
);
114 newCell
->next
= NULL
;
116 set
->head
[hashIdx
] = newCell
;
118 prev
->next
= newCell
;
122 void _set_delete(Set
* set
, void* item
)
124 UInt hashIdx
= _set_get_hindex(set
, item
);
125 SetCell
*cell
= set
->head
[hashIdx
],
129 if (memcmp(cell
->item
, item
, set
->dataSize
) == 0)
132 set
->head
[hashIdx
] = cell
->next
;
134 prev
->next
= cell
->next
;
135 safe_free(cell
->item
);
145 Vector
* set_to_vector(Set
* set
) {
146 Vector
* v
= _vector_new(set
->dataSize
);
147 for (UInt i
= 0; i
< set
->hashSize
; i
++) {
148 SetCell
* cell
= set
->head
[i
];
149 while (cell
!= NULL
) {
150 _vector_push(v
, cell
->item
);
157 void set_clear(Set
* set
)
159 for (UInt i
= 0; i
< set
->hashSize
; i
++)
161 SetCell
* cell
= set
->head
[i
];
164 SetCell
* next
= cell
->next
;
165 safe_free(cell
->item
);
174 void set_destroy(Set
* set
)
177 safe_free(set
->head
);