rtlds.cpp 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381
  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 "jliball.hpp"
  15. #include "eclrtl.hpp"
  16. #include "eclhelper.hpp"
  17. #include "rtlds_imp.hpp"
  18. #include "rtlread_imp.hpp"
  19. #define FIRST_CHUNK_SIZE 0x100
  20. #define DOUBLE_LIMIT 0x10000 // must be a power of 2
  21. unsigned getNextSize(unsigned max, unsigned required)
  22. {
  23. if (required > DOUBLE_LIMIT)
  24. {
  25. max = (required + DOUBLE_LIMIT) & ~(DOUBLE_LIMIT-1);
  26. if (required >= max)
  27. throw MakeStringException(-1, "getNextSize: Request for %d bytes oldMax = %d", required, max);
  28. }
  29. else
  30. {
  31. if (max == 0)
  32. max = FIRST_CHUNK_SIZE;
  33. while (required >= max)
  34. max += max;
  35. }
  36. return max;
  37. }
  38. //---------------------------------------------------------------------------
  39. RtlDatasetBuilder::RtlDatasetBuilder()
  40. {
  41. maxSize = 0;
  42. buffer = NULL;
  43. totalSize = 0;
  44. }
  45. RtlDatasetBuilder::~RtlDatasetBuilder()
  46. {
  47. free(buffer);
  48. }
  49. void RtlDatasetBuilder::ensure(size32_t required)
  50. {
  51. if (required > maxSize)
  52. {
  53. maxSize = getNextSize(maxSize, required);
  54. buffer = (byte *)realloc(buffer, maxSize);
  55. if (!buffer)
  56. throw MakeStringException(-1, "Failed to allocate temporary dataset (requesting %d bytes)", maxSize);
  57. }
  58. }
  59. byte * RtlDatasetBuilder::ensureCapacity(size32_t required, const char * fieldName)
  60. {
  61. ensure(totalSize + required);
  62. return buffer + totalSize;
  63. }
  64. void RtlDatasetBuilder::flushDataset()
  65. {
  66. }
  67. void RtlDatasetBuilder::getData(size32_t & len, void * & data)
  68. {
  69. flushDataset();
  70. len = totalSize;
  71. data = malloc(totalSize);
  72. memcpy(data, buffer, totalSize);
  73. }
  74. size32_t RtlDatasetBuilder::getSize()
  75. {
  76. flushDataset();
  77. return totalSize;
  78. }
  79. byte * RtlDatasetBuilder::queryData()
  80. {
  81. flushDataset();
  82. return buffer;
  83. }
  84. void RtlDatasetBuilder::reportMissingRow() const
  85. {
  86. throw MakeStringException(MSGAUD_user, 1000, "RtlDatasetBuilder::row() is NULL");
  87. }
  88. //---------------------------------------------------------------------------
  89. RtlFixedDatasetBuilder::RtlFixedDatasetBuilder(unsigned _recordSize, unsigned maxRows)
  90. {
  91. recordSize = _recordSize;
  92. if ((int)maxRows > 0)
  93. ensure(recordSize * maxRows);
  94. }
  95. byte * RtlFixedDatasetBuilder::createSelf()
  96. {
  97. self = ensureCapacity(recordSize, NULL);
  98. return self;
  99. }
  100. //---------------------------------------------------------------------------
  101. RtlLimitedFixedDatasetBuilder::RtlLimitedFixedDatasetBuilder(unsigned _recordSize, unsigned _maxRows, DefaultRowCreator _rowCreator, IResourceContext *_ctx) : RtlFixedDatasetBuilder(_recordSize, _maxRows)
  102. {
  103. maxRows = _maxRows;
  104. if ((int)maxRows < 0) maxRows = 0;
  105. rowCreator = _rowCreator;
  106. ctx = _ctx;
  107. }
  108. byte * RtlLimitedFixedDatasetBuilder::createRow()
  109. {
  110. if (totalSize >= maxRows * recordSize)
  111. return NULL;
  112. return RtlFixedDatasetBuilder::createRow();
  113. }
  114. void RtlLimitedFixedDatasetBuilder::flushDataset()
  115. {
  116. if (rowCreator)
  117. {
  118. while (totalSize < maxRows * recordSize)
  119. {
  120. createRow();
  121. size32_t size = rowCreator(rowBuilder(), ctx);
  122. finalizeRow(size);
  123. }
  124. }
  125. RtlFixedDatasetBuilder::flushDataset();
  126. }
  127. //---------------------------------------------------------------------------
  128. RtlVariableDatasetBuilder::RtlVariableDatasetBuilder(IRecordSize & _recordSize)
  129. {
  130. recordSize = &_recordSize;
  131. maxRowSize = recordSize->getRecordSize(NULL); // initial size
  132. }
  133. byte * RtlVariableDatasetBuilder::createSelf()
  134. {
  135. self = ensureCapacity(maxRowSize, NULL);
  136. return self;
  137. }
  138. void RtlVariableDatasetBuilder::deserializeRow(IOutputRowDeserializer & deserializer, IRowDeserializerSource & in)
  139. {
  140. createRow();
  141. size32_t rowSize = deserializer.deserialize(rowBuilder(), in);
  142. finalizeRow(rowSize);
  143. }
  144. //---------------------------------------------------------------------------
  145. RtlLimitedVariableDatasetBuilder::RtlLimitedVariableDatasetBuilder(IRecordSize & _recordSize, unsigned _maxRows, DefaultRowCreator _rowCreator, IResourceContext *_ctx) : RtlVariableDatasetBuilder(_recordSize)
  146. {
  147. numRows = 0;
  148. maxRows = _maxRows;
  149. rowCreator = _rowCreator;
  150. ctx = _ctx;
  151. }
  152. byte * RtlLimitedVariableDatasetBuilder::createRow()
  153. {
  154. if (numRows >= maxRows)
  155. return NULL;
  156. numRows++;
  157. return RtlVariableDatasetBuilder::createRow();
  158. }
  159. void RtlLimitedVariableDatasetBuilder::flushDataset()
  160. {
  161. if (rowCreator)
  162. {
  163. while (numRows < maxRows)
  164. {
  165. createRow();
  166. size32_t thisSize = rowCreator(rowBuilder(), ctx);
  167. finalizeRow(thisSize);
  168. }
  169. }
  170. RtlVariableDatasetBuilder::flushDataset();
  171. }
  172. //---------------------------------------------------------------------------
  173. byte * * rtlRowsAttr::linkrows() const
  174. {
  175. if (rows)
  176. rtlLinkRowset(rows);
  177. return rows;
  178. }
  179. void rtlRowsAttr::set(size32_t _count, byte * * _rows)
  180. {
  181. setown(_count, rtlLinkRowset(_rows));
  182. }
  183. void rtlRowsAttr::setRow(IEngineRowAllocator * rowAllocator, const byte * _row)
  184. {
  185. setown(1, rowAllocator->appendRowOwn(NULL, 1, rowAllocator->linkRow(_row)));
  186. }
  187. void rtlRowsAttr::setown(size32_t _count, byte * * _rows)
  188. {
  189. dispose();
  190. count = _count;
  191. rows = _rows;
  192. }
  193. void rtlRowsAttr::dispose()
  194. {
  195. if (rows)
  196. rtlReleaseRowset(count, rows);
  197. }
  198. //---------------------------------------------------------------------------
  199. void rtlReportFieldOverflow(unsigned size, unsigned max, const RtlFieldInfo * field)
  200. {
  201. if (field)
  202. rtlReportFieldOverflow(size, max, field->name->str());
  203. else
  204. rtlReportRowOverflow(size, max);
  205. }
  206. void RtlRowBuilderBase::reportMissingRow() const
  207. {
  208. throw MakeStringException(MSGAUD_user, 1000, "RtlRowBuilderBase::row() is NULL");
  209. }
  210. byte * RtlDynamicRowBuilder::ensureCapacity(size32_t required, const char * fieldName)
  211. {
  212. if (required > maxLength)
  213. {
  214. if (!self)
  215. create();
  216. if (required > maxLength)
  217. {
  218. void * next = rowAllocator->resizeRow(required, self, maxLength);
  219. if (!next)
  220. {
  221. rtlReportFieldOverflow(required, maxLength, fieldName);
  222. return NULL;
  223. }
  224. self = static_cast<byte *>(next);
  225. }
  226. }
  227. return self;
  228. }
  229. void RtlDynamicRowBuilder::swapWith(RtlDynamicRowBuilder & other)
  230. {
  231. size32_t savedMaxLength = maxLength;
  232. void * savedSelf = getUnfinalizedClear();
  233. setown(other.getMaxLength(), other.getUnfinalizedClear());
  234. other.setown(savedMaxLength, savedSelf);
  235. }
  236. //---------------------------------------------------------------------------
  237. byte * RtlStaticRowBuilder::ensureCapacity(size32_t required, const char * fieldName)
  238. {
  239. if (required <= maxLength)
  240. return static_cast<byte *>(self);
  241. rtlReportFieldOverflow(required, maxLength, fieldName);
  242. return NULL;
  243. }
  244. byte * RtlStaticRowBuilder::createSelf()
  245. {
  246. throwUnexpected();
  247. }
  248. //---------------------------------------------------------------------------
  249. RtlLinkedDatasetBuilder::RtlLinkedDatasetBuilder(IEngineRowAllocator * _rowAllocator, int _choosenLimit) : builder(_rowAllocator, false)
  250. {
  251. rowAllocator = LINK(_rowAllocator);
  252. rowset = NULL;
  253. count = 0;
  254. max = 0;
  255. choosenLimit = (unsigned)_choosenLimit;
  256. }
  257. RtlLinkedDatasetBuilder::~RtlLinkedDatasetBuilder()
  258. {
  259. builder.clear();
  260. if (rowset)
  261. rowAllocator->releaseRowset(count, rowset);
  262. ::Release(rowAllocator);
  263. }
  264. void RtlLinkedDatasetBuilder::append(const void * source)
  265. {
  266. if (count < choosenLimit)
  267. {
  268. ensure(count+1);
  269. rowset[count] = source ? (byte *)rowAllocator->linkRow(source) : NULL;
  270. count++;
  271. }
  272. }
  273. void RtlLinkedDatasetBuilder::appendRows(size32_t num, byte * * rows)
  274. {
  275. if (num && (count < choosenLimit))
  276. {
  277. unsigned maxNumToAdd = (count + num < choosenLimit) ? num : choosenLimit - count;
  278. unsigned numAdded = 0;
  279. ensure(count+maxNumToAdd);
  280. for (unsigned i=0; i < num; i++)
  281. {
  282. byte *row = rows[i];
  283. if (row)
  284. {
  285. rowset[count+numAdded] = (byte *)rowAllocator->linkRow(row);
  286. numAdded++;
  287. if (numAdded == maxNumToAdd)
  288. break;
  289. }
  290. }
  291. count += numAdded;
  292. }
  293. }
  294. void RtlLinkedDatasetBuilder::appendOwn(const void * row)
  295. {
  296. assertex(!builder.exists());
  297. if (count < choosenLimit)
  298. {
  299. ensure(count+1);
  300. rowset[count] = (byte *)row;
  301. count++;
  302. }
  303. else
  304. rowAllocator->releaseRow(row);
  305. }
  306. byte * RtlLinkedDatasetBuilder::createRow()
  307. {
  308. if (count >= choosenLimit)
  309. return NULL;
  310. return builder.getSelf();
  311. }
  312. //cloned from thorcommon.cpp
  313. class RtlChildRowLinkerWalker : implements IIndirectMemberVisitor
  314. {
  315. public:
  316. virtual void visitRowset(size32_t count, byte * * rows)
  317. {
  318. rtlLinkRowset(rows);
  319. }
  320. virtual void visitRow(const byte * row)
  321. {
  322. rtlLinkRow(row);
  323. }
  324. };
  325. void RtlLinkedDatasetBuilder::cloneRow(size32_t len, const void * row)
  326. {
  327. if (count >= choosenLimit)
  328. return;
  329. byte * self = builder.ensureCapacity(len, NULL);
  330. memcpy(self, row, len);
  331. IOutputMetaData * meta = rowAllocator->queryOutputMeta();
  332. if (meta->getMetaFlags() & MDFneedserialize)
  333. {
  334. RtlChildRowLinkerWalker walker;
  335. meta->walkIndirectMembers(self, walker);
  336. }
  337. finalizeRow(len);
  338. }
  339. void RtlLinkedDatasetBuilder::deserializeRow(IOutputRowDeserializer & deserializer, IRowDeserializerSource & in)
  340. {
  341. builder.ensureRow();
  342. size32_t rowSize = deserializer.deserialize(builder, in);
  343. finalizeRow(rowSize);
  344. }
  345. inline void doDeserializeRowset(RtlLinkedDatasetBuilder & builder, IOutputRowDeserializer & deserializer, IRowDeserializerSource & in, offset_t marker, bool isGrouped)
  346. {
  347. byte eogPending = false;
  348. while (!in.finishedNested(marker))
  349. {
  350. if (isGrouped && eogPending)
  351. builder.appendEOG();
  352. builder.deserializeRow(deserializer, in);
  353. if (isGrouped)
  354. in.read(1, &eogPending);
  355. }
  356. }
  357. inline void doSerializeRowset(IRowSerializerTarget & out, IOutputRowSerializer * serializer, size32_t count, byte * * rows, bool isGrouped)
  358. {
  359. for (unsigned i=0; i < count; i++)
  360. {
  361. byte *row = rows[i];
  362. if (row) // When serializing a dictionary, there may be nulls in the rowset. These can be skipped (we rehash on deserialize)
  363. {
  364. serializer->serialize(out, rows[i]);
  365. if (isGrouped)
  366. {
  367. byte eogPending = (i+1 < count) && (rows[i+1] == NULL);
  368. out.put(1, &eogPending);
  369. }
  370. }
  371. }
  372. }
  373. void RtlLinkedDatasetBuilder::deserialize(IOutputRowDeserializer & deserializer, IRowDeserializerSource & in, bool isGrouped)
  374. {
  375. offset_t marker = in.beginNested();
  376. doDeserializeRowset(*this, deserializer, in, marker, isGrouped);
  377. }
  378. void RtlLinkedDatasetBuilder::finalizeRows()
  379. {
  380. if (count != max)
  381. resize(count);
  382. }
  383. void RtlLinkedDatasetBuilder::finalizeRow(size32_t rowSize)
  384. {
  385. assertex(builder.exists());
  386. const void * next = builder.finalizeRowClear(rowSize);
  387. appendOwn(next);
  388. }
  389. byte * * RtlLinkedDatasetBuilder::linkrows()
  390. {
  391. finalizeRows();
  392. return rtlLinkRowset(rowset);
  393. }
  394. void RtlLinkedDatasetBuilder::expand(size32_t required)
  395. {
  396. assertex(required <= choosenLimit);
  397. //MORE: Next factoring change this so it passes this logic over to the row allocator
  398. size32_t newMax = max ? max : 4;
  399. while (newMax < required)
  400. {
  401. newMax += newMax;
  402. assertex(newMax);
  403. }
  404. if (newMax > choosenLimit)
  405. newMax = choosenLimit;
  406. resize(newMax);
  407. }
  408. void RtlLinkedDatasetBuilder::resize(size32_t required)
  409. {
  410. rowset = rowAllocator->reallocRows(rowset, max, required);
  411. max = required;
  412. }
  413. void appendRowsToRowset(size32_t & targetCount, byte * * & targetRowset, IEngineRowAllocator * rowAllocator, size32_t extraCount, byte * * extraRows)
  414. {
  415. if (extraCount)
  416. {
  417. size32_t prevCount = targetCount;
  418. byte * * expandedRowset = rowAllocator->reallocRows(targetRowset, prevCount, prevCount+extraCount);
  419. unsigned numAdded = 0;
  420. for (unsigned i=0; i < extraCount; i++)
  421. {
  422. byte *extraRow = extraRows[i];
  423. if (extraRow)
  424. {
  425. expandedRowset[prevCount+numAdded] = (byte *)rowAllocator->linkRow(extraRow);
  426. numAdded++;
  427. }
  428. }
  429. targetCount = prevCount + numAdded;
  430. targetRowset = expandedRowset;
  431. }
  432. }
  433. inline void doDeserializeRowset(size32_t & count, byte * * & rowset, IEngineRowAllocator * _rowAllocator, IOutputRowDeserializer * deserializer, IRowDeserializerSource & in, bool isGrouped)
  434. {
  435. RtlLinkedDatasetBuilder builder(_rowAllocator);
  436. builder.deserialize(*deserializer, in, isGrouped);
  437. count = builder.getcount();
  438. rowset = builder.linkrows();
  439. }
  440. extern ECLRTL_API void rtlDeserializeRowset(size32_t & count, byte * * & rowset, IEngineRowAllocator * _rowAllocator, IOutputRowDeserializer * deserializer, IRowDeserializerSource & in)
  441. {
  442. doDeserializeRowset(count, rowset, _rowAllocator, deserializer, in, false);
  443. }
  444. extern ECLRTL_API void rtlDeserializeGroupedRowset(size32_t & count, byte * * & rowset, IEngineRowAllocator * _rowAllocator, IOutputRowDeserializer * deserializer, IRowDeserializerSource & in)
  445. {
  446. doDeserializeRowset(count, rowset, _rowAllocator, deserializer, in, true);
  447. }
  448. void rtlSerializeRowset(IRowSerializerTarget & out, IOutputRowSerializer * serializer, size32_t count, byte * * rows)
  449. {
  450. size32_t marker = out.beginNested();
  451. doSerializeRowset(out, serializer, count, rows, false);
  452. out.endNested(marker);
  453. }
  454. void rtlSerializeGroupedRowset(IRowSerializerTarget & out, IOutputRowSerializer * serializer, size32_t count, byte * * rows)
  455. {
  456. size32_t marker = out.beginNested();
  457. doSerializeRowset(out, serializer, count, rows, true);
  458. out.endNested(marker);
  459. }
  460. //---------------------------------------------------------------------------
  461. RtlLinkedDictionaryBuilder::RtlLinkedDictionaryBuilder(IEngineRowAllocator * _rowAllocator, IHThorHashLookupInfo *_hashInfo, unsigned _initialSize)
  462. : builder(_rowAllocator, false)
  463. {
  464. init(_rowAllocator, _hashInfo, _initialSize);
  465. }
  466. RtlLinkedDictionaryBuilder::RtlLinkedDictionaryBuilder(IEngineRowAllocator * _rowAllocator, IHThorHashLookupInfo *_hashInfo)
  467. : builder(_rowAllocator, false)
  468. {
  469. init(_rowAllocator, _hashInfo, 8);
  470. }
  471. void RtlLinkedDictionaryBuilder::init(IEngineRowAllocator * _rowAllocator, IHThorHashLookupInfo *_hashInfo, unsigned _initialSize)
  472. {
  473. hash = _hashInfo->queryHash();
  474. compare = _hashInfo->queryCompare();
  475. initialSize = _initialSize;
  476. rowAllocator = LINK(_rowAllocator);
  477. table = NULL;
  478. usedCount = 0;
  479. usedLimit = 0;
  480. tableSize = 0;
  481. }
  482. RtlLinkedDictionaryBuilder::~RtlLinkedDictionaryBuilder()
  483. {
  484. // builder.clear();
  485. if (table)
  486. rowAllocator->releaseRowset(tableSize, table);
  487. ::Release(rowAllocator);
  488. }
  489. void RtlLinkedDictionaryBuilder::append(const void * source)
  490. {
  491. if (source)
  492. {
  493. appendOwn(rowAllocator->linkRow(source));
  494. }
  495. }
  496. void RtlLinkedDictionaryBuilder::appendOwn(const void * source)
  497. {
  498. if (source)
  499. {
  500. checkSpace();
  501. unsigned rowidx = hash->hash(source) % tableSize;
  502. loop
  503. {
  504. const void *entry = table[rowidx];
  505. if (entry && compare->docompare(source, entry)==0)
  506. {
  507. rowAllocator->releaseRow(entry);
  508. usedCount--;
  509. entry = NULL;
  510. }
  511. if (!entry)
  512. {
  513. table[rowidx] = (byte *) source;
  514. usedCount++;
  515. break;
  516. }
  517. rowidx++;
  518. if (rowidx==tableSize)
  519. rowidx = 0;
  520. }
  521. }
  522. }
  523. void RtlLinkedDictionaryBuilder::checkSpace()
  524. {
  525. if (!table)
  526. {
  527. table = rowAllocator->createRowset(initialSize);
  528. tableSize = initialSize;
  529. memset(table, 0, tableSize*sizeof(byte *));
  530. usedLimit = (tableSize * 3) / 4;
  531. usedCount = 0;
  532. }
  533. else if (usedCount > usedLimit)
  534. {
  535. // Rehash
  536. byte * * oldTable = table;
  537. unsigned oldSize = tableSize;
  538. table = rowAllocator->createRowset(tableSize*2);
  539. tableSize = tableSize*2; // Don't update until we have successfully allocated, so that we remain consistent if createRowset throws an exception.
  540. memset(table, 0, tableSize * sizeof(byte *));
  541. usedLimit = (tableSize * 3) / 4;
  542. usedCount = 0;
  543. unsigned i;
  544. for (i = 0; i < oldSize; i++)
  545. {
  546. append(oldTable[i]); // we link the rows here...
  547. }
  548. rowAllocator->releaseRowset(oldSize, oldTable); // ... because this will release them
  549. }
  550. }
  551. void RtlLinkedDictionaryBuilder::appendRows(size32_t num, byte * * rows)
  552. {
  553. // MORE - if we know that the source is already a hashtable, we can optimize the add to an empty table...
  554. for (unsigned i=0; i < num; i++)
  555. append(rows[i]);
  556. }
  557. void RtlLinkedDictionaryBuilder::finalizeRow(size32_t rowSize)
  558. {
  559. assertex(builder.exists());
  560. const void * next = builder.finalizeRowClear(rowSize);
  561. appendOwn(next);
  562. }
  563. void RtlLinkedDictionaryBuilder::cloneRow(size32_t len, const void * row)
  564. {
  565. byte * self = builder.ensureCapacity(len, NULL);
  566. memcpy(self, row, len);
  567. IOutputMetaData * meta = rowAllocator->queryOutputMeta();
  568. if (meta->getMetaFlags() & MDFneedserialize)
  569. {
  570. RtlChildRowLinkerWalker walker;
  571. meta->walkIndirectMembers(self, walker);
  572. }
  573. finalizeRow(len);
  574. }
  575. extern ECLRTL_API unsigned __int64 rtlDictionaryCount(size32_t tableSize, byte **table)
  576. {
  577. unsigned __int64 ret = 0;
  578. for (size32_t i = 0; i < tableSize; i++)
  579. if (table[i])
  580. ret++;
  581. return ret;
  582. }
  583. extern ECLRTL_API byte *rtlDictionaryLookup(IHThorHashLookupInfo &hashInfo, size32_t tableSize, byte **table, const byte *source, byte *defaultRow)
  584. {
  585. if (!tableSize)
  586. return (byte *) rtlLinkRow(defaultRow);
  587. IHash *hash = hashInfo.queryHash();
  588. ICompare *compare = hashInfo.queryCompare();
  589. unsigned rowidx = hash->hash(source) % tableSize;
  590. loop
  591. {
  592. const void *entry = table[rowidx];
  593. if (!entry)
  594. return (byte *) rtlLinkRow(defaultRow);
  595. if (compare->docompare(source, entry)==0)
  596. return (byte *) rtlLinkRow(entry);
  597. rowidx++;
  598. if (rowidx==tableSize)
  599. rowidx = 0;
  600. }
  601. }
  602. extern ECLRTL_API bool rtlDictionaryLookupExists(IHThorHashLookupInfo &hashInfo, size32_t tableSize, byte **table, const byte *source)
  603. {
  604. if (!tableSize)
  605. return false;
  606. IHash *hash = hashInfo.queryHash();
  607. ICompare *compare = hashInfo.queryCompare();
  608. unsigned rowidx = hash->hash(source) % tableSize;
  609. loop
  610. {
  611. const void *entry = table[rowidx];
  612. if (!entry)
  613. return false;
  614. if (compare->docompare(source, entry)==0)
  615. return true;
  616. rowidx++;
  617. if (rowidx==tableSize)
  618. rowidx = 0;
  619. }
  620. }
  621. extern ECLRTL_API void rtlSerializeDictionary(IRowSerializerTarget & out, IOutputRowSerializer * serializer, size32_t count, byte * * rows)
  622. {
  623. out.put(sizeof(count), &count);
  624. size32_t idx = 0;
  625. while (idx < count)
  626. {
  627. byte numRows = 0;
  628. while (numRows < 255 && idx+numRows < count && rows[idx+numRows] != NULL)
  629. numRows++;
  630. out.put(1, &numRows);
  631. for (int i = 0; i < numRows; i++)
  632. {
  633. byte *nextrec = rows[idx+i];
  634. assert(nextrec);
  635. serializer->serialize(out, nextrec);
  636. }
  637. idx += numRows;
  638. byte numNulls = 0;
  639. while (numNulls < 255 && idx+numNulls < count && rows[idx+numNulls] == NULL)
  640. numNulls++;
  641. out.put(1, &numNulls);
  642. idx += numNulls;
  643. }
  644. }
  645. extern ECLRTL_API void rtlDictionary2RowsetX(size32_t & count, byte * * & rowset, IEngineRowAllocator * rowAllocator, IOutputRowDeserializer * deserializer, size32_t lenSrc, const void * src)
  646. {
  647. RtlLinkedDatasetBuilder builder(rowAllocator);
  648. Owned<ISerialStream> stream = createMemorySerialStream(src, lenSrc);
  649. CThorStreamDeserializerSource source(stream);
  650. size32_t totalRows;
  651. source.read(sizeof(totalRows), &totalRows);
  652. builder.ensure(totalRows);
  653. byte nullsPending = 0;
  654. byte rowsPending = 0;
  655. while (!source.finishedNested(lenSrc))
  656. {
  657. source.read(1, &rowsPending);
  658. for (int i = 0; i < rowsPending; i++)
  659. builder.deserializeRow(*deserializer, source);
  660. source.read(1, &nullsPending);
  661. for (int i = 0; i < nullsPending; i++)
  662. builder.append(NULL);
  663. }
  664. count = builder.getcount();
  665. assertex(count==totalRows);
  666. rowset = builder.linkrows();
  667. }
  668. //---------------------------------------------------------------------------
  669. //These definitions should be shared with thorcommon, but to do that
  670. //they would need to be moved to an rtlds.ipp header, which thorcommon then included.
  671. class ECLRTL_API CThorRtlRowSerializer : implements IRowSerializerTarget
  672. {
  673. public:
  674. CThorRtlRowSerializer(MemoryBuffer & _buffer) : buffer(_buffer)
  675. {
  676. }
  677. virtual void put(size32_t len, const void * ptr)
  678. {
  679. buffer.append(len, ptr);
  680. }
  681. virtual size32_t beginNested()
  682. {
  683. unsigned pos = buffer.length();
  684. buffer.append((size32_t)0);
  685. return pos;
  686. }
  687. virtual void endNested(size32_t sizePos)
  688. {
  689. unsigned pos = buffer.length();
  690. buffer.rewrite(sizePos);
  691. buffer.append((size32_t)(pos - (sizePos + sizeof(size32_t))));
  692. buffer.rewrite(pos);
  693. }
  694. protected:
  695. MemoryBuffer & buffer;
  696. };
  697. inline void doDataset2RowsetX(size32_t & count, byte * * & rowset, IEngineRowAllocator * rowAllocator, IOutputRowDeserializer * deserializer, size32_t lenSrc, const void * src, bool isGrouped)
  698. {
  699. RtlLinkedDatasetBuilder builder(rowAllocator);
  700. Owned<ISerialStream> stream = createMemorySerialStream(src, lenSrc);
  701. CThorStreamDeserializerSource source(stream);
  702. doDeserializeRowset(builder, *deserializer, source, lenSrc, isGrouped);
  703. count = builder.getcount();
  704. rowset = builder.linkrows();
  705. }
  706. inline void doRowset2DatasetX(unsigned & tlen, void * & tgt, IOutputRowSerializer * serializer, size32_t count, byte * * rows, bool isGrouped)
  707. {
  708. MemoryBuffer buffer;
  709. CThorRtlRowSerializer out(buffer);
  710. doSerializeRowset(out, serializer, count, rows, isGrouped);
  711. rtlFree(tgt);
  712. tlen = buffer.length();
  713. tgt = buffer.detach(); // not strictly speaking correct - it should have been allocated with rtlMalloc();
  714. }
  715. extern ECLRTL_API void rtlDataset2RowsetX(size32_t & count, byte * * & rowset, IEngineRowAllocator * rowAllocator, IOutputRowDeserializer * deserializer, size32_t lenSrc, const void * src, bool isGrouped)
  716. {
  717. doDataset2RowsetX(count, rowset, rowAllocator, deserializer, lenSrc, src, isGrouped);
  718. }
  719. extern ECLRTL_API void rtlDataset2RowsetX(size32_t & count, byte * * & rowset, IEngineRowAllocator * rowAllocator, IOutputRowDeserializer * deserializer, size32_t lenSrc, const void * src)
  720. {
  721. doDataset2RowsetX(count, rowset, rowAllocator, deserializer, lenSrc, src, false);
  722. }
  723. extern ECLRTL_API void rtlGroupedDataset2RowsetX(size32_t & count, byte * * & rowset, IEngineRowAllocator * rowAllocator, IOutputRowDeserializer * deserializer, size32_t lenSrc, const void * src)
  724. {
  725. doDataset2RowsetX(count, rowset, rowAllocator, deserializer, lenSrc, src, true);
  726. }
  727. extern ECLRTL_API void rtlRowset2DatasetX(unsigned & tlen, void * & tgt, IOutputRowSerializer * serializer, size32_t count, byte * * rows, bool isGrouped)
  728. {
  729. doRowset2DatasetX(tlen, tgt, serializer, count, rows, isGrouped);
  730. }
  731. extern ECLRTL_API void rtlRowset2DatasetX(unsigned & tlen, void * & tgt, IOutputRowSerializer * serializer, size32_t count, byte * * rows)
  732. {
  733. doRowset2DatasetX(tlen, tgt, serializer, count, rows, false);
  734. }
  735. extern ECLRTL_API void rtlGroupedRowset2DatasetX(unsigned & tlen, void * & tgt, IOutputRowSerializer * serializer, size32_t count, byte * * rows)
  736. {
  737. doRowset2DatasetX(tlen, tgt, serializer, count, rows, true);
  738. }
  739. extern ECLRTL_API void rtlRowset2DictionaryX(unsigned & tlen, void * & tgt, IOutputRowSerializer * serializer, size32_t count, byte * * rows)
  740. {
  741. MemoryBuffer rowdata;
  742. CThorRtlRowSerializer out(rowdata);
  743. rtlSerializeDictionary(out, serializer, count, rows);
  744. rtlFree(tgt);
  745. tlen = rowdata.length();
  746. tgt = rowdata.detach();
  747. }
  748. void deserializeRowsetX(size32_t & count, byte * * & rowset, IEngineRowAllocator * _rowAllocator, IOutputRowDeserializer * deserializer, MemoryBuffer &in)
  749. {
  750. Owned<ISerialStream> stream = createMemoryBufferSerialStream(in);
  751. CThorStreamDeserializerSource rowSource(stream);
  752. doDeserializeRowset(count, rowset, _rowAllocator, deserializer, rowSource, false);
  753. }
  754. void deserializeGroupedRowsetX(size32_t & count, byte * * & rowset, IEngineRowAllocator * _rowAllocator, IOutputRowDeserializer * deserializer, MemoryBuffer &in)
  755. {
  756. Owned<ISerialStream> stream = createMemoryBufferSerialStream(in);
  757. CThorStreamDeserializerSource rowSource(stream);
  758. doDeserializeRowset(count, rowset, _rowAllocator, deserializer, rowSource, true);
  759. }
  760. void serializeRowsetX(size32_t count, byte * * rows, IOutputRowSerializer * serializer, MemoryBuffer & buffer)
  761. {
  762. CThorRtlRowSerializer out(buffer);
  763. rtlSerializeRowset(out, serializer, count, rows);
  764. }
  765. void serializeGroupedRowsetX(size32_t count, byte * * rows, IOutputRowSerializer * serializer, MemoryBuffer & buffer)
  766. {
  767. CThorRtlRowSerializer out(buffer);
  768. rtlSerializeGroupedRowset(out, serializer, count, rows);
  769. }
  770. void serializeRow(const void * row, IOutputRowSerializer * serializer, MemoryBuffer & buffer)
  771. {
  772. CThorRtlRowSerializer out(buffer);
  773. serializer->serialize(out, static_cast<const byte *>(row));
  774. }
  775. extern ECLRTL_API byte * rtlDeserializeBufferRow(IEngineRowAllocator * rowAllocator, IOutputRowDeserializer * deserializer, MemoryBuffer & buffer)
  776. {
  777. Owned<ISerialStream> stream = createMemoryBufferSerialStream(buffer);
  778. CThorStreamDeserializerSource source(stream);
  779. RtlDynamicRowBuilder rowBuilder(rowAllocator);
  780. size32_t rowSize = deserializer->deserialize(rowBuilder, source);
  781. return static_cast<byte *>(const_cast<void *>(rowBuilder.finalizeRowClear(rowSize)));
  782. }
  783. extern ECLRTL_API byte * rtlDeserializeRow(IEngineRowAllocator * rowAllocator, IOutputRowDeserializer * deserializer, const void * src)
  784. {
  785. Owned<ISerialStream> stream = createMemorySerialStream(src, 0x7fffffff);
  786. CThorStreamDeserializerSource source(stream);
  787. RtlDynamicRowBuilder rowBuilder(rowAllocator);
  788. size32_t rowSize = deserializer->deserialize(rowBuilder, source);
  789. return static_cast<byte *>(const_cast<void *>(rowBuilder.finalizeRowClear(rowSize)));
  790. }
  791. extern ECLRTL_API size32_t rtlSerializeRow(size32_t lenOut, void * out, IOutputRowSerializer * serializer, const void * src)
  792. {
  793. MemoryBuffer buffer;
  794. CThorRtlRowSerializer result(buffer);
  795. buffer.setBuffer(lenOut, out, false);
  796. buffer.setWritePos(0);
  797. serializer->serialize(result, (const byte *)src);
  798. return buffer.length();
  799. }
  800. class ECLRTL_API CThorRtlBuilderSerializer : implements IRowSerializerTarget
  801. {
  802. public:
  803. CThorRtlBuilderSerializer(ARowBuilder & _builder) : builder(_builder)
  804. {
  805. offset = 0;
  806. }
  807. virtual void put(size32_t len, const void * ptr)
  808. {
  809. byte * data = builder.ensureCapacity(offset + len, "");
  810. memcpy(data+offset, ptr, len);
  811. offset += len;
  812. }
  813. virtual size32_t beginNested()
  814. {
  815. unsigned pos = offset;
  816. offset += sizeof(size32_t);
  817. return pos;
  818. }
  819. virtual void endNested(size32_t sizePos)
  820. {
  821. byte * self = builder.getSelf();
  822. *(size32_t *)(self + sizePos) = offset - (sizePos + sizeof(size32_t));
  823. }
  824. inline size32_t length() const { return offset; }
  825. protected:
  826. ARowBuilder & builder;
  827. size32_t offset;
  828. };
  829. extern ECLRTL_API size32_t rtlDeserializeToBuilder(ARowBuilder & builder, IOutputRowDeserializer * deserializer, const void * src)
  830. {
  831. Owned<ISerialStream> stream = createMemorySerialStream(src, 0x7fffffff);
  832. CThorStreamDeserializerSource source(stream);
  833. return deserializer->deserialize(builder, source);
  834. }
  835. extern ECLRTL_API size32_t rtlSerializeToBuilder(ARowBuilder & builder, IOutputRowSerializer * serializer, const void * src)
  836. {
  837. CThorRtlBuilderSerializer target(builder);
  838. serializer->serialize(target, (const byte *)src);
  839. return target.length();
  840. }
  841. //---------------------------------------------------------------------------
  842. RtlDatasetCursor::RtlDatasetCursor(size32_t _len, const void * _data)
  843. {
  844. setDataset(_len, _data);
  845. }
  846. bool RtlDatasetCursor::exists()
  847. {
  848. return (end != buffer);
  849. }
  850. const byte * RtlDatasetCursor::first()
  851. {
  852. if (buffer != end)
  853. cur = buffer;
  854. return cur;
  855. }
  856. const byte * RtlDatasetCursor::get()
  857. {
  858. return cur;
  859. }
  860. void RtlDatasetCursor::setDataset(size32_t _len, const void * _data)
  861. {
  862. buffer = (const byte *)_data;
  863. end = buffer + _len;
  864. cur = NULL;
  865. }
  866. bool RtlDatasetCursor::isValid()
  867. {
  868. return (cur != NULL);
  869. }
  870. /*
  871. const byte * RtlDatasetCursor::next()
  872. {
  873. if (cur)
  874. {
  875. cur += getRowSize();
  876. if (cur >= end)
  877. cur = NULL;
  878. }
  879. return cur;
  880. }
  881. */
  882. //---------------------------------------------------------------------------
  883. RtlFixedDatasetCursor::RtlFixedDatasetCursor(size32_t _len, const void * _data, unsigned _recordSize) : RtlDatasetCursor(_len, _data)
  884. {
  885. recordSize = _recordSize;
  886. }
  887. RtlFixedDatasetCursor::RtlFixedDatasetCursor() : RtlDatasetCursor(0, NULL)
  888. {
  889. recordSize = 1;
  890. }
  891. size32_t RtlFixedDatasetCursor::count()
  892. {
  893. return (size32_t)((end - buffer) / recordSize);
  894. }
  895. size32_t RtlFixedDatasetCursor::getSize()
  896. {
  897. return recordSize;
  898. }
  899. void RtlFixedDatasetCursor::init(size32_t _len, const void * _data, unsigned _recordSize)
  900. {
  901. recordSize = _recordSize;
  902. setDataset(_len, _data);
  903. }
  904. const byte * RtlFixedDatasetCursor::next()
  905. {
  906. if (cur)
  907. {
  908. cur += recordSize;
  909. if (cur >= end)
  910. cur = NULL;
  911. }
  912. return cur;
  913. }
  914. const byte * RtlFixedDatasetCursor::select(unsigned idx)
  915. {
  916. cur = buffer + idx * recordSize;
  917. if (cur >= end)
  918. cur = NULL;
  919. return cur;
  920. }
  921. //---------------------------------------------------------------------------
  922. RtlVariableDatasetCursor::RtlVariableDatasetCursor(size32_t _len, const void * _data, IRecordSize & _recordSize) : RtlDatasetCursor(_len, _data)
  923. {
  924. recordSize = &_recordSize;
  925. }
  926. RtlVariableDatasetCursor::RtlVariableDatasetCursor() : RtlDatasetCursor(0, NULL)
  927. {
  928. recordSize = NULL;
  929. }
  930. void RtlVariableDatasetCursor::init(size32_t _len, const void * _data, IRecordSize & _recordSize)
  931. {
  932. recordSize = &_recordSize;
  933. setDataset(_len, _data);
  934. }
  935. size32_t RtlVariableDatasetCursor::count()
  936. {
  937. const byte * finger = buffer;
  938. unsigned c = 0;
  939. while (finger < end)
  940. {
  941. finger += recordSize->getRecordSize(finger);
  942. c++;
  943. }
  944. assertex(finger == end);
  945. return c;
  946. }
  947. size32_t RtlVariableDatasetCursor::getSize()
  948. {
  949. return recordSize->getRecordSize(cur);
  950. }
  951. const byte * RtlVariableDatasetCursor::next()
  952. {
  953. if (cur)
  954. {
  955. cur += recordSize->getRecordSize(cur);
  956. if (cur >= end)
  957. cur = NULL;
  958. }
  959. return cur;
  960. }
  961. const byte * RtlVariableDatasetCursor::select(unsigned idx)
  962. {
  963. const byte * finger = buffer;
  964. unsigned c = 0;
  965. while (finger < end)
  966. {
  967. if (c == idx)
  968. {
  969. cur = finger;
  970. return cur;
  971. }
  972. finger += recordSize->getRecordSize(finger);
  973. c++;
  974. }
  975. assertex(finger == end);
  976. cur = NULL;
  977. return NULL;
  978. }
  979. //---------------------------------------------------------------------------
  980. RtlLinkedDatasetCursor::RtlLinkedDatasetCursor(unsigned _numRows, byte * * _rows) : numRows(_numRows), rows(_rows)
  981. {
  982. cur = (unsigned)-1;
  983. }
  984. RtlLinkedDatasetCursor::RtlLinkedDatasetCursor()
  985. {
  986. numRows = 0;
  987. rows = NULL;
  988. cur = (unsigned)-1;
  989. }
  990. void RtlLinkedDatasetCursor::init(unsigned _numRows, byte * * _rows)
  991. {
  992. numRows = _numRows;
  993. rows = _rows;
  994. cur = (unsigned)-1;
  995. }
  996. const byte * RtlLinkedDatasetCursor::first()
  997. {
  998. cur = 0;
  999. return cur < numRows ? rows[cur] : NULL;
  1000. }
  1001. const byte * RtlLinkedDatasetCursor::get()
  1002. {
  1003. return cur < numRows ? rows[cur] : NULL;
  1004. }
  1005. bool RtlLinkedDatasetCursor::isValid()
  1006. {
  1007. return (cur < numRows);
  1008. }
  1009. const byte * RtlLinkedDatasetCursor::next()
  1010. {
  1011. if (cur < numRows)
  1012. cur++;
  1013. return cur < numRows ? rows[cur] : NULL;
  1014. }
  1015. const byte * RtlLinkedDatasetCursor::select(unsigned idx)
  1016. {
  1017. cur = idx;
  1018. return cur < numRows ? rows[cur] : NULL;
  1019. }
  1020. //---------------------------------------------------------------------------
  1021. bool rtlCheckInList(const void * lhs, IRtlDatasetCursor * cursor, ICompare * compare)
  1022. {
  1023. const byte * cur;
  1024. for (cur = cursor->first(); cur; cur = cursor->next())
  1025. {
  1026. if (compare->docompare(lhs, cur) == 0)
  1027. return true;
  1028. }
  1029. return false;
  1030. }
  1031. void rtlSetToSetX(bool & outIsAll, size32_t & outLen, void * & outData, bool inIsAll, size32_t inLen, void * inData)
  1032. {
  1033. outIsAll = inIsAll;
  1034. outLen = inLen;
  1035. outData = malloc(inLen);
  1036. memcpy(outData, inData, inLen);
  1037. }
  1038. void rtlAppendSetX(bool & outIsAll, size32_t & outLen, void * & outData, bool leftIsAll, size32_t leftLen, void * leftData, bool rightIsAll, size32_t rightLen, void * rightData)
  1039. {
  1040. outIsAll = leftIsAll | rightIsAll;
  1041. if (outIsAll)
  1042. {
  1043. outLen = 0;
  1044. outData = NULL;
  1045. }
  1046. else
  1047. {
  1048. outLen = leftLen+rightLen;
  1049. outData = malloc(outLen);
  1050. memcpy(outData, leftData, leftLen);
  1051. memcpy((byte*)outData+leftLen, rightData, rightLen);
  1052. }
  1053. }
  1054. //------------------------------------------------------------------------------
  1055. RtlCompoundIterator::RtlCompoundIterator()
  1056. {
  1057. ok = false;
  1058. numLevels = 0;
  1059. iters = NULL;
  1060. cursors = NULL;
  1061. }
  1062. RtlCompoundIterator::~RtlCompoundIterator()
  1063. {
  1064. delete [] iters;
  1065. delete [] cursors;
  1066. }
  1067. void RtlCompoundIterator::addIter(unsigned idx, IRtlDatasetSimpleCursor * iter, byte * * cursor)
  1068. {
  1069. assertex(idx < numLevels);
  1070. iters[idx] = iter;
  1071. cursors[idx] = cursor;
  1072. }
  1073. void RtlCompoundIterator::init(unsigned _numLevels)
  1074. {
  1075. numLevels = _numLevels;
  1076. iters = new IRtlDatasetSimpleCursor * [numLevels];
  1077. cursors = new byte * * [numLevels];
  1078. }
  1079. //Could either duplicate this function, N times, or have it as a helper function that accesses pre-defined virtuals.
  1080. bool RtlCompoundIterator::first(unsigned level)
  1081. {
  1082. IRtlDatasetSimpleCursor * curIter = iters[level];
  1083. if (level == 0)
  1084. {
  1085. const byte * cur = curIter->first();
  1086. setCursor(level, cur);
  1087. return (cur != NULL);
  1088. }
  1089. if (!first(level-1))
  1090. return false;
  1091. loop
  1092. {
  1093. const byte * cur = curIter->first();
  1094. if (cur)
  1095. {
  1096. setCursor(level, cur);
  1097. return true;
  1098. }
  1099. if (!next(level-1))
  1100. return false;
  1101. }
  1102. }
  1103. bool RtlCompoundIterator::next(unsigned level)
  1104. {
  1105. IRtlDatasetSimpleCursor * curIter = iters[level];
  1106. const byte * cur = curIter->next();
  1107. if (cur)
  1108. {
  1109. setCursor(level, cur);
  1110. return true;
  1111. }
  1112. if (level == 0)
  1113. return false;
  1114. loop
  1115. {
  1116. if (!next(level-1))
  1117. return false;
  1118. const byte * cur = curIter->first();
  1119. if (cur)
  1120. {
  1121. setCursor(level, cur);
  1122. return true;
  1123. }
  1124. }
  1125. }
  1126. //------------------------------------------------------------------------------
  1127. void RtlSimpleIterator::addIter(unsigned idx, IRtlDatasetSimpleCursor * _iter, byte * * _cursor)
  1128. {
  1129. assertex(idx == 0);
  1130. iter = _iter;
  1131. cursor = _cursor;
  1132. *cursor = NULL;
  1133. }
  1134. bool RtlSimpleIterator::first()
  1135. {
  1136. const byte * cur = iter->first();
  1137. *cursor = (byte *)cur;
  1138. return (cur != NULL);
  1139. }
  1140. bool RtlSimpleIterator::next()
  1141. {
  1142. const byte * cur = iter->next();
  1143. *cursor = (byte *)cur;
  1144. return (cur != NULL);
  1145. }