12 #include "../../stdafx.h"
13 #include "../../core/alloc_func.hpp"
16 #include "../../safeguards.h"
26 const int BinaryHeap::BINARY_HEAP_BLOCKSIZE_MASK = BinaryHeap::BINARY_HEAP_BLOCKSIZE - 1;
39 for (i = 0; i < this->
blocks; i++) {
40 if (this->elements[i] == NULL) {
49 (this->size & BINARY_HEAP_BLOCKSIZE_MASK) == j) {
52 free(this->elements[i][j].item);
57 free(this->elements[i]);
58 this->elements[i] = NULL;
74 this->
Clear(free_values);
75 for (i = 0; i < this->
blocks; i++) {
76 if (this->elements[i] == NULL)
break;
77 free(this->elements[i]);
88 if (this->size == this->max_size)
return false;
89 assert(this->size < this->max_size);
93 assert((this->size & BINARY_HEAP_BLOCKSIZE_MASK) == 0);
99 this->
GetElement(this->size + 1).priority = priority;
141 if (this->
GetElement(i + 1).item == item)
break;
143 }
while (i < this->size);
145 if (i == this->size)
return false;
164 if (2 * j + 1 <= this->size) {
171 }
else if (2 * j <= this->size) {
198 if (this->size == 0)
return NULL;
214 this->max_size = max_size;
218 this->elements = CallocT<BinaryHeapNode*>((max_size - 1) / BINARY_HEAP_BLOCKSIZE + 1);
219 this->elements[0] = MallocT<BinaryHeapNode>(BINARY_HEAP_BLOCKSIZE);
244 this->num_buckets = num_buckets;
245 this->buckets = (
HashNode*)MallocT<byte>(num_buckets * (
sizeof(*this->buckets) +
sizeof(*this->buckets_in_use)));
246 this->buckets_in_use = (
bool*)(this->buckets + num_buckets);
247 for (i = 0; i < num_buckets; i++) this->buckets_in_use[i] =
false;
260 for (i = 0; i < this->num_buckets; i++) {
261 if (this->buckets_in_use[i]) {
265 if (free_values)
free(this->buckets[i].value);
266 node = this->buckets[i].next;
267 while (node != NULL) {
272 if (free_values)
free(prev->value);
284 void Hash::PrintStatistics()
const
286 uint used_buckets = 0;
287 uint max_collision = 0;
292 for (i = 0; i <
lengthof(usage); i++) usage[i] = 0;
293 for (i = 0; i < this->num_buckets; i++) {
295 if (this->buckets_in_use[i]) {
299 for (node = &this->buckets[i]; node != NULL; node = node->next) collision++;
300 if (collision > max_collision) max_collision = collision;
304 if (collision > 0 && usage[collision] >= max_usage) {
305 max_usage = usage[collision];
312 "Non empty buckets: %d\n"
313 "Max collision: %d\n",
314 this->num_buckets, this->size, used_buckets, max_collision
317 for (i = 0; i <= max_collision; i++) {
319 printf(
"%d:%d ", i, usage[i]);
324 for (j = 0; j < usage[i] * 160 / 800; j++) putchar(
'#');
342 if (this->size > 2000) this->PrintStatistics();
346 for (i = 0; i < this->num_buckets; i++) {
347 if (this->buckets_in_use[i]) {
350 this->buckets_in_use[i] =
false;
352 if (free_values)
free(this->buckets[i].value);
353 node = this->buckets[i].next;
354 while (node != NULL) {
358 if (free_values)
free(prev->value);
376 uint hash = this->hash(key1, key2);
380 if (!this->buckets_in_use[hash]) {
381 if (prev_out != NULL) *prev_out = NULL;
384 }
else if (this->buckets[hash].key1 == key1 && this->buckets[hash].key2 == key2) {
386 result = this->buckets + hash;
387 if (prev_out != NULL) *prev_out = NULL;
390 HashNode *prev = this->buckets + hash;
393 for (node = prev->next; node != NULL; node = node->next) {
394 if (node->key1 == key1 && node->key2 == key2) {
401 if (prev_out != NULL) *prev_out = prev;
420 }
else if (prev == NULL) {
424 result = node->value;
425 if (node->next != NULL) {
434 uint hash = this->hash(key1, key2);
435 this->buckets_in_use[hash] =
false;
440 result = node->value;
442 prev->next = node->next;
446 if (result != NULL) this->size--;
461 void *result = node->value;
469 uint hash = this->hash(key1, key2);
470 this->buckets_in_use[hash] =
true;
471 node = this->buckets + hash;
474 node = MallocT<HashNode>(1);
493 return (node != NULL) ? node->value : NULL;