rtlsize.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #include "platform.h"
  14. #include <math.h>
  15. #include <stdio.h>
  16. #include "jmisc.hpp"
  17. #include "jutil.hpp"
  18. #include "jlib.hpp"
  19. #include "eclrtl.hpp"
  20. #include "rtlsize.hpp"
  21. /*************** This file is not yet used. WIP ******************************/
  22. class OffsetInfoArray : public PointerArray
  23. {
  24. public:
  25. OffsetInfoBase & item(unsigned idx) { return *(OffsetInfoBase *)PointerArray::item(idx); };
  26. };
  27. SizeSelector::SizeSelector(OffsetInfoBase & _monitor) : monitor(_monitor)
  28. {
  29. }
  30. SizeSelector::~SizeSelector()
  31. {
  32. }
  33. unsigned SizeSelector::getSize()
  34. {
  35. if (monitor.isValid())
  36. return monitor.getSize();
  37. return 0;
  38. }
  39. SizeSelector & SizeSelector::reset()
  40. {
  41. return *this;
  42. }
  43. //---------------------------------------------------------------------------
  44. #ifdef _MSC_VER
  45. #pragma warning (push)
  46. #pragma warning( disable : 4355 )
  47. #endif
  48. OffsetInfoBase::OffsetInfoBase(OffsetInfoBase * _owner, OffsetInfoBase * _pred, unsigned _predDelta, unsigned _fixedSize) : curSelection(*this)
  49. {
  50. owner = _owner;
  51. pred = _pred;
  52. predDelta = _predDelta;
  53. fixedSize = _fixedSize;
  54. cachedSize = fixedSize;
  55. }
  56. #ifdef _MSC_VER
  57. #pragma warning (pop)
  58. #endif
  59. void OffsetInfoBase::addChild(OffsetInfoBase & child)
  60. {
  61. assertex(false);
  62. }
  63. void OffsetInfoBase::adjustSize(int delta)
  64. {
  65. if (owner)
  66. owner->adjustSize(delta);
  67. cachedSize += delta;
  68. }
  69. SizeSelector & OffsetInfoBase::get()
  70. {
  71. return curSelection.reset();
  72. }
  73. unsigned OffsetInfoBase::getOffset()
  74. {
  75. if (pred)
  76. return pred->getOffset() + pred->getOffset() + predDelta;
  77. if (owner)
  78. return owner->getOffset() + predDelta;
  79. return 0;
  80. }
  81. unsigned OffsetInfoBase::getSize()
  82. {
  83. return cachedSize;
  84. }
  85. void OffsetInfoBase::moveSection(unsigned offset, int delta)
  86. {
  87. owner->moveSection(offset, delta);
  88. }
  89. bool OffsetInfoBase::isValid()
  90. {
  91. if (owner)
  92. return owner->isValid();
  93. return true;
  94. }
  95. //---------------------------------------------------------------------------
  96. CompoundOffsetInfo::CompoundOffsetInfo(OffsetInfoBase * _owner, OffsetInfoBase * _pred, unsigned _predDelta, unsigned _fixedSize) : OffsetInfoBase(_owner, _pred, _predDelta, _fixedSize)
  97. {
  98. children = new OffsetInfoArray;
  99. }
  100. CompoundOffsetInfo::~CompoundOffsetInfo()
  101. {
  102. delete children;
  103. }
  104. void CompoundOffsetInfo::addChild(OffsetInfoBase & child)
  105. {
  106. children->append(&child);
  107. if (child.isValid())
  108. adjustSize(child.getSize());
  109. }
  110. //---------------------------------------------------------------------------
  111. RecordOffsetInfo::RecordOffsetInfo(OffsetInfoBase * _owner, OffsetInfoBase * _pred, unsigned _predDelta, unsigned _fixedSize) :
  112. CompoundOffsetInfo(_owner, _pred, _predDelta, _fixedSize)
  113. {
  114. if (owner)
  115. owner->addChild(*this);
  116. }
  117. //---------------------------------------------------------------------------
  118. RootRecordOffsetInfo::RootRecordOffsetInfo(const void * _baseAddress, unsigned _fixedSize) :
  119. CompoundOffsetInfo(NULL, NULL, 0, _fixedSize)
  120. {
  121. baseAddress = (unsigned char *)_baseAddress;
  122. }
  123. void RootRecordOffsetInfo::moveSection(unsigned offset, int delta)
  124. {
  125. if (delta > 0)
  126. {
  127. memmove(baseAddress+offset+delta, baseAddress+offset, cachedSize-offset);
  128. memset(baseAddress+offset, 0xff, delta);
  129. }
  130. else
  131. {
  132. memmove(baseAddress+offset, baseAddress+offset-delta, cachedSize-offset+delta);
  133. }
  134. }
  135. //---------------------------------------------------------------------------
  136. IfBlockOffsetInfo::IfBlockOffsetInfo(OffsetInfoBase * _owner, OffsetInfoBase * _pred, unsigned _predDelta, unsigned _fixedSize, bool _isOkay) :
  137. CompoundOffsetInfo(_owner, _pred, _predDelta, _fixedSize)
  138. {
  139. isOkay = _isOkay;
  140. if (owner)
  141. owner->addChild(*this);
  142. }
  143. void IfBlockOffsetInfo::adjustSize(int delta)
  144. {
  145. if (isOkay)
  146. CompoundOffsetInfo::adjustSize(delta);
  147. else
  148. cachedSize += delta;
  149. }
  150. bool IfBlockOffsetInfo::isValid()
  151. {
  152. if (!isOkay)
  153. return false;
  154. return CompoundOffsetInfo::isValid();
  155. }
  156. void IfBlockOffsetInfo::setValid(bool nowValid)
  157. {
  158. if (isOkay != nowValid)
  159. {
  160. if (isOkay)
  161. {
  162. //Condition no longer true->shuffle contents up...
  163. unsigned offset = getOffset();
  164. int size = (int)getSize();
  165. owner->moveSection(offset, -size);
  166. adjustSize(-size);
  167. isOkay = false;
  168. }
  169. else
  170. {
  171. //unsigned offset = getOffset();
  172. //copy from offset to end of record to end of record.
  173. //create a default for this level (and possibly any child records).
  174. //child nodes need to notice that values have been created/destroyed
  175. //change the size of this element + parents
  176. //copy back onto end of record.
  177. }
  178. }
  179. }
  180. /*
  181. Variable sized arrays.
  182. - Nodes know when their conditions change. If possible change, structure is notified.
  183. - Checking and creation functions need
  184. i) offset structure
  185. ii) indexes to initialise (as an unsigned[])
  186. passed into them. So they know what they are working on, and so not too inefficient. Means sizes should
  187. always be consistent in the structure.
  188. - Doesn't work so well with grand-children, but will just about.
  189. Or
  190. - Nodes dynamically calculate condition from current settings.
  191. - CONCLUSION: Far to inefficient.......
  192. Or
  193. - Calling code always inform each item that changes in turn.
  194. - Would require loops to be generated in some circumstances.
  195. - Creation function only occurs one level at a time
  196. - Need explict code to , and always assumes false for children/
  197. - Problem: #elements could change by 1
  198. - CONCLUSION: In general too complicated/would get tied in knots.
  199. Embedded child records
  200. 1. Pointers are maintained for each of the parent/child records.
  201. 2. Create/offset functions are passed pointers to each of the different levels of children.
  202. 3. Would mean multiple "cursors" passed into denormalize/normalize functions. Other activities could create internal cursors.
  203. 4. Means you cannot access one child from another.
  204. 5. Offset calculation becomes linear - no array complications.
  205. 6. No array indexing since structure has been flattened
  206. 7. No random modification because fields can always be updated in order.
  207. */
  208. //---------------------------------------------------------------------------
  209. AlienOffsetInfo::AlienOffsetInfo(OffsetInfoBase * _owner, OffsetInfoBase * _pred, unsigned _predDelta, unsigned _startSize) :
  210. OffsetInfoBase(_owner, _pred, _predDelta, _startSize)
  211. {
  212. if (owner)
  213. owner->addChild(*this);
  214. }
  215. //############################################################################################################################################################
  216. //############################################################################################################################################################
  217. //############################################################################################################################################################
  218. #if 0
  219. class SizeChildArray : public PointerArray
  220. {
  221. public:
  222. SizeMonitor & item(unsigned idx) { return *(SizeMonitor *)item(idx); };
  223. };
  224. SizeSelector::SizeSelector(SizeMonitor & _monitor, unsigned maxDimensions) : monitor(_monitor)
  225. {
  226. maxDimension s= _maxDimensions;
  227. curSelection = new unsigned[maxDimensions];
  228. }
  229. SizeSelector::~SizeSelector()
  230. {
  231. delete [] curSelection;
  232. }
  233. unsigned SizeSelector::getSize()
  234. {
  235. assertex(curDimension == maxDimensions);
  236. if (monitor->isValid(curSelection))
  237. return monitor.getSize(curSelection);
  238. return 0;
  239. }
  240. SizeSelector & SizeSelector::reset()
  241. {
  242. curDimension = 0;
  243. return *this;
  244. }
  245. SizeSelector & SizeSelector::select(unsigned idx)
  246. {
  247. assertex(curDimension < maxDimensions);
  248. curSelection[curDimension++] = idx;
  249. return *this;
  250. }
  251. //---------------------------------------------------------------------------
  252. SizeMonitor::SizeMonitor(SizeMonitor * _owner, SizeMonitor * _pred, unsigned _predDelta) : curSelection(*this, _owner ? _owner->numDimensions() : 0)
  253. {
  254. owner = _owner;
  255. pred = _pred;
  256. predDelta = _predDelta;
  257. maxDimensions = owner ? owner->numDimensions() : 0;
  258. }
  259. SizeSelector & SizeMonitor::get()
  260. {
  261. return curSelection.reset();
  262. }
  263. void SizeMonitor::structureChanged()
  264. {
  265. //MORE!
  266. }
  267. unsigned SizeMonitor::getSize(unsigned * curDimensions)
  268. {
  269. return fixedSize;
  270. }
  271. //---------------------------------------------------------------------------
  272. unsigned RecordMonitor::getSize(unsigned * curDimensions)
  273. {
  274. unsigned size = fixedSize;
  275. ForEachItemIn(idx, *children)
  276. size += children->item(idx).getSize(curDimensions);
  277. return size;
  278. }
  279. //---------------------------------------------------------------------------
  280. void SizeMonitor::adjustSize(unsigned * dimension, int delta)
  281. {
  282. if (owner)
  283. owner->adjustSize(dimension, delta);
  284. cacheSize[getChildIndex(dimension)] += delta;
  285. }
  286. unsigned SizeMonitor::getChildIndex(unsigned * curDimensions)
  287. {
  288. unsigned curIndex = 0;
  289. for (unsigend idx=0; idx < maxDimensions; idx++)
  290. {
  291. if (idx)
  292. curIndex *= maxDimensions[idx-1];
  293. curIndex += curDimensions[idx];
  294. }
  295. return curIndex;
  296. }
  297. void SizeMonitor::getOffset(unsigned * dimensions)
  298. {
  299. if (pred)
  300. return pred->getOffset(dimensions) + pred->getOffset(dimensions) + fixedDelta;
  301. if (owner)
  302. return owner->getOffset(dimensions) + fixedDelta;
  303. return 0;
  304. }
  305. void SizeMonitor::getSize(unsigned * dimensions)
  306. {
  307. return cachedSize[getChildIndex(dimensions)];
  308. }
  309. void SizeMonitor::dimensionChanged(unsigned dim, unsigned newDim)
  310. {
  311. //check if need to expand max.
  312. /* Reallocate the cachedSizes, and copy the dimensions */
  313. //MORE!
  314. }
  315. //---------------------------------------------------------------------------
  316. unsigned ArrayMonitor::calcSize(unsigned * curDimensions)
  317. {
  318. unsigned size = 0;
  319. unsigned numDimensions = getDimension(curDimensions);
  320. if (children->ordinality())
  321. {
  322. SizeMonitor & child = children->item(0);
  323. SizeSelector iter(child, numDimensions+1);
  324. for (dim = 0; dim < numDimensions; dim++)
  325. size += iter.reset(numDimensions, curDimensions).select(dim).getSize() + fixedSize;
  326. }
  327. else
  328. size = fixedSize * numDimensions;
  329. return size;
  330. }
  331. void ArrayMonitor::getDimensions(unsigned * dimensions)
  332. {
  333. return dimension[getChildIndex(dimensions)];
  334. }
  335. bool ArrayMonitor::isValid(unsigned * dimensions)
  336. {
  337. if (!owner->isValid(dimensions))
  338. return false;
  339. if (getDimension(dimensions) == 0)
  340. return false;
  341. return true;
  342. }
  343. //---------------------------------------------------------------------------
  344. void IfBlockMonitor::setShown(unsigned * dimensions, bool nowShown)
  345. {
  346. if (isShown[dimensions] != nowShown)
  347. {
  348. if (isShown[dimensions])
  349. {
  350. isShown[dimensions] = false;
  351. owner->adjustSize(-getSize(dimensions))
  352. }
  353. else
  354. {
  355. isShown[dimensions] = false;
  356. owner->adjustSize(-getSize(dimensions))
  357. }
  358. }
  359. }
  360. #endif