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;