fixedmap.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. #ifndef __FIXEDMAP_H
  2. #define __FIXEDMAP_H
  3. /*
  4. An STL map-like container. Quickly thrown together to replace STL maps
  5. in specific instances. Many gotchas. Use with caution.
  6. */
  7. #include <stdlib.h>
  8. template < class T, class U >
  9. class VVFixedMap
  10. {
  11. private:
  12. struct Data {
  13. T data;
  14. U key;
  15. };
  16. Data *items;
  17. unsigned int numItems;
  18. unsigned int maxItems;
  19. VVFixedMap(void) {}
  20. public:
  21. VVFixedMap(unsigned int maxItems)
  22. {
  23. items = new Data[maxItems];
  24. numItems = 0;
  25. this->maxItems = maxItems;
  26. }
  27. ~VVFixedMap(void)
  28. {
  29. items -= ( maxItems - numItems );
  30. delete [] items;
  31. numItems = 0;
  32. }
  33. bool Insert(const T &newItem, const U &key)
  34. {
  35. Data *storage = NULL;
  36. //Check for fullness.
  37. if(numItems >= maxItems) {
  38. assert( 0 );
  39. return false;
  40. }
  41. //Check for reuse.
  42. if(!FindUnsorted(key, storage)) {
  43. storage = items + numItems;
  44. numItems++;
  45. }
  46. else
  47. assert( 0 );
  48. storage->data = newItem;
  49. storage->key = key;
  50. return true;
  51. }
  52. // Faster version of Insert(), but it doesn't check for dupes. Used
  53. // by the filecode cache (when we know the data we're inserting is good).
  54. bool InsertUnsafe(const T &newItem, const U &key)
  55. {
  56. //Check for fullness.
  57. if(numItems >= maxItems) {
  58. return false;
  59. }
  60. Data *storage = items + numItems;
  61. numItems++;
  62. storage->data = newItem;
  63. storage->key = key;
  64. return true;
  65. }
  66. void Sort(void)
  67. {
  68. qsort(items, numItems, sizeof(Data),
  69. VVFixedMap< T, U >::FixedMapSorter);
  70. }
  71. //Binary search, items must have been sorted!
  72. T *Find(const U &key)
  73. {
  74. int i;
  75. int high;
  76. int low;
  77. for(low = -1, high = numItems; high - low > 1; ) {
  78. i = (high + low) / 2;
  79. if(key < items[i].key) {
  80. high = i;
  81. } else if(key > items[i].key) {
  82. low = i;
  83. } else {
  84. return &items[i].data;
  85. }
  86. }
  87. if(items[i+1].key == key) {
  88. return &items[i+1].data;
  89. } else if(items[i-1].key == key) {
  90. return &items[i-1].data;
  91. }
  92. return NULL;
  93. }
  94. //Slower, but don't need to call sort first.
  95. T *FindUnsorted(const U &key, Data *&storage)
  96. {
  97. int i;
  98. for(i=0; i<numItems; i++) {
  99. if(items[i].key == key) {
  100. storage = items + i;
  101. return &items[i].data;
  102. }
  103. }
  104. return NULL;
  105. }
  106. // returns the top item's data
  107. // and removes the item from the map
  108. T *Pop(void)
  109. {
  110. T* top = NULL;
  111. if(numItems)
  112. {
  113. top = &items[0].data;
  114. items++;
  115. numItems--;
  116. }
  117. return top;
  118. }
  119. static int FixedMapSorter(const void *a, const void *b)
  120. {
  121. if(((Data*)a)->key > ((Data*)b)->key) {
  122. return 1;
  123. } else if(((Data*)a)->key == ((Data*)b)->key) {
  124. return 0;
  125. } else {
  126. return -1;
  127. }
  128. }
  129. };
  130. #endif