home *** CD-ROM | disk | FTP | other *** search
/ Resource Library: Graphics / graphics-16000.iso / msdos / raytrace / dkb / dump2iff.lzh / showprioq.c < prev    next >
C/C++ Source or Header  |  1991-06-08  |  6KB  |  220 lines

  1. /*****************************************************************************
  2. *
  3. *                                  showprioq.c
  4. *
  5. *   from DKBTrace (c) 1990  David Buck
  6. *
  7. *  This file manages a priority queue for dump2iff
  8. *
  9. * This software is freely distributable. The source and/or object code may be
  10. * copied or uploaded to communications services so long as this notice remains
  11. * at the top of each file.  If any changes are made to the program, you must
  12. * clearly indicate in the documentation and in the programs startup message
  13. * who it was who made the changes. The documentation should also describe what
  14. * those changes were. This software may not be included in whole or in
  15. * part into any commercial package without the express written consent of the
  16. * author.  It may, however, be included in other public domain or freely
  17. * distributed software so long as the proper credit for the software is given.
  18. *
  19. * This software is provided as is without any guarantees or warranty. Although
  20. * the author has attempted to find and correct any bugs in the software, he
  21. * is not responsible for any damage caused by the use of the software.  The
  22. * author is under no obligation to provide service, corrections, or upgrades
  23. * to this package.
  24. *
  25. * Despite all the legal stuff above, if you do find bugs, I would like to hear
  26. * about them.  Also, if you have any comments or questions, you may contact me
  27. * at the following address:
  28. *
  29. *     David Buck
  30. *     22C Sonnet Cres.
  31. *     Nepean Ontario
  32. *     Canada, K2H 8W7
  33. *
  34. *  I can also be reached on the following bulleton boards:
  35. *
  36. *     OMX              (613) 731-3419
  37. *     Mystic           (613) 596-4249  or  (613) 596-4772
  38. *
  39. *  Fidonet:   1:163/109.9
  40. *  Internet:  dbuck@ccs.carleton.ca
  41. *  You Can Call Me Ray: (708) 358-5611
  42. *
  43. *
  44. *****************************************************************************/
  45.  
  46.  
  47. #include <stdio.h>
  48. #include <exec/types.h>
  49. #include "showprioq.h"
  50. #include "dump2iff.h"
  51. #include "dumproto.h"
  52.  
  53. char *malloc();
  54.  
  55.  
  56. struct prioq_struct *pq_new (index_size, value_size)
  57.   int index_size, value_size;
  58.   {
  59.   struct prioq_struct *pq;
  60.   unsigned char *tmp_array;
  61.   int i;
  62.  
  63.   if (index_size > 256)
  64.     return (NULL);
  65.  
  66.   if ((pq = (struct prioq_struct *) malloc
  67.         (sizeof (struct prioq_struct))) == NULL)
  68.     return (NULL);
  69.  
  70.   if ((pq -> queue = (struct q_entry *)
  71.                   malloc (index_size * sizeof (struct q_entry))) == NULL)  {
  72.     free (pq);
  73.     return (NULL);
  74.     }
  75.     
  76.   if ((pq -> array = (unsigned char *) malloc (value_size)) == NULL) {
  77.     free (pq -> queue);
  78.     free (pq);
  79.     return (NULL);
  80.     }
  81.  
  82.   for (i=0, tmp_array = pq -> array ; i<value_size ; i++, tmp_array++)
  83.     *tmp_array = 0;
  84.  
  85.   pq -> queue_size = index_size;
  86.   pq -> array_size = value_size;
  87.   pq -> current_entry = 0;
  88.   return (pq);
  89.   }
  90.  
  91. void pq_add (q, index, value)
  92.   struct prioq_struct *q;
  93.   unsigned int index, value;
  94.   {
  95.   unsigned int existing_entry;
  96.  
  97.   if (value >= q -> array_size)
  98.     return;
  99.  
  100.   if ((existing_entry = pq_find_value(q, value)) != 0) {
  101.     if ((q -> queue[existing_entry].index) < index)
  102.       (q -> queue[existing_entry].index) = index;
  103.     pq_balance (q, existing_entry);
  104.     }
  105.   else {
  106.     q -> current_entry++;
  107.     if (q -> current_entry >= q -> queue_size) {
  108.       q -> current_entry--;
  109.       q -> array [q->queue[q->current_entry].value] = 0;
  110.       }
  111.  
  112.     q -> queue [q -> current_entry].index = index;
  113.     q -> queue [q -> current_entry].value = value;
  114.     q -> array [value] = q -> current_entry;
  115.     pq_balance (q, q -> current_entry);
  116.     }
  117.   return;
  118.   }
  119.     
  120. int pq_find_value (q, value)
  121.   struct prioq_struct *q;
  122.   unsigned int value;
  123.   {
  124.   if (value < q -> array_size)
  125.     return ((int) q -> array[value]);
  126.   else
  127.     return (0);
  128.   }
  129.  
  130. void pq_balance(q, entry_pos1)
  131.   struct prioq_struct *q;
  132.   unsigned int entry_pos1;
  133.   {
  134.   register struct q_entry *entry1, *entry2;
  135.   register unsigned int tmp_index, tmp_value, entry_pos2;
  136.  
  137.   entry1 = &q->queue[entry_pos1];
  138.  
  139.   if ((entry_pos1 * 2 < q->queue_size)
  140.       && (entry_pos1 * 2 <= q -> current_entry))
  141.     {
  142.     if ((entry_pos1*2+1 > q->current_entry) ||
  143.         (q->queue[entry_pos1*2].index > q->queue[entry_pos1*2+1].index))
  144.       entry_pos2 = entry_pos1*2;
  145.     else
  146.       entry_pos2 = entry_pos1*2+1;
  147.  
  148.     entry2 = &q->queue[entry_pos2];
  149.  
  150.     if (entry1->index < entry2->index) {
  151.       q -> array [entry1->value] = entry_pos2;
  152.       q -> array [entry2->value] = entry_pos1;
  153.  
  154.       tmp_index = entry1->index;
  155.       entry1->index = entry2->index;
  156.       entry2->index = tmp_index;
  157.  
  158.       tmp_value = entry1->value;
  159.       entry1->value = entry2->value;
  160.       entry2->value = tmp_value;
  161.  
  162.       pq_balance (q, entry_pos2);
  163.       }
  164.     }
  165.  
  166.   if (entry_pos1 / 2 >= 1 )
  167.     {
  168.     entry_pos2 = entry_pos1 / 2;
  169.     entry2 = &q->queue[entry_pos2];
  170.     if (entry1->index > entry2->index) {
  171.       q -> array [entry1->value] = entry_pos2;
  172.       q -> array [entry2->value] = entry_pos1;
  173.  
  174.       tmp_index = entry1->index;
  175.       entry1->index = entry2->index;
  176.       entry2->index = tmp_index;
  177.  
  178.       tmp_value = entry1->value;
  179.       entry1->value = entry2->value;
  180.       entry2->value = tmp_value;
  181.  
  182.       pq_balance (q, entry_pos2);
  183.       }
  184.     }
  185.   }
  186.  
  187. int pq_get_highest_index(q)
  188.   struct prioq_struct *q;
  189.   {
  190.   if (q -> current_entry >= 1)
  191.     return ((int) q -> queue[1].index);
  192.   else
  193.     return (0);
  194.   }
  195.  
  196. int pq_get_highest_value(q)
  197.   struct prioq_struct *q;
  198.   {
  199.   if (q -> current_entry >= 1)
  200.     return ((int) q -> queue[1].value);
  201.   else
  202.     return (0);
  203.   }
  204.  
  205. void pq_delete_highest (q)
  206.   struct prioq_struct *q;
  207.   {
  208.   q -> queue[1].index = q -> queue[q -> current_entry].index;
  209.   q -> queue[1].value = q -> queue[q -> current_entry--].value;
  210.   pq_balance (q, 1);
  211.   }
  212.  
  213. void pq_free (q)
  214.   struct prioq_struct *q;
  215.   {
  216.   free (q ->queue);
  217.   free (q -> array);
  218.   free (q);
  219.   }
  220.