MinMaxTree.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. #pragma once
  2. #include "MASTER.h"
  3. #include "GLOBAL.h"
  4. #include "SzlFileLoader.h"
  5. #include "fileStuff.h"
  6. #include "importSzPltFile.h"
  7. #include "RawArray.h"
  8. #include "readValueArray.h"
  9. namespace tecplot
  10. {
  11. namespace ___3933
  12. {
  13. class MinMaxTree
  14. {
  15. UNCOPYABLE_CLASS(MinMaxTree);
  16. public:
  17. typedef uint32_t EntryIndex_t;
  18. private:
  19. static EntryIndex_t const CHILDREN_BITS_PER_PARENT = 6;
  20. static EntryIndex_t const NUM_CHILDREN_PER_PARENT = (1 << CHILDREN_BITS_PER_PARENT);
  21. static EntryIndex_t const MAX_DEPTH = (24 + CHILDREN_BITS_PER_PARENT - 1) / CHILDREN_BITS_PER_PARENT;
  22. static size_t const MIN_ENTRIES_TO_ALLOCATE = 32;
  23. static size_t const ALLOCATION_EXPANSION_FACTOR = 2;
  24. ___2240<___2481> m_minMaxArraysByDepth;
  25. #ifndef NO_ASSERTS
  26. EntryIndex_t m_size;
  27. #endif
  28. public:
  29. MinMaxTree()
  30. {
  31. #ifndef NO_ASSERTS
  32. m_size = 0;
  33. #endif
  34. }
  35. ~MinMaxTree() {}
  36. inline void swap(MinMaxTree &___2888)
  37. {
  38. ASSERT_ONLY(___372 const thisWasEmpty = this->empty();)
  39. ASSERT_ONLY(___372 const thisWasValidlyPopulated = this->isValidlyPopulated(EntryIndex_t(this->size()));) ASSERT_ONLY(___372 const otherWasEmpty = ___2888.empty();) ASSERT_ONLY(___372 const otherWasValidlyPopulated = ___2888.isValidlyPopulated(EntryIndex_t(___2888.size()));) m_minMaxArraysByDepth.swap(___2888.m_minMaxArraysByDepth);
  40. #ifndef NO_ASSERTS
  41. using std::swap;
  42. swap(m_size, ___2888.m_size);
  43. #endif
  44. ENSURE(EQUIVALENCE(thisWasEmpty, ___2888.empty()));
  45. ENSURE(EQUIVALENCE(thisWasValidlyPopulated, ___2888.isValidlyPopulated(EntryIndex_t(___2888.size()))));
  46. ENSURE(EQUIVALENCE(otherWasEmpty, this->empty()));
  47. ENSURE(EQUIVALENCE(otherWasValidlyPopulated, this->isValidlyPopulated(EntryIndex_t(this->size()))));
  48. }
  49. static EntryIndex_t getNumEntriesAtDepth(EntryIndex_t ___2795, EntryIndex_t depth)
  50. {
  51. REQUIRE(___2795 > 0);
  52. REQUIRE(depth <= MAX_DEPTH);
  53. EntryIndex_t const shift = depth * CHILDREN_BITS_PER_PARENT;
  54. EntryIndex_t const ___3358 = ((___2795 - 1) >> shift) + 1;
  55. return ___3358;
  56. }
  57. ___372 empty() const
  58. {
  59. ___372 const isEmpty = m_minMaxArraysByDepth.empty();
  60. ENSURE(VALID_BOOLEAN(isEmpty));
  61. ENSURE(EQUIVALENCE(isEmpty, m_size == 0));
  62. return isEmpty;
  63. }
  64. ___372 isPopulated() const { return !empty() && m_minMaxArraysByDepth[MAX_DEPTH - 1][0].___2067(); }
  65. #ifndef NO_ASSERTS
  66. size_t size() const
  67. {
  68. REQUIRE(EQUIVALENCE(m_size == 0, m_minMaxArraysByDepth.empty()));
  69. REQUIRE(IMPLICATION(m_size > 0, m_size == m_minMaxArraysByDepth[0].size()));
  70. return m_size;
  71. }
  72. ___372 isValidlyPopulated(EntryIndex_t ___2795) const
  73. {
  74. REQUIRE(___2795 == m_size);
  75. return m_minMaxArraysByDepth.size() == MAX_DEPTH && m_minMaxArraysByDepth[0].size() == ___2795 && m_minMaxArraysByDepth[0][0].___2067() && m_minMaxArraysByDepth[0][___2795 / 2].___2067() && m_minMaxArraysByDepth[0][___2795 - 1].___2067() && m_minMaxArraysByDepth[MAX_DEPTH / 2].size() == getNumEntriesAtDepth(___2795, MAX_DEPTH / 2) && m_minMaxArraysByDepth[MAX_DEPTH / 2][0].___2067() && m_minMaxArraysByDepth[MAX_DEPTH / 2][getNumEntriesAtDepth(___2795, MAX_DEPTH / 2) / 2].___2067() && m_minMaxArraysByDepth[MAX_DEPTH / 2][getNumEntriesAtDepth(___2795, MAX_DEPTH / 2) - 1].___2067() && m_minMaxArraysByDepth[MAX_DEPTH - 1].size() == getNumEntriesAtDepth(___2795, MAX_DEPTH - 1) && m_minMaxArraysByDepth[MAX_DEPTH - 1][0].___2067() && m_minMaxArraysByDepth[MAX_DEPTH - 1][getNumEntriesAtDepth(___2795, MAX_DEPTH - 1) / 2].___2067() && m_minMaxArraysByDepth[MAX_DEPTH - 1][getNumEntriesAtDepth(___2795, MAX_DEPTH - 1) - 1].___2067();
  76. }
  77. #endif
  78. public:
  79. uint64_t numBytesAllocated(uint64_t ___2795) const
  80. {
  81. REQUIRE(___2795 == m_size);
  82. uint64_t ___2779 = m_minMaxArraysByDepth.numBytesAllocated(MAX_DEPTH);
  83. if (!m_minMaxArraysByDepth.empty())
  84. {
  85. for (EntryIndex_t depth = 0; depth < MAX_DEPTH; depth++)
  86. {
  87. EntryIndex_t const numEntriesAtDepth = getNumEntriesAtDepth(EntryIndex_t(___2795), depth);
  88. ___2779 += m_minMaxArraysByDepth[depth].numBytesAllocated(numEntriesAtDepth);
  89. }
  90. }
  91. return ___2779;
  92. }
  93. ___372 allocUninitialized(EntryIndex_t ___2795)
  94. {
  95. REQUIRE(___2795 > 0);
  96. #ifndef NO_ASSERTS
  97. m_size = ___2795;
  98. #endif
  99. ___372 ___2039 = m_minMaxArraysByDepth.alloc(MAX_DEPTH);
  100. for (EntryIndex_t depth = 0; ___2039 && depth < MAX_DEPTH; ++depth)
  101. {
  102. EntryIndex_t const numEntiresAtDepth = getNumEntriesAtDepth(___2795, depth);
  103. ___2039 = m_minMaxArraysByDepth[depth].alloc(numEntiresAtDepth);
  104. }
  105. if (!___2039)
  106. ___937();
  107. ENSURE(VALID_BOOLEAN(___2039));
  108. ENSURE(EQUIVALENCE(___2039, !m_minMaxArraysByDepth.empty()));
  109. ENSURE(IMPLICATION(___2039, !m_minMaxArraysByDepth[0].empty()));
  110. return ___2039;
  111. }
  112. void initializeWithInvalidMinMaxes(EntryIndex_t ___2795)
  113. {
  114. REQUIRE(___2795 > 0 && ___2795 == m_size);
  115. REQUIRE(m_minMaxArraysByDepth.size() == MAX_DEPTH);
  116. ___478(___2795 == getNumEntriesAtDepth(___2795, 0));
  117. for (EntryIndex_t depth = 0; depth < MAX_DEPTH; ++depth)
  118. {
  119. EntryIndex_t const numEntiresAtDepth = getNumEntriesAtDepth(___2795, depth);
  120. ___2481 &___2480 = m_minMaxArraysByDepth[depth];
  121. for (EntryIndex_t entry = 0; entry < numEntiresAtDepth; entry++)
  122. ___2480[entry].invalidate();
  123. }
  124. ENSURE(!m_minMaxArraysByDepth[0][0].___2067() && !m_minMaxArraysByDepth[0][___2795 / 2].___2067() && !m_minMaxArraysByDepth[0][___2795 - 1].___2067() && !m_minMaxArraysByDepth[MAX_DEPTH - 1][0].___2067());
  125. ENSURE(!isPopulated());
  126. }
  127. void ___937()
  128. {
  129. m_minMaxArraysByDepth.___937();
  130. #ifndef NO_ASSERTS
  131. m_size = 0;
  132. #endif
  133. }
  134. void getChildRangeUsingNumEntries(EntryIndex_t parentPos, EntryIndex_t numEntriesAtChildDepth, EntryIndex_t &childStart, EntryIndex_t &childEnd) const
  135. {
  136. REQUIRE(numEntriesAtChildDepth > 0);
  137. REQUIRE(parentPos < numEntriesAtChildDepth * NUM_CHILDREN_PER_PARENT);
  138. childStart = parentPos << CHILDREN_BITS_PER_PARENT;
  139. ___478(childStart == parentPos * NUM_CHILDREN_PER_PARENT);
  140. childEnd = std::min(childStart + NUM_CHILDREN_PER_PARENT, numEntriesAtChildDepth);
  141. ENSURE(childStart < childEnd);
  142. ENSURE(childEnd <= numEntriesAtChildDepth);
  143. }
  144. void getChildRange(EntryIndex_t ___2795, EntryIndex_t parentDepth, EntryIndex_t parentPos, EntryIndex_t &childStart, EntryIndex_t &childEnd) const
  145. {
  146. REQUIRE(___2795 == m_size);
  147. REQUIRE(isValidlyPopulated(___2795));
  148. REQUIRE(parentDepth > 0);
  149. REQUIRE(parentDepth <= MAX_DEPTH);
  150. REQUIRE(parentPos < getNumEntriesAtDepth(___2795, parentDepth));
  151. EntryIndex_t const childDepth = parentDepth - 1;
  152. EntryIndex_t const numEntriesAtChildDepth = getNumEntriesAtDepth(___2795, childDepth);
  153. getChildRangeUsingNumEntries(parentPos, numEntriesAtChildDepth, childStart, childEnd);
  154. ENSURE(childStart < childEnd);
  155. ENSURE(childEnd <= getNumEntriesAtDepth(___2795, childDepth));
  156. }
  157. ___2479 const &getMinMaxAtDepth(EntryIndex_t depth, EntryIndex_t pos) const
  158. {
  159. REQUIRE(depth < MAX_DEPTH);
  160. REQUIRE(pos < m_minMaxArraysByDepth[depth].size());
  161. REQUIRE(!m_minMaxArraysByDepth[depth].empty());
  162. ___2479 const &minMax = m_minMaxArraysByDepth[depth][pos];
  163. ENSURE(minMax.___2067());
  164. return minMax;
  165. }
  166. bool minMaxIsValidForEntry(EntryIndex_t entry) const
  167. {
  168. REQUIRE(entry < size());
  169. bool const ___2067 = m_minMaxArraysByDepth[0][entry].___2067();
  170. return ___2067;
  171. }
  172. ___2479 const &___1759(EntryIndex_t entry) const
  173. {
  174. REQUIRE(entry < size());
  175. ___2479 const &minMax = m_minMaxArraysByDepth[0][entry];
  176. ENSURE(minMax.___2067());
  177. return minMax;
  178. }
  179. void ___3499(EntryIndex_t entry, double minVal, double maxVal)
  180. {
  181. REQUIRE(entry < size());
  182. REQUIRE(minVal <= maxVal);
  183. m_minMaxArraysByDepth[0][entry].___3499(minVal, maxVal);
  184. ENSURE(m_minMaxArraysByDepth[0][entry].___2067());
  185. }
  186. void ___3499(EntryIndex_t entry, ___2479 const &minMax)
  187. {
  188. REQUIRE(entry < size());
  189. REQUIRE(minMax.___2067());
  190. m_minMaxArraysByDepth[0][entry].___3499(minMax);
  191. ENSURE(m_minMaxArraysByDepth[0][entry].___2067());
  192. }
  193. void populateTree(EntryIndex_t ___2795);
  194. ___372 populateTreeFromMinMax(___2479 const &minMax)
  195. {
  196. ___372 ___2039 = allocUninitialized(1);
  197. if (___2039)
  198. {
  199. m_minMaxArraysByDepth[0][0] = minMax;
  200. populateTree(1);
  201. }
  202. else
  203. ___937();
  204. ENSURE(IMPLICATION(___2039, isValidlyPopulated(1)));
  205. ENSURE(IMPLICATION(___2039, isPopulated()));
  206. ENSURE(IMPLICATION(!___2039, empty()));
  207. return ___2039;
  208. }
  209. ___372 populateTreeFromFile(___1399 &file, FieldDataType_e ___1363, EntryIndex_t ___2795, IODescription const &___972)
  210. {
  211. REQUIRE(___2795 > 0);
  212. ___372 ___2039 = allocUninitialized(___2795);
  213. switch (___1363)
  214. {
  215. case FieldDataType_Float:
  216. ___2039 = ___2039 && readMinMaxArray<float>(file, 0, ___2795, m_minMaxArraysByDepth[0], ___972);
  217. break;
  218. case FieldDataType_Double:
  219. ___2039 = ___2039 && readMinMaxArray<double>(file, 0, ___2795, m_minMaxArraysByDepth[0], ___972);
  220. break;
  221. case FieldDataType_Int32:
  222. ___2039 = ___2039 && readMinMaxArray<int32_t>(file, 0, ___2795, m_minMaxArraysByDepth[0], ___972);
  223. break;
  224. case FieldDataType_Int16:
  225. ___2039 = ___2039 && readMinMaxArray<int16_t>(file, 0, ___2795, m_minMaxArraysByDepth[0], ___972);
  226. break;
  227. case FieldDataType_Byte:
  228. case ___1365:
  229. ___2039 = ___2039 && readMinMaxArray<uint8_t>(file, 0, ___2795, m_minMaxArraysByDepth[0], ___972);
  230. break;
  231. default:
  232. ___478(___1305);
  233. ___2039 = ___1305;
  234. break;
  235. }
  236. if (___2039)
  237. populateTree(___2795);
  238. else
  239. ___937();
  240. ENSURE(IMPLICATION(___2039, isValidlyPopulated(___2795)));
  241. ENSURE(IMPLICATION(___2039, isPopulated()));
  242. ENSURE(IMPLICATION(!___2039, empty()));
  243. return ___2039;
  244. }
  245. static void findEntriesContainingNVarValues(___3269<MinMaxTree const *> const &minMaxTrees, ___3269<double> const &vals, EntryIndex_t ___2795, ___2090::___2980 ___2977, ___3269<___2090::SubzoneAddress> &entryAddresses)
  246. {
  247. size_t const numTrees = minMaxTrees.size();
  248. REQUIRE(!minMaxTrees.empty());
  249. REQUIRE(VALID_REF(minMaxTrees[0]) && minMaxTrees[0]->isValidlyPopulated(___2795));
  250. REQUIRE(VALID_REF(minMaxTrees[numTrees / 2]) && minMaxTrees[numTrees / 2]->isValidlyPopulated(___2795));
  251. REQUIRE(VALID_REF(minMaxTrees[numTrees - 1]) && minMaxTrees[numTrees - 1]->isValidlyPopulated(___2795));
  252. REQUIRE(minMaxTrees.size() == vals.size());
  253. REQUIRE(___2795 == minMaxTrees[0]->size() && ___2795 == minMaxTrees[numTrees / 2]->size() && ___2795 == minMaxTrees[numTrees - 1]->size());
  254. if (numTrees == 3)
  255. {
  256. MinMaxTree::findEntriesContaining3VarValues(*minMaxTrees[0], *minMaxTrees[1], *minMaxTrees[2], vals[0], vals[1], vals[2], ___2977, ___2795, entryAddresses);
  257. }
  258. else
  259. {
  260. EntryIndex_t startPos;
  261. EntryIndex_t endPos;
  262. minMaxTrees[0]->getChildRange(___2795, MinMaxTree::MAX_DEPTH, 0, startPos, endPos);
  263. MinMaxTree::recursivelyFindEntriesContainingNVarValues(minMaxTrees, vals, MinMaxTree::MAX_DEPTH - 1, startPos, endPos, ___2795, ___2977, entryAddresses);
  264. }
  265. }
  266. static void findEntriesContaining3VarValues(MinMaxTree const &xMinMaxTree, MinMaxTree const &yMinMaxTree, MinMaxTree const &zMinMaxTree, double xVal, double yVal, double zVal, ___2090::___2980 ___2977, EntryIndex_t ___2795, ___3269<___2090::SubzoneAddress> &entryAddresses)
  267. {
  268. REQUIRE(xMinMaxTree.isValidlyPopulated(___2795));
  269. REQUIRE(yMinMaxTree.isValidlyPopulated(___2795));
  270. REQUIRE(zMinMaxTree.isValidlyPopulated(___2795));
  271. REQUIRE(MAX_DEPTH == 4);
  272. EntryIndex_t const numEntriesAtDepth0 = ___2795;
  273. ;
  274. ___478(numEntriesAtDepth0 == getNumEntriesAtDepth(___2795, 0));
  275. EntryIndex_t const numEntriesAtDepth1 = getNumEntriesAtDepth(___2795, 1);
  276. EntryIndex_t const numEntriesAtDepth2 = getNumEntriesAtDepth(___2795, 2);
  277. EntryIndex_t const numEntriesAtDepth3 = getNumEntriesAtDepth(___2795, 3);
  278. EntryIndex_t depth3Start;
  279. EntryIndex_t depth3End;
  280. xMinMaxTree.getChildRangeUsingNumEntries(0, numEntriesAtDepth3, depth3Start, depth3End);
  281. for (EntryIndex_t depth3Pos = depth3Start; depth3Pos < depth3End; ++depth3Pos)
  282. {
  283. if (xMinMaxTree.getMinMaxAtDepth(3, depth3Pos).containsValue(xVal) && yMinMaxTree.getMinMaxAtDepth(3, depth3Pos).containsValue(yVal) && zMinMaxTree.getMinMaxAtDepth(3, depth3Pos).containsValue(zVal))
  284. {
  285. EntryIndex_t depth2Start;
  286. EntryIndex_t depth2End;
  287. xMinMaxTree.getChildRangeUsingNumEntries(depth3Pos, numEntriesAtDepth2, depth2Start, depth2End);
  288. for (EntryIndex_t depth2Pos = depth2Start; depth2Pos < depth2End; ++depth2Pos)
  289. {
  290. if (xMinMaxTree.getMinMaxAtDepth(2, depth2Pos).containsValue(xVal) && yMinMaxTree.getMinMaxAtDepth(2, depth2Pos).containsValue(yVal) && zMinMaxTree.getMinMaxAtDepth(2, depth2Pos).containsValue(zVal))
  291. {
  292. EntryIndex_t depth1Start;
  293. EntryIndex_t depth1End;
  294. xMinMaxTree.getChildRangeUsingNumEntries(depth2Pos, numEntriesAtDepth1, depth1Start, depth1End);
  295. for (EntryIndex_t depth1Pos = depth1Start; depth1Pos < depth1End; ++depth1Pos)
  296. {
  297. if (xMinMaxTree.getMinMaxAtDepth(1, depth1Pos).containsValue(xVal) && yMinMaxTree.getMinMaxAtDepth(1, depth1Pos).containsValue(yVal) && zMinMaxTree.getMinMaxAtDepth(1, depth1Pos).containsValue(zVal))
  298. {
  299. EntryIndex_t depth0Start;
  300. EntryIndex_t depth0End;
  301. xMinMaxTree.getChildRangeUsingNumEntries(depth1Pos, numEntriesAtDepth0, depth0Start, depth0End);
  302. for (EntryIndex_t depth0Pos = depth0Start; depth0Pos < depth0End; ++depth0Pos)
  303. {
  304. if (xMinMaxTree.getMinMaxAtDepth(0, depth0Pos).containsValue(xVal) && yMinMaxTree.getMinMaxAtDepth(0, depth0Pos).containsValue(yVal) && zMinMaxTree.getMinMaxAtDepth(0, depth0Pos).containsValue(zVal))
  305. {
  306. if (entryAddresses.empty())
  307. entryAddresses.reserve(MIN_ENTRIES_TO_ALLOCATE);
  308. else if (entryAddresses.size() >= entryAddresses.capacity())
  309. entryAddresses.reserve(entryAddresses.size() * ALLOCATION_EXPANSION_FACTOR);
  310. entryAddresses.append(___2090::SubzoneAddress(___2977, depth0Pos));
  311. }
  312. }
  313. }
  314. }
  315. }
  316. }
  317. }
  318. }
  319. }
  320. private:
  321. static void recursivelyFindEntriesContainingNVarValues(___3269<MinMaxTree const *> const &minMaxTrees, ___3269<double> const &vals, EntryIndex_t depth, EntryIndex_t startPos, EntryIndex_t endPos, EntryIndex_t ___2795, ___2090::___2980 ___2977, ___3269<___2090::SubzoneAddress> &entryAddresses);
  322. };
  323. typedef ___2240<MinMaxTree> MinMaxTreeArray;
  324. typedef ___2240<MinMaxTreeArray> MinMaxTree2DArray;
  325. typedef ___2240<MinMaxTree2DArray> MinMaxTree3DArray;
  326. }
  327. }