rtlkey.cpp 56 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901
  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 "jlib.hpp"
  14. #include "jsort.hpp"
  15. #include "jexcept.hpp"
  16. #include "rtlkey.hpp"
  17. #include "rtlkey2.hpp"
  18. #include "eclrtl_imp.hpp"
  19. #include "rtlrecord.hpp"
  20. #include "rtlnewkey.hpp"
  21. class CKeySegmentMonitor : implements IKeySegmentMonitor, public CInterface
  22. {
  23. protected:
  24. size32_t size;
  25. size32_t offset;
  26. unsigned fieldIdx;
  27. unsigned hash;
  28. public:
  29. IMPLEMENT_IINTERFACE;
  30. CKeySegmentMonitor(unsigned _fieldIdx, unsigned _offset, unsigned _size);
  31. CKeySegmentMonitor(MemoryBuffer &mb)
  32. {
  33. mb.read(size).read(offset).read(fieldIdx).read(hash);
  34. }
  35. virtual bool matchesBuffer(const void * rawRow) const override = 0;
  36. virtual bool matches(const RtlRow * rawRow) const override
  37. {
  38. return matchesBuffer(rawRow->queryRow());
  39. }
  40. virtual bool increment(void *keyval) const override;
  41. virtual unsigned getFieldIdx() const override { return fieldIdx; }
  42. virtual unsigned getOffset() const override { return offset; }
  43. virtual unsigned getSize() const override { return size; }
  44. virtual bool isWild() const override { return false; }
  45. virtual bool isEmpty() const override { return false; }
  46. virtual bool isSigned() const override { return false; }
  47. virtual bool isLittleEndian() const override { return false; }
  48. virtual unsigned numFieldsRequired() const override { return 0; } // Should rename to queryFieldIdx or similar
  49. virtual int docompare(const void * l, const void * r) const override
  50. {
  51. char *lptr = ((char *) l) + offset;
  52. char *rptr = ((char *) r) + offset;
  53. return memcmp(lptr, rptr, size);
  54. }
  55. virtual bool equivalentTo(const IKeySegmentMonitor &other) const override
  56. {
  57. return offset==other.getOffset()
  58. && size==other.getSize()
  59. && isSigned()==other.isSigned()
  60. && isLittleEndian()==other.isLittleEndian();
  61. }
  62. virtual unsigned queryHashCode() const override
  63. {
  64. return hash;
  65. }
  66. virtual bool setOffset(unsigned _offset) override
  67. {
  68. offset = _offset;
  69. return true;
  70. }
  71. virtual void setHigh(void *keyval) const override;
  72. virtual void copy(void * l, const void * r) const override
  73. {
  74. char *lptr = ((char *) l) + offset;
  75. char *rptr = ((char *) r) + offset;
  76. memcpy(lptr, rptr, size);
  77. }
  78. virtual MemoryBuffer &serialize(MemoryBuffer &mb) const override
  79. {
  80. KeySegmentMonitorSerializeType typ = serializeType();
  81. assertex(typ!=KSMST_none);
  82. return mb.append((byte)typ).append(size).append(offset).append(hash);
  83. }
  84. virtual KeySegmentMonitorSerializeType serializeType() const override = 0;
  85. };
  86. class CWildKeySegmentMonitor : public CKeySegmentMonitor
  87. {
  88. public:
  89. CWildKeySegmentMonitor(unsigned _fieldIdx, unsigned _offset, unsigned _size);
  90. CWildKeySegmentMonitor(MemoryBuffer &mb)
  91. : CKeySegmentMonitor(mb)
  92. {
  93. }
  94. virtual bool matchesBuffer(const void *keyval) const override;
  95. virtual int docompare(const void *,const void *) const override;
  96. virtual void setLow(void *keyval) const override;
  97. virtual void endRange(void *keyval) const override;
  98. virtual bool isWild() const override { return true; }
  99. virtual bool isSimple() const override { return true; }
  100. virtual bool isWellKeyed() const override { return false; }
  101. virtual bool isOptional() const override { return true; }
  102. virtual IKeySegmentMonitor *clone() const override;
  103. virtual KeySegmentMonitorSerializeType serializeType() const override { return KSMST_WILDKEYSEGMENTMONITOR; }
  104. };
  105. class CSetKeySegmentMonitor : public CKeySegmentMonitor
  106. {
  107. private:
  108. Owned<IStringSet> set;
  109. bool optional;
  110. public:
  111. CSetKeySegmentMonitor(bool _optional, IStringSet *set, unsigned _fieldIdx, unsigned _offset, unsigned _size);
  112. CSetKeySegmentMonitor(MemoryBuffer &mb)
  113. : CKeySegmentMonitor(mb)
  114. {
  115. set.setown(deserializeStringSet(mb));
  116. mb.read(optional);
  117. }
  118. // IKeySegmentMonitor
  119. virtual bool increment(void *keyval) const override;
  120. virtual void setLow(void *keyval) const override;
  121. virtual bool matchesBuffer(const void *keyval) const override;
  122. virtual void endRange(void *keyval) const override;
  123. virtual bool isEmpty() const override { return set->isEmptySet(); }
  124. virtual bool isWellKeyed() const override;
  125. virtual bool isOptional() const override { return optional; }
  126. virtual bool isSimple() const override { return true; }
  127. virtual bool isSigned() const override { return set->isSigned(); }
  128. virtual bool isLittleEndian() const override { return !set->isBigEndian(); }
  129. virtual IKeySegmentMonitor *clone() const override;
  130. virtual int docompare(const void * l, const void * r) const override
  131. {
  132. char *lptr = ((char *) l) + offset;
  133. char *rptr = ((char *) r) + offset;
  134. return set->memcmp(lptr, rptr, size);
  135. }
  136. virtual MemoryBuffer &serialize(MemoryBuffer &mb) const override
  137. {
  138. CKeySegmentMonitor::serialize(mb);
  139. set->serialize(mb);
  140. return mb.append(optional);
  141. }
  142. virtual KeySegmentMonitorSerializeType serializeType() const override { return KSMST_SETKEYSEGMENTMONITOR; }
  143. };
  144. CKeySegmentMonitor::CKeySegmentMonitor(unsigned _fieldIdx, unsigned _offset, unsigned _size)
  145. {
  146. size = _size;
  147. offset = _offset;
  148. fieldIdx = _fieldIdx;
  149. hash = 123456;
  150. hash = hashc((unsigned char *) &offset, sizeof(offset), hash);
  151. hash = hashc((unsigned char *) &size, sizeof(size), hash);
  152. }
  153. bool CKeySegmentMonitor::increment(void *bufptr) const
  154. {
  155. char *ptr = ((char *) bufptr) + offset;
  156. int i = size;
  157. while (i--)
  158. {
  159. ptr[i]++;
  160. if (ptr[i]!=0)
  161. return true;
  162. }
  163. return false;
  164. }
  165. void CKeySegmentMonitor::setHigh(void *bufptr) const
  166. {
  167. // NOTE - effectively whenever this is called we are treating the segmonitor as if it was a wild one
  168. char *ptr = ((char *) bufptr) + offset;
  169. memset(ptr, 0xff, size);
  170. }
  171. CWildKeySegmentMonitor::CWildKeySegmentMonitor(unsigned _fieldIdx, unsigned _offset, unsigned _size)
  172. : CKeySegmentMonitor(_fieldIdx, _offset, _size)
  173. {
  174. }
  175. IKeySegmentMonitor *CWildKeySegmentMonitor::clone() const
  176. {
  177. return new CWildKeySegmentMonitor(fieldIdx, offset, size);
  178. }
  179. bool CWildKeySegmentMonitor::matchesBuffer(const void *keyval) const
  180. {
  181. return true;
  182. }
  183. int CWildKeySegmentMonitor::docompare(const void *l, const void *r) const
  184. {
  185. return 0;
  186. }
  187. void CWildKeySegmentMonitor::setLow(void *bufptr) const
  188. {
  189. char *ptr = ((char *) bufptr) + offset;
  190. memset(ptr, 0, size);
  191. }
  192. void CWildKeySegmentMonitor::endRange(void *bufptr) const
  193. {
  194. char *ptr = ((char *) bufptr) + offset;
  195. memset(ptr, 0xff, size);
  196. }
  197. CSetKeySegmentMonitor::CSetKeySegmentMonitor(bool _optional, IStringSet *_set, unsigned _fieldIdx, unsigned _offset, unsigned _size)
  198. : set(_set), CKeySegmentMonitor(_fieldIdx, _offset, _size)
  199. {
  200. optional = _optional;
  201. hash = FNV_32_HASHONE_VALUE(hash, (byte) set->isSigned());
  202. hash = FNV_32_HASHONE_VALUE(hash, (byte) !set->isBigEndian());
  203. }
  204. IKeySegmentMonitor *CSetKeySegmentMonitor::clone() const
  205. {
  206. return new CSetKeySegmentMonitor(optional, set.getLink(), fieldIdx, offset, size);
  207. }
  208. bool CSetKeySegmentMonitor::increment(void *bufptr) const
  209. {
  210. char *ptr = ((char *) bufptr) + offset;
  211. bool ok = set->increment(ptr);
  212. if (ok)
  213. {
  214. unsigned nextTransition;
  215. bool res = set->inRange(ptr, nextTransition);
  216. if (!res)
  217. {
  218. if (-1 == nextTransition) return false;
  219. set->getTransitionValue(ptr, nextTransition);
  220. }
  221. }
  222. return ok;
  223. }
  224. void CSetKeySegmentMonitor::setLow(void *bufptr) const
  225. {
  226. char *ptr = ((char *) bufptr) + offset;
  227. if (set->transitionCount())
  228. set->getTransitionValue(ptr, 0);
  229. else
  230. memset(ptr, 0, size); // MORE - should really trap earlier
  231. }
  232. void CSetKeySegmentMonitor::endRange(void *bufptr) const
  233. {
  234. char *ptr = ((char *) bufptr) + offset;
  235. unsigned nextTransition;
  236. bool res = set->inRange(ptr, nextTransition);
  237. assertex(res);
  238. verifyex(set->getTransitionValue(ptr, nextTransition));
  239. }
  240. bool CSetKeySegmentMonitor::matchesBuffer(const void *bufptr) const
  241. {
  242. char *ptr = ((char *) bufptr) + offset;
  243. return set->inRange(ptr);
  244. }
  245. bool CSetKeySegmentMonitor::isWellKeyed() const
  246. {
  247. // This check determines whether or not keyed, opt considers this field to be keyed.
  248. // The goal is to allow sets but not ranges, slightly complicated by the fact that adjacent values in a set turn into ranges.
  249. return set->numValues() < 50;
  250. }
  251. class CSingleKeySegmentMonitorBase : public CKeySegmentMonitor
  252. {
  253. protected:
  254. void *val;
  255. bool optional;
  256. public:
  257. CSingleKeySegmentMonitorBase(bool _optional, const void *_val, unsigned _fieldIdx, unsigned _offset, unsigned _size)
  258. : CKeySegmentMonitor(_fieldIdx, _offset, _size)
  259. {
  260. if (_val)
  261. {
  262. val = malloc(_size);
  263. memcpy(val, _val, _size);
  264. }
  265. else
  266. val = NULL;
  267. optional = _optional;
  268. }
  269. CSingleKeySegmentMonitorBase(bool _optional, unsigned _fieldIdx, unsigned _offset, unsigned _size)
  270. : CKeySegmentMonitor(_fieldIdx, _offset, _size)
  271. {
  272. val = NULL;
  273. optional = _optional;
  274. }
  275. CSingleKeySegmentMonitorBase(MemoryBuffer &mb)
  276. : CKeySegmentMonitor(mb)
  277. {
  278. bool hasval;
  279. mb.read(hasval);
  280. if (hasval) {
  281. val = malloc(size);
  282. memcpy(val,mb.readDirect(size),size);
  283. }
  284. else
  285. val = NULL;
  286. mb.read(optional);
  287. }
  288. ~CSingleKeySegmentMonitorBase()
  289. {
  290. free(val);
  291. }
  292. // IKeySegmentMonitor
  293. virtual bool increment(void *bufptr) const override
  294. {
  295. // Set to next permitted value above current
  296. if (docompare(bufptr, ((char *) val)-offset) < 0)
  297. {
  298. char *ptr = ((char *) bufptr) + offset;
  299. memcpy(ptr, val, size);
  300. return true;
  301. }
  302. else
  303. return false;
  304. }
  305. virtual void setLow(void *bufptr) const override
  306. {
  307. // Set to lowest permitted value
  308. char *ptr = ((char *) bufptr) + offset;
  309. memcpy(ptr, val, size);
  310. }
  311. virtual bool matchesBuffer(const void *bufptr) const override
  312. {
  313. // Is current a permitted value?
  314. char *ptr = ((char *) bufptr) + offset;
  315. return memcmp(ptr, val, size) == 0;
  316. }
  317. virtual void endRange(void *bufptr) const override
  318. {
  319. // Set to last permitted value in the range that includes current (which is asserted to be valid)
  320. #ifdef DEBUG
  321. assertex(matchesBuffer(bufptr));
  322. #endif
  323. }
  324. virtual bool isWellKeyed() const override { return true; }
  325. virtual bool isOptional() const override { return optional; }
  326. virtual bool isSimple() const override { return true; }
  327. virtual MemoryBuffer &serialize(MemoryBuffer &mb) const override
  328. {
  329. CKeySegmentMonitor::serialize(mb);
  330. if (val)
  331. mb.append((bool)true).append(size,val);
  332. else
  333. mb.append((bool)false);
  334. return mb.append(optional);
  335. }
  336. };
  337. class CSingleKeySegmentMonitor : public CSingleKeySegmentMonitorBase
  338. {
  339. public:
  340. CSingleKeySegmentMonitor(bool _optional, const void *_val, unsigned _fieldIdx, unsigned _offset, unsigned _size)
  341. : CSingleKeySegmentMonitorBase(_optional, _val, _fieldIdx, _offset, _size)
  342. {
  343. hash = FNV_32_HASHONE_VALUE(hash, (byte) 0);
  344. hash = FNV_32_HASHONE_VALUE(hash, (byte) 0);
  345. }
  346. CSingleKeySegmentMonitor(MemoryBuffer &mb)
  347. : CSingleKeySegmentMonitorBase(mb)
  348. {
  349. }
  350. virtual IKeySegmentMonitor *clone() const override
  351. {
  352. return new CSingleKeySegmentMonitor(optional, val, fieldIdx, offset, size);
  353. }
  354. virtual bool isSigned() const override { return false; }
  355. virtual bool isLittleEndian() const override { return false; }
  356. virtual KeySegmentMonitorSerializeType serializeType() const override { return KSMST_SINGLEKEYSEGMENTMONITOR; }
  357. };
  358. class CSingleBigSignedKeySegmentMonitor : public CSingleKeySegmentMonitorBase
  359. {
  360. public:
  361. CSingleBigSignedKeySegmentMonitor(bool _optional, const void *_val, unsigned _fieldIdx, unsigned _offset, unsigned _size)
  362. : CSingleKeySegmentMonitorBase(_optional, _val, _fieldIdx, _offset, _size)
  363. {
  364. hash = FNV_32_HASHONE_VALUE(hash, (byte) 1);
  365. hash = FNV_32_HASHONE_VALUE(hash, (byte) 0);
  366. }
  367. CSingleBigSignedKeySegmentMonitor(MemoryBuffer &mb)
  368. : CSingleKeySegmentMonitorBase(mb)
  369. {
  370. }
  371. virtual IKeySegmentMonitor *clone() const override
  372. {
  373. return new CSingleBigSignedKeySegmentMonitor(optional, val, fieldIdx, offset, size);
  374. }
  375. virtual int docompare(const void *l, const void *r) const override
  376. {
  377. return memcmpbigsigned(((char *) l) + offset, ((char *) r) + offset, size);
  378. }
  379. virtual bool isSigned() const override { return true; }
  380. virtual bool isLittleEndian() const override { return false; }
  381. virtual KeySegmentMonitorSerializeType serializeType() const override { return KSMST_SINGLEBIGSIGNEDKEYSEGMENTMONITOR; }
  382. };
  383. class CSingleLittleSignedKeySegmentMonitor : public CSingleKeySegmentMonitorBase
  384. {
  385. public:
  386. CSingleLittleSignedKeySegmentMonitor(bool _optional, const void *_val, unsigned _fieldIdx, unsigned _offset, unsigned _size)
  387. : CSingleKeySegmentMonitorBase(_optional, _val, _fieldIdx, _offset, _size)
  388. {
  389. hash = FNV_32_HASHONE_VALUE(hash, (byte) 1);
  390. hash = FNV_32_HASHONE_VALUE(hash, (byte) 1);
  391. }
  392. CSingleLittleSignedKeySegmentMonitor(MemoryBuffer &mb)
  393. : CSingleKeySegmentMonitorBase(mb)
  394. {
  395. }
  396. virtual IKeySegmentMonitor *clone() const override
  397. {
  398. return new CSingleLittleSignedKeySegmentMonitor(optional, val, fieldIdx, offset, size);
  399. }
  400. virtual int docompare(const void *l, const void *r) const
  401. {
  402. return memcmplittlesigned(((char *) l) + offset, ((char *) r) + offset, size);
  403. }
  404. virtual bool isSigned() const override { return true; }
  405. virtual bool isLittleEndian() const override { return true; }
  406. virtual KeySegmentMonitorSerializeType serializeType() const override { return KSMST_SINGLELITTLESIGNEDKEYSEGMENTMONITOR; }
  407. };
  408. class CSingleLittleKeySegmentMonitor : public CSingleKeySegmentMonitorBase
  409. {
  410. public:
  411. CSingleLittleKeySegmentMonitor(bool _optional, const void *_val, unsigned _fieldIdx, unsigned _offset, unsigned _size)
  412. : CSingleKeySegmentMonitorBase(_optional, _val, _fieldIdx, _offset, _size)
  413. {
  414. hash = FNV_32_HASHONE_VALUE(hash, (byte) 0);
  415. hash = FNV_32_HASHONE_VALUE(hash, (byte) 1);
  416. }
  417. CSingleLittleKeySegmentMonitor(MemoryBuffer &mb)
  418. : CSingleKeySegmentMonitorBase(mb)
  419. {
  420. }
  421. virtual IKeySegmentMonitor *clone() const override
  422. {
  423. return new CSingleLittleKeySegmentMonitor(optional, val, fieldIdx, offset, size);
  424. }
  425. virtual int docompare(const void *l, const void *r) const override
  426. {
  427. return memcmplittleunsigned(((char *) l) + offset, ((char *) r) + offset, size);
  428. }
  429. virtual bool isSigned() const override { return false; }
  430. virtual bool isLittleEndian() const override { return true; }
  431. virtual KeySegmentMonitorSerializeType serializeType() const override { return KSMST_CSINGLELITTLEKEYSEGMENTMONITOR; }
  432. };
  433. class COverrideableKeySegmentMonitor : public IOverrideableKeySegmentMonitor, public CInterface
  434. {
  435. const void *overridden;
  436. unsigned hash;
  437. public:
  438. IMPLEMENT_IINTERFACE
  439. COverrideableKeySegmentMonitor(IKeySegmentMonitor * _base)
  440. {
  441. base.setown(_base);
  442. overridden = NULL;
  443. hash = base->queryHashCode();
  444. hash = FNV_32_HASHONE_VALUE(hash, (byte) 123);
  445. }
  446. COverrideableKeySegmentMonitor(MemoryBuffer &mb)
  447. {
  448. mb.read(hash);
  449. base.setown(deserializeKeySegmentMonitor(mb));
  450. overridden = NULL;
  451. }
  452. virtual void setOverrideBuffer(const void *ptr) override
  453. {
  454. overridden = ptr;
  455. }
  456. virtual unsigned queryHashCode() const override
  457. {
  458. return hash;
  459. }
  460. virtual bool matchesBuffer(const void *keyval) const override
  461. {
  462. if (overridden)
  463. {
  464. unsigned offset = base->getOffset();
  465. return memcmp((char *) keyval+offset, (char *) overridden+offset, base->getSize()) == 0;
  466. }
  467. else
  468. return base->matchesBuffer(keyval);
  469. }
  470. virtual bool matches(const RtlRow *keyval) const override
  471. {
  472. return matchesBuffer(keyval->queryRow());
  473. }
  474. virtual bool increment(void *keyval) const override
  475. {
  476. if (overridden)
  477. {
  478. // Set to next permitted value above current
  479. unsigned offset = base->getOffset();
  480. if (memcmp((char *) keyval+offset, (char *) overridden+offset, base->getSize()) < 0)
  481. {
  482. memcpy((char *) keyval+offset, (char *) overridden+offset, base->getSize());
  483. return true;
  484. }
  485. return false;
  486. }
  487. else
  488. return base->increment(keyval);
  489. }
  490. virtual void setLow(void *keyval) const override
  491. {
  492. if (overridden)
  493. {
  494. unsigned offset = base->getOffset();
  495. memcpy((char *) keyval+offset, (char *) overridden+offset, base->getSize());
  496. }
  497. else
  498. base->setLow(keyval);
  499. }
  500. virtual void setHigh(void *keyval) const override
  501. {
  502. if (overridden)
  503. {
  504. unsigned offset = base->getOffset();
  505. memcpy((char *) keyval+offset, (char *) overridden+offset, base->getSize());
  506. }
  507. else
  508. base->setHigh(keyval);
  509. }
  510. virtual void endRange(void *keyval) const override
  511. {
  512. if (overridden)
  513. {
  514. unsigned offset = base->getOffset();
  515. memcpy((char *) keyval+offset, (char *) overridden+offset, base->getSize());
  516. }
  517. base->endRange(keyval);
  518. }
  519. virtual void copy(void * expandedRow, const void *rawRight) const override
  520. {
  521. base->copy(expandedRow, rawRight);
  522. }
  523. virtual bool isWild() const override { return overridden ? false : base->isWild(); }
  524. virtual unsigned getFieldIdx() const override { return base->getFieldIdx(); }
  525. virtual unsigned getOffset() const override { return base->getOffset(); }
  526. virtual unsigned getSize() const override { return base->getSize(); }
  527. virtual bool isEmpty() const override { return base->isEmpty(); }
  528. virtual bool isSigned() const override { return base->isSigned(); }
  529. virtual bool isLittleEndian() const override { return base->isLittleEndian(); }
  530. virtual bool isWellKeyed() const override { return overridden ? true : base->isWellKeyed(); }
  531. virtual bool isOptional() const override { return base->isOptional(); }
  532. virtual unsigned numFieldsRequired() const override { return base->numFieldsRequired(); }
  533. virtual bool isSimple() const override { return base->isSimple(); }
  534. virtual bool equivalentTo(const IKeySegmentMonitor &other) const override { throwUnexpected(); }
  535. virtual int docompare(const void * expandedLeft, const void *rawRight) const override { throwUnexpected(); }
  536. virtual bool setOffset(unsigned _offset) override { throwUnexpected(); }
  537. virtual MemoryBuffer &serialize(MemoryBuffer &mb) const override { throwUnexpected(); }
  538. virtual KeySegmentMonitorSerializeType serializeType() const override { throwUnexpected(); }
  539. virtual IKeySegmentMonitor *clone() const override { throwUnexpected(); }
  540. protected:
  541. Owned<IKeySegmentMonitor> base;
  542. };
  543. ECLRTL_API IStringSet *createRtlStringSet(size32_t size)
  544. {
  545. return createStringSet(size);
  546. }
  547. ECLRTL_API IStringSet *createRtlStringSetEx(size32_t size, bool bigEndian, bool isSigned)
  548. {
  549. return createStringSet(size, bigEndian, isSigned);
  550. }
  551. ECLRTL_API IStringSet * rtlUnionSet(IStringSet * lhs, IStringSet * rhs)
  552. {
  553. if (lhs->isEmptySet())
  554. return LINK(rhs);
  555. else if (lhs->isFullSet())
  556. return LINK(lhs);
  557. if (rhs->isEmptySet())
  558. return LINK(lhs);
  559. else if (rhs->isFullSet())
  560. return LINK(rhs);
  561. return lhs->unionSet(rhs);
  562. }
  563. ECLRTL_API IStringSet * rtlIntersectSet(IStringSet * lhs, IStringSet * rhs)
  564. {
  565. if (lhs->isFullSet())
  566. return LINK(rhs);
  567. else if (lhs->isEmptySet())
  568. return LINK(lhs);
  569. if (rhs->isFullSet())
  570. return LINK(lhs);
  571. else if (rhs->isEmptySet())
  572. return LINK(rhs);
  573. return lhs->intersectSet(rhs);
  574. }
  575. IKeySegmentMonitor *createKeySegmentMonitor(bool optional, IStringSet *set, unsigned _fieldIdx, unsigned _offset, unsigned _size)
  576. {
  577. if (!set)
  578. return new CWildKeySegmentMonitor(_fieldIdx, _offset, _size);
  579. Owned<IStringSet> removeSet = set; // make sure set is released if optimized out.
  580. if (set->isSingleValue())
  581. {
  582. void *data = alloca(_size);
  583. set->getTransitionValue(data, 0);
  584. if (set->isSigned())
  585. {
  586. if (set->isBigEndian())
  587. return createSingleBigSignedKeySegmentMonitor(optional, _fieldIdx, _offset, _size, data);
  588. else
  589. return createSingleLittleSignedKeySegmentMonitor(optional, _fieldIdx, _offset, _size, data);
  590. }
  591. else
  592. {
  593. if (set->isBigEndian())
  594. return createSingleKeySegmentMonitor(optional, _fieldIdx, _offset, _size, data);
  595. else
  596. return createSingleLittleKeySegmentMonitor(optional, _fieldIdx, _offset, _size, data);
  597. }
  598. }
  599. else if (set->isFullSet())
  600. return new CWildKeySegmentMonitor(_fieldIdx, _offset, _size);
  601. else
  602. return new CSetKeySegmentMonitor(optional, removeSet.getClear(), _fieldIdx, _offset, _size);
  603. }
  604. ECLRTL_API IStringSet *createRtlStringValue(size32_t size, const char * value)
  605. {
  606. IStringSet * set = createStringSet(size);
  607. set->addRange(value, value);
  608. return set;
  609. }
  610. IKeySegmentMonitor *createWildKeySegmentMonitor(unsigned _fieldIdx, unsigned _offset, unsigned _size)
  611. {
  612. return new CWildKeySegmentMonitor(_fieldIdx, _offset, _size);
  613. }
  614. IKeySegmentMonitor *createEmptyKeySegmentMonitor(bool optional, unsigned _fieldIdx, unsigned _offset, unsigned _size)
  615. {
  616. return new CSetKeySegmentMonitor(optional, createStringSet(_size), _fieldIdx, _offset, _size);
  617. }
  618. ECLRTL_API IKeySegmentMonitor *createSingleKeySegmentMonitor(bool optional, unsigned _fieldIdx, unsigned offset, unsigned size, const void * value)
  619. {
  620. return new CSingleKeySegmentMonitor(optional, value, _fieldIdx, offset, size);
  621. }
  622. ECLRTL_API IOverrideableKeySegmentMonitor *createOverrideableKeySegmentMonitor(IKeySegmentMonitor *base)
  623. {
  624. return new COverrideableKeySegmentMonitor(base);
  625. }
  626. ECLRTL_API IKeySegmentMonitor *createSingleBigSignedKeySegmentMonitor(bool optional, unsigned fieldIdx, unsigned offset, unsigned size, const void * value)
  627. {
  628. return new CSingleBigSignedKeySegmentMonitor(optional, value, fieldIdx, offset, size);
  629. }
  630. ECLRTL_API IKeySegmentMonitor *createSingleLittleSignedKeySegmentMonitor(bool optional, unsigned fieldIdx, unsigned offset, unsigned size, const void * value)
  631. {
  632. // MORE - common int sizes 1,2,4 (8?) might be better done with dedicated subclasses
  633. return new CSingleLittleSignedKeySegmentMonitor(optional, value, fieldIdx, offset, size);
  634. }
  635. ECLRTL_API IKeySegmentMonitor *createSingleLittleKeySegmentMonitor(bool optional, unsigned fieldIdx, unsigned offset, unsigned size, const void * value)
  636. {
  637. // MORE - common int sizes 1,2,4 (8?) might be better done with dedicated subclasses
  638. return new CSingleLittleKeySegmentMonitor(optional, value, fieldIdx, offset, size);
  639. }
  640. ECLRTL_API IKeySegmentMonitor *createDummyKeySegmentMonitor(unsigned _fieldIdx, unsigned _offset, unsigned _size, bool isSigned, bool isLittleEndian)
  641. {
  642. if (isSigned)
  643. if (isLittleEndian)
  644. return new CSingleLittleSignedKeySegmentMonitor(false, NULL, _fieldIdx, _offset, _size);
  645. else
  646. return new CSingleBigSignedKeySegmentMonitor(false, NULL, _fieldIdx, _offset, _size);
  647. else
  648. if (isLittleEndian)
  649. return new CSingleLittleKeySegmentMonitor(false, NULL, _fieldIdx, _offset, _size);
  650. else
  651. return new CSingleKeySegmentMonitor(false, NULL, _fieldIdx, _offset, _size);
  652. }
  653. ECLRTL_API IKeySegmentMonitor *deserializeKeySegmentMonitor(MemoryBuffer &mb)
  654. {
  655. byte typ;
  656. mb.read(typ);
  657. switch ((KeySegmentMonitorSerializeType)typ) {
  658. case KSMST_WILDKEYSEGMENTMONITOR:
  659. return new CWildKeySegmentMonitor(mb);
  660. case KSMST_SETKEYSEGMENTMONITOR:
  661. return new CSetKeySegmentMonitor(mb);
  662. case KSMST_SINGLEKEYSEGMENTMONITOR:
  663. return new CSingleKeySegmentMonitor(mb);
  664. case KSMST_SINGLEBIGSIGNEDKEYSEGMENTMONITOR:
  665. return new CSingleBigSignedKeySegmentMonitor(mb);
  666. case KSMST_SINGLELITTLESIGNEDKEYSEGMENTMONITOR:
  667. return new CSingleLittleSignedKeySegmentMonitor(mb);
  668. case KSMST_CSINGLELITTLEKEYSEGMENTMONITOR:
  669. return new CSingleLittleKeySegmentMonitor(mb);
  670. case KSMST_OVERRIDEABLEKEYSEGMENTMONITOR:
  671. return new COverrideableKeySegmentMonitor(mb);
  672. }
  673. return NULL; // up to caller to check
  674. }
  675. enum StringSetSerializeType
  676. {
  677. SSST_none,
  678. SSST_BIGUNSIGNEDSTRINGSET,
  679. SSST_BIGSIGNEDSTRINGSET,
  680. SSST_LITTLEUNSIGNEDSTRINGSET,
  681. SSST_LITTLESIGNEDSTRINGSET,
  682. SSST_max
  683. };
  684. ECLRTL_API int memcmpbigsigned(const void *l, const void *r, unsigned size)
  685. {
  686. signed int diff = ((signed char *) l)[0]-((signed char *) r)[0];
  687. if (diff)
  688. return diff;
  689. for(unsigned i = 1; i < size; i++)
  690. {
  691. diff = ((unsigned char *) l)[i]-((unsigned char *) r)[i];
  692. if (diff)
  693. return diff;
  694. }
  695. return 0;
  696. }
  697. ECLRTL_API int memcmplittleunsigned(const void *l, const void *r, unsigned size)
  698. {
  699. while (size)
  700. {
  701. size--;
  702. int diff = ((unsigned char *) l)[size]-((unsigned char *) r)[size];
  703. if (diff)
  704. return diff;
  705. }
  706. return 0;
  707. }
  708. ECLRTL_API int memcmplittlesigned(const void *l, const void *r, unsigned size)
  709. {
  710. size--;
  711. signed int diff = ((signed char *) l)[size]-((signed char *) r)[size];
  712. if (diff)
  713. return diff;
  714. while (size)
  715. {
  716. size--;
  717. diff = ((unsigned char *) l)[size]-((unsigned char *) r)[size];
  718. if (diff)
  719. return diff;
  720. }
  721. return 0;
  722. }
  723. class CStringSet : implements IStringSet, public CInterface
  724. {
  725. protected:
  726. size32_t size;
  727. IArrayOf<ITransition> transitions;
  728. IStringSet *unionOrIntersect(IStringSet *r, bool isUnion);
  729. virtual CStringSet *createEmptySet() = 0;
  730. virtual bool decrement(void *val) const = 0;
  731. virtual bool increment(void *val) const = 0;
  732. virtual int memcmp(const void *val1, const void *val2, size32_t size) const = 0;
  733. virtual unsigned getCardinality(const void *val1, const void *val2, size32_t size) const = 0;
  734. virtual void memset(void *ptr, int val, size32_t size) const = 0;
  735. virtual bool isLowVal(const void *val) const = 0;
  736. virtual bool isHighVal(const void *val) const = 0;
  737. bool oneless(const void *l, const void *r) const;
  738. void addTransitionAt(const void *val, bool state, unsigned pos);
  739. void appendTransition(ITransition *t);
  740. public:
  741. IMPLEMENT_IINTERFACE;
  742. CStringSet(size32_t size);
  743. CStringSet(MemoryBuffer &mb);
  744. // IStringSet
  745. virtual void addRange(const void *loval, const void *hival);
  746. virtual void addAll();
  747. virtual ITransition *queryTransition(unsigned idx);
  748. virtual bool getTransitionValue(void *value, unsigned idx);
  749. virtual void killRange(const void *loval, const void *hival);
  750. virtual bool inRange(const void *val) const;
  751. virtual bool inRange(const void *val, unsigned &transition) const;
  752. virtual size32_t getSize() { return size; };
  753. virtual void reset();
  754. virtual unsigned transitionCount();
  755. virtual IStringSet *invertSet();
  756. virtual IStringSet *unionSet(IStringSet *);
  757. virtual IStringSet *intersectSet(IStringSet *);
  758. virtual const char *describe(StringBuffer &ret);
  759. virtual bool isEmptySet() const { return transitions.length()==0; }
  760. virtual bool isFullSet() const
  761. {
  762. return transitions.length()==2 &&
  763. isLowVal(transitions.item(0).getValue()) &&
  764. isHighVal(transitions.item(1).getValue());
  765. }
  766. virtual bool isSingleValue() const
  767. {
  768. return transitions.length()==2 &&
  769. memcmp(transitions.item(0).getValue(), transitions.item(1).getValue(), size) == 0;
  770. }
  771. virtual unsigned numValues() const
  772. {
  773. unsigned ret = 0;
  774. unsigned idx = 0;
  775. while (transitions.isItem(idx+1))
  776. {
  777. unsigned thisrange = getCardinality(transitions.item(idx).getValue(), transitions.item(idx+1).getValue(), size);
  778. if (thisrange + ret < ret)
  779. return (unsigned) -1;
  780. ret += thisrange;
  781. idx += 2;
  782. }
  783. return ret;
  784. }
  785. virtual MemoryBuffer &serialize(MemoryBuffer &mb) const
  786. {
  787. StringSetSerializeType typ = serializeType();
  788. assertex(typ!=SSST_none);
  789. mb.append((byte)typ).append(size).append(transitions.ordinality());
  790. ForEachItemIn(i,transitions) {
  791. transitions.item(i).serialize(size,mb);
  792. }
  793. return mb;
  794. }
  795. virtual StringSetSerializeType serializeType() const = 0;
  796. };
  797. class CBigUnsignedStringSet : public CStringSet
  798. {
  799. protected:
  800. virtual CStringSet *createEmptySet()
  801. {
  802. return new CBigUnsignedStringSet(size);
  803. }
  804. virtual bool increment(void *_val) const
  805. {
  806. unsigned char *val = (unsigned char *)_val;
  807. int i = size;
  808. while (i--)
  809. {
  810. val[i]++;
  811. if (val[i]!=0)
  812. return true;
  813. }
  814. return false;
  815. }
  816. virtual bool decrement(void *_val) const
  817. {
  818. unsigned char *val = (unsigned char *)_val;
  819. int i = size;
  820. while (i--)
  821. {
  822. val[i]--;
  823. if ((unsigned char)val[i]!=0xff)
  824. return true;
  825. }
  826. return false;
  827. }
  828. virtual int memcmp(const void *val1, const void *val2, size32_t size) const
  829. {
  830. return ::memcmp(val1, val2, size);
  831. }
  832. virtual void memset(void *ptr, int val, size32_t size) const
  833. {
  834. ::memset(ptr, val, size);
  835. }
  836. virtual unsigned getCardinality(const void *val1, const void *val2, size32_t size) const
  837. {
  838. unsigned char *p1 = (unsigned char *) val1;
  839. unsigned char *p2 = (unsigned char *) val2;
  840. unsigned ret = 1;
  841. unsigned mult = 1;
  842. while (size--)
  843. {
  844. unsigned diff = p2[size] - p1[size];
  845. if (diff)
  846. {
  847. if (!mult)
  848. return (unsigned) -1;
  849. else
  850. ret += diff * mult;
  851. }
  852. if (mult*256 < mult)
  853. mult = 0;
  854. else
  855. mult *= 256;
  856. }
  857. return ret;
  858. }
  859. virtual bool isHighVal(const void *val) const
  860. {
  861. const unsigned char *vval = (const unsigned char *) val;
  862. for (unsigned i = 0; i < size; i++)
  863. if (vval[i] != 0xff)
  864. return false;
  865. return true;
  866. }
  867. virtual bool isLowVal(const void *val) const
  868. {
  869. const unsigned char *vval = (const unsigned char *) val;
  870. for (unsigned i = 0; i < size; i++)
  871. if (vval[i] != 0x00)
  872. return false;
  873. return true;
  874. }
  875. virtual bool isSigned() const { return false; }
  876. virtual bool isBigEndian() const { return true; }
  877. virtual StringSetSerializeType serializeType() const
  878. {
  879. return SSST_BIGUNSIGNEDSTRINGSET;
  880. }
  881. public:
  882. CBigUnsignedStringSet(unsigned size) : CStringSet(size) {}
  883. CBigUnsignedStringSet(MemoryBuffer &mb) : CStringSet(mb) {}
  884. };
  885. class CBigSignedStringSet : public CBigUnsignedStringSet
  886. {
  887. protected:
  888. virtual CStringSet *createEmptySet()
  889. {
  890. return new CBigSignedStringSet(size);
  891. }
  892. // increment and decrement are same as unsigned
  893. virtual int memcmp(const void *val1, const void *val2, size32_t size) const
  894. {
  895. return ::memcmpbigsigned(val1, val2, size);
  896. }
  897. virtual void memset(void *ptr, int val, size32_t size) const
  898. {
  899. ::memset(ptr, val, size);
  900. switch(val)
  901. {
  902. case 0:
  903. *(unsigned char *) ptr = 0x80;
  904. break;
  905. case 0xff:
  906. *(unsigned char *) ptr = 0x7f;
  907. break;
  908. default:
  909. throwUnexpected();
  910. }
  911. }
  912. virtual bool isHighVal(const void *val) const
  913. {
  914. const unsigned char *vval = (const unsigned char *) val;
  915. if (vval[0] != 0x7f)
  916. return false;
  917. for (unsigned i = 1; i < size; i++)
  918. if (vval[i] != 0xff)
  919. return false;
  920. return true;
  921. }
  922. virtual bool isLowVal(const void *val) const
  923. {
  924. const unsigned char *vval = (const unsigned char *) val;
  925. if (vval[0] != 0x80)
  926. return false;
  927. for (unsigned i = 1; i < size; i++)
  928. if (vval[i] != 0x00)
  929. return false;
  930. return true;
  931. }
  932. virtual bool isSigned() const { return true; }
  933. virtual bool isBigEndian() const { return true; }
  934. virtual StringSetSerializeType serializeType() const
  935. {
  936. return SSST_BIGSIGNEDSTRINGSET;
  937. }
  938. public:
  939. CBigSignedStringSet(unsigned size) : CBigUnsignedStringSet(size) {}
  940. CBigSignedStringSet(MemoryBuffer &mb) : CBigUnsignedStringSet(mb) {}
  941. };
  942. class CLittleUnsignedStringSet : public CStringSet
  943. {
  944. protected:
  945. virtual CStringSet *createEmptySet()
  946. {
  947. return new CLittleUnsignedStringSet(size);
  948. }
  949. virtual bool increment(void *_val) const
  950. {
  951. unsigned char *val = (unsigned char *)_val;
  952. unsigned i = 0;
  953. while (i < size)
  954. {
  955. val[i]++;
  956. if (val[i]!=0)
  957. return true;
  958. i++;
  959. }
  960. return false;
  961. }
  962. virtual unsigned getCardinality(const void *val1, const void *val2, size32_t size) const
  963. {
  964. unsigned char *p1 = (unsigned char *) val1;
  965. unsigned char *p2 = (unsigned char *) val2;
  966. unsigned ret = 1;
  967. unsigned mult = 1;
  968. unsigned i = 0;
  969. while (i < size)
  970. {
  971. unsigned diff = p2[i] - p1[i];
  972. if (diff)
  973. {
  974. if (!mult)
  975. return (unsigned) -1;
  976. else
  977. ret += diff * mult;
  978. }
  979. if (mult*256 < mult)
  980. mult = 0;
  981. else
  982. mult *= 256;
  983. i++;
  984. }
  985. return ret;
  986. }
  987. virtual bool decrement(void *_val) const
  988. {
  989. unsigned char *val = (unsigned char *)_val;
  990. unsigned i = 0;
  991. while (i < size)
  992. {
  993. val[i]--;
  994. if ((unsigned char)val[i]!=0xff)
  995. return true;
  996. i++;
  997. }
  998. return false;
  999. }
  1000. virtual int memcmp(const void *val1, const void *val2, size32_t size) const
  1001. {
  1002. return ::memcmplittleunsigned(val1, val2, size);
  1003. }
  1004. virtual void memset(void *ptr, int val, size32_t size) const
  1005. {
  1006. ::memset(ptr, val, size);
  1007. }
  1008. virtual bool isHighVal(const void *val) const
  1009. {
  1010. const unsigned char *vval = (const unsigned char *) val;
  1011. for (unsigned i = 0; i < size; i++)
  1012. if (vval[i] != 0xff)
  1013. return false;
  1014. return true;
  1015. }
  1016. virtual bool isLowVal(const void *val) const
  1017. {
  1018. const unsigned char *vval = (const unsigned char *) val;
  1019. for (unsigned i = 0; i < size; i++)
  1020. if (vval[i] != 0x00)
  1021. return false;
  1022. return true;
  1023. }
  1024. virtual bool isSigned() const { return false; }
  1025. virtual bool isBigEndian() const { return false; }
  1026. virtual StringSetSerializeType serializeType() const
  1027. {
  1028. return SSST_LITTLEUNSIGNEDSTRINGSET;
  1029. }
  1030. public:
  1031. CLittleUnsignedStringSet(unsigned size) : CStringSet(size) {}
  1032. CLittleUnsignedStringSet(MemoryBuffer &mb) : CStringSet(mb) {}
  1033. };
  1034. class CLittleSignedStringSet : public CLittleUnsignedStringSet
  1035. {
  1036. protected:
  1037. virtual CStringSet *createEmptySet()
  1038. {
  1039. return new CLittleSignedStringSet(size);
  1040. }
  1041. // increment and decrement are same as unsigned
  1042. virtual int memcmp(const void *val1, const void *val2, size32_t size) const
  1043. {
  1044. return ::memcmplittlesigned(val1, val2, size);
  1045. }
  1046. virtual void memset(void *ptr, int val, size32_t size) const
  1047. {
  1048. if (size > 1)
  1049. ::memset(ptr, val, size);
  1050. unsigned char *pptr = (unsigned char *) ptr;
  1051. switch(val)
  1052. {
  1053. case 0:
  1054. pptr[size-1] = 0x80;
  1055. break;
  1056. case 0xff:
  1057. pptr[size-1] = 0x7f;
  1058. break;
  1059. default:
  1060. throwUnexpected();
  1061. }
  1062. }
  1063. virtual bool isHighVal(const void *val) const
  1064. {
  1065. const unsigned char *vval = (const unsigned char *) val;
  1066. if (vval[size-1] != 0x7f)
  1067. return false;
  1068. for (unsigned i = 0; i < size-1; i++)
  1069. if (vval[i] != 0xff)
  1070. return false;
  1071. return true;
  1072. }
  1073. virtual bool isLowVal(const void *val) const
  1074. {
  1075. const unsigned char *vval = (const unsigned char *) val;
  1076. if (vval[size-1] != 0x80)
  1077. return false;
  1078. for (unsigned i = 0; i < size-1; i++)
  1079. if (vval[i] != 0x00)
  1080. return false;
  1081. return true;
  1082. }
  1083. virtual bool isSigned() const { return true; }
  1084. virtual bool isBigEndian() const { return false; }
  1085. virtual StringSetSerializeType serializeType() const
  1086. {
  1087. return SSST_LITTLESIGNEDSTRINGSET;
  1088. }
  1089. public:
  1090. CLittleSignedStringSet(unsigned size) : CLittleUnsignedStringSet(size) {}
  1091. CLittleSignedStringSet(MemoryBuffer &mb) : CLittleUnsignedStringSet(mb) {}
  1092. };
  1093. class CTransition : implements ITransition, public CInterface
  1094. {
  1095. private:
  1096. bool state; // note: should move before ITransition to pack better in 64bit
  1097. const void *val;
  1098. public:
  1099. IMPLEMENT_IINTERFACE;
  1100. CTransition(const void *_val, bool _state)
  1101. {
  1102. val = _val;
  1103. state = _state;
  1104. }
  1105. CTransition(MemoryBuffer &mb,size32_t size)
  1106. {
  1107. mb.read(state);
  1108. val = malloc(size);
  1109. memcpy((void *)val,mb.readDirect(size),size);
  1110. }
  1111. ~CTransition() { free((void *) val); }
  1112. // ITransition
  1113. bool getState() const { return state; }
  1114. const void *getValue() const { return val; }
  1115. MemoryBuffer &serialize(size32_t size, MemoryBuffer &mb) const
  1116. {
  1117. mb.append(state);
  1118. memcpy(mb.reserve(size),val,size);
  1119. return mb;
  1120. }
  1121. bool canSerialize() const { return true; }
  1122. };
  1123. //======================================================================================
  1124. CStringSet::CStringSet(size32_t _size)
  1125. {
  1126. size = _size;
  1127. }
  1128. CStringSet::CStringSet(MemoryBuffer &mb)
  1129. {
  1130. mb.read(size);
  1131. unsigned n;
  1132. mb.read(n);
  1133. while(n--)
  1134. transitions.append(*new CTransition(mb,size));
  1135. }
  1136. void CStringSet::reset()
  1137. {
  1138. transitions.kill();
  1139. }
  1140. bool CStringSet::oneless(const void *l, const void *r) const
  1141. {
  1142. // MORE - would be more efficient to make this virtual like the memcmp...
  1143. void *t = alloca(size);
  1144. memcpy(t, r, size);
  1145. decrement(t);
  1146. return memcmp(l, t, size)==0;
  1147. }
  1148. unsigned CStringSet::transitionCount()
  1149. {
  1150. return transitions.ordinality();
  1151. }
  1152. void CStringSet::addTransitionAt(const void *val, bool state, unsigned pos)
  1153. {
  1154. void *newval = malloc(size);
  1155. memcpy(newval, val, size);
  1156. transitions.add(* new CTransition(newval, state), pos);
  1157. }
  1158. void CStringSet::appendTransition(ITransition *t)
  1159. {
  1160. if (t->getState() && transitions.length())
  1161. {
  1162. unsigned lastidx = transitions.length()-1;
  1163. ITransition &prev = transitions.item(lastidx);
  1164. assertex(prev.getState()==!t->getState());
  1165. if (oneless(prev.getValue(), t->getValue()))
  1166. {
  1167. transitions.remove(lastidx);
  1168. t->Release();
  1169. return;
  1170. }
  1171. }
  1172. transitions.append(*t);
  1173. }
  1174. void CStringSet::addRange(const void *loval, const void *hival)
  1175. {
  1176. if (!loval)
  1177. {
  1178. void *x = alloca(size);
  1179. memset(x, 0, size);
  1180. loval = x;
  1181. }
  1182. if (!hival)
  1183. {
  1184. void *x = alloca(size);
  1185. memset(x, 0xff, size);
  1186. hival = x;
  1187. }
  1188. if (memcmp(loval, hival, size) > 0)
  1189. return;
  1190. unsigned idx;
  1191. bool inset = false;
  1192. int b = transitions.ordinality();
  1193. if (!b)
  1194. {
  1195. addTransitionAt(loval, true, 0);
  1196. addTransitionAt(hival, false, 1);
  1197. return;
  1198. }
  1199. else
  1200. {
  1201. // binchop to find last transition > val...
  1202. unsigned int a = 0;
  1203. int rc;
  1204. while ((int)a<b)
  1205. {
  1206. int i = a+(b+1-a)/2;
  1207. rc = memcmp(loval, transitions.item(i-1).getValue(), size);
  1208. if (rc>0)
  1209. a = i;
  1210. else
  1211. b = i-1;
  1212. }
  1213. if (a>0)
  1214. {
  1215. idx = a;
  1216. ITransition &t = transitions.item(idx-1);
  1217. if(!t.getState())
  1218. {
  1219. if (oneless(t.getValue(), loval))
  1220. transitions.remove(--idx);
  1221. else
  1222. addTransitionAt(loval, true, idx++);
  1223. }
  1224. else
  1225. inset = true;
  1226. }
  1227. else
  1228. {
  1229. addTransitionAt(loval, true, 0);
  1230. idx = 1;
  1231. }
  1232. }
  1233. while (transitions.isItem(idx))
  1234. {
  1235. ITransition &t = transitions.item(idx);
  1236. int diff = memcmp(t.getValue(), hival, size);
  1237. if (diff <= 0)
  1238. {
  1239. inset = t.getState();
  1240. transitions.remove(idx);
  1241. }
  1242. else
  1243. break;
  1244. }
  1245. if (!inset)
  1246. {
  1247. if (transitions.isItem(idx))
  1248. {
  1249. ITransition &t = transitions.item(idx);
  1250. assertex(t.getState());
  1251. if (oneless(hival, t.getValue()))
  1252. {
  1253. transitions.remove(idx);
  1254. return;
  1255. }
  1256. }
  1257. addTransitionAt(hival, false, idx);
  1258. }
  1259. }
  1260. void CStringSet::killRange(const void *loval, const void *hival)
  1261. {
  1262. if (!loval)
  1263. {
  1264. void *x = alloca(size);
  1265. memset(x, 0, size);
  1266. loval = x;
  1267. }
  1268. if (!hival)
  1269. {
  1270. void *x = alloca(size);
  1271. memset(x, 0xff, size);
  1272. hival = x;
  1273. }
  1274. assertex(memcmp(loval, hival, size) <= 0);
  1275. bool inset = false;
  1276. ForEachItemIn(idx, transitions)
  1277. {
  1278. ITransition &t = transitions.item(idx);
  1279. int diff = memcmp(t.getValue(), loval, size);
  1280. if (diff < 0)
  1281. inset = t.getState();
  1282. else
  1283. break;
  1284. }
  1285. if (inset)
  1286. {
  1287. void *nlo = alloca(size);
  1288. memcpy(nlo, loval, size);
  1289. decrement(nlo);
  1290. addTransitionAt(nlo, false, idx++);
  1291. }
  1292. while (transitions.isItem(idx))
  1293. {
  1294. ITransition &t = transitions.item(idx);
  1295. int diff = memcmp(t.getValue(), hival, size);
  1296. if (diff <= 0)
  1297. {
  1298. inset = t.getState();
  1299. transitions.remove(idx);
  1300. }
  1301. else
  1302. break;
  1303. }
  1304. if (inset)
  1305. {
  1306. void *nhi = alloca(size);
  1307. memcpy(nhi, hival, size);
  1308. increment(nhi);
  1309. addTransitionAt(nhi, true, idx);
  1310. }
  1311. }
  1312. void CStringSet::addAll()
  1313. {
  1314. reset();
  1315. void *val = alloca(size);
  1316. memset(val, 0, size);
  1317. addTransitionAt(val, true, 0);
  1318. memset(val, 0xff, size);
  1319. addTransitionAt(val, false, 1);
  1320. }
  1321. const char *CStringSet::describe(StringBuffer &ret)
  1322. {
  1323. ret.append('[');
  1324. ForEachItemIn(idx, transitions)
  1325. {
  1326. ITransition &t = transitions.item(idx);
  1327. if (t.getState())
  1328. {
  1329. if (idx)
  1330. ret.append(',');
  1331. }
  1332. else
  1333. ret.append("..");
  1334. appendURL(&ret, (char *) t.getValue(), size, true);
  1335. }
  1336. ret.append(']');
  1337. return ret.str();
  1338. }
  1339. bool CStringSet::inRange(const void *val) const
  1340. {
  1341. unsigned nextTransition;
  1342. return inRange(val, nextTransition);
  1343. }
  1344. bool CStringSet::inRange(const void *val, unsigned &nextTransition) const
  1345. {
  1346. int b = transitions.ordinality();
  1347. if (!b)
  1348. {
  1349. nextTransition = (unsigned) -1;
  1350. return false;
  1351. }
  1352. else if (b >= 4)
  1353. {
  1354. // binchop to find last transition >= val...
  1355. unsigned int a = 0;
  1356. int rc;
  1357. while ((int)a<b)
  1358. {
  1359. int i = a+(b+1-a)/2;
  1360. rc = memcmp(val, transitions.item(i-1).getValue(), size);
  1361. if (rc>=0)
  1362. a = i;
  1363. else
  1364. b = i-1;
  1365. }
  1366. if (a>0)
  1367. {
  1368. nextTransition = (a>=transitions.ordinality())? (unsigned) -1: a; // a is first transition that is > val
  1369. a--;
  1370. if (transitions.item(a).getState())
  1371. return true;
  1372. if (memcmp(val, transitions.item(a).getValue(), size)==0)
  1373. {
  1374. nextTransition = a;
  1375. return true;
  1376. }
  1377. return false;
  1378. }
  1379. else
  1380. {
  1381. nextTransition = 0;
  1382. return false;
  1383. }
  1384. }
  1385. else
  1386. {
  1387. bool inset = false;
  1388. ForEachItemIn(idx, transitions)
  1389. {
  1390. ITransition &t = transitions.item(idx);
  1391. int diff = memcmp(t.getValue(), val, size);
  1392. if (t.getState())
  1393. {
  1394. if (diff <= 0)
  1395. inset = true;
  1396. if (diff == 0)
  1397. {
  1398. idx++;
  1399. break;
  1400. }
  1401. else if (diff > 0)
  1402. break;
  1403. }
  1404. else
  1405. {
  1406. if (diff >= 0)
  1407. break;
  1408. if (diff < 0)
  1409. inset = false;
  1410. }
  1411. }
  1412. nextTransition = (idx>=transitions.ordinality())? (unsigned) -1: idx;
  1413. return inset;
  1414. }
  1415. }
  1416. IStringSet *CStringSet::unionOrIntersect(IStringSet *r, bool isUnion)
  1417. {
  1418. bool inA = false;
  1419. bool inB = false;
  1420. bool state = false;
  1421. assertex(r->getSize()==size);
  1422. int idxA = 0;
  1423. int idxB = 0;
  1424. ITransition *tA = queryTransition(idxA);
  1425. ITransition *tB = r->queryTransition(idxB);
  1426. CStringSet *result = createEmptySet();
  1427. for (;;)
  1428. {
  1429. int diff;
  1430. if (tA == NULL)
  1431. {
  1432. if (tB == NULL)
  1433. break;
  1434. else
  1435. diff = 1;
  1436. }
  1437. else if (tB == NULL)
  1438. diff = -1;
  1439. else
  1440. diff = memcmp(tA->getValue(), tB->getValue(), size);
  1441. ITransition *t = NULL;
  1442. if (!diff)
  1443. {
  1444. diff = (int) tB->getState() - (int) tA->getState(); // leading edge sorts before trailing edge for intersect...
  1445. if (isUnion)
  1446. diff = -diff; // trailing edge sorts before leading edge for union...
  1447. }
  1448. if (diff <= 0)
  1449. {
  1450. inA = tA->getState();
  1451. t = tA;
  1452. idxA++;
  1453. tA = queryTransition(idxA);
  1454. }
  1455. if (diff >= 0)
  1456. {
  1457. inB = tB->getState();
  1458. t = tB;
  1459. idxB++;
  1460. tB = r->queryTransition(idxB);
  1461. }
  1462. bool newState;
  1463. if (isUnion)
  1464. newState = inA || inB;
  1465. else
  1466. newState = inA && inB;
  1467. if (newState != state)
  1468. {
  1469. state = newState;
  1470. t->Link();
  1471. result->appendTransition(t);
  1472. }
  1473. }
  1474. return result;
  1475. }
  1476. IStringSet *CStringSet::invertSet()
  1477. {
  1478. CStringSet *result = createEmptySet();
  1479. result->addAll();
  1480. bool inset = false;
  1481. void *loval = alloca(size);
  1482. void *hival = alloca(size);
  1483. memset(loval, 0, size);
  1484. ForEachItemIn(idx, transitions)
  1485. {
  1486. ITransition &t = transitions.item(idx);
  1487. assertex(t.getState() == !inset);
  1488. if (inset)
  1489. {
  1490. memcpy(hival, t.getValue(), size);
  1491. result->killRange(loval, hival);
  1492. }
  1493. else
  1494. memcpy(loval, t.getValue(), size);
  1495. inset = t.getState();
  1496. }
  1497. if (inset)
  1498. {
  1499. memset(hival, 0xff, size);
  1500. result->killRange(loval, hival);
  1501. }
  1502. return result;
  1503. }
  1504. IStringSet *CStringSet::unionSet(IStringSet *other)
  1505. {
  1506. return unionOrIntersect(other, true);
  1507. }
  1508. IStringSet *CStringSet::intersectSet(IStringSet *other)
  1509. {
  1510. return unionOrIntersect(other, false);
  1511. }
  1512. ITransition *CStringSet::queryTransition(unsigned int idx)
  1513. {
  1514. if (transitions.isItem(idx))
  1515. {
  1516. ITransition *t = &transitions.item(idx);
  1517. return t;
  1518. }
  1519. else
  1520. return NULL;
  1521. }
  1522. bool CStringSet::getTransitionValue(void *value, unsigned int idx)
  1523. {
  1524. if (idx == (unsigned) -1 || idx >= transitions.ordinality()) return false;
  1525. ITransition &t = transitions.item(idx);
  1526. memcpy(value, t.getValue(), size);
  1527. return true;
  1528. }
  1529. IStringSet *createStringSet(size32_t size)
  1530. {
  1531. return new CBigUnsignedStringSet(size);
  1532. }
  1533. IStringSet *createStringSet(size32_t size, bool bigEndian, bool isSigned)
  1534. {
  1535. if (bigEndian)
  1536. {
  1537. if (isSigned)
  1538. return new CBigSignedStringSet(size);
  1539. else
  1540. return new CBigUnsignedStringSet(size);
  1541. }
  1542. else
  1543. {
  1544. if (isSigned)
  1545. return new CLittleSignedStringSet(size);
  1546. else
  1547. return new CLittleUnsignedStringSet(size);
  1548. }
  1549. }
  1550. ECLRTL_API IStringSet *deserializeStringSet(MemoryBuffer &mb)
  1551. {
  1552. byte typ;
  1553. mb.read(typ);
  1554. switch((StringSetSerializeType)typ) {
  1555. case SSST_BIGUNSIGNEDSTRINGSET:
  1556. return new CBigUnsignedStringSet(mb);
  1557. case SSST_BIGSIGNEDSTRINGSET:
  1558. return new CBigSignedStringSet(mb);
  1559. case SSST_LITTLEUNSIGNEDSTRINGSET:
  1560. return new CLittleUnsignedStringSet(mb);
  1561. case SSST_LITTLESIGNEDSTRINGSET:
  1562. return new CLittleSignedStringSet(mb);
  1563. }
  1564. return NULL; // up to caller to check
  1565. };
  1566. //---------------------------------------------------------------------------------------------------------------------
  1567. class LegacySetCreator : implements ISetCreator
  1568. {
  1569. public:
  1570. LegacySetCreator(IStringSet & _set, size32_t _minRecordSize, const RtlTypeInfo * _fieldType)
  1571. : set(_set), minRecordSize(_minRecordSize), fieldType(_fieldType) {}
  1572. virtual void addRange(TransitionMask lowerMask, const StringBuffer & lowerString, TransitionMask upperMask, const StringBuffer & upperString) override
  1573. {
  1574. MemoryBufferBuilder lobuilder(lobuffer.clear(), minRecordSize);
  1575. fieldType->buildUtf8(lobuilder, 0, nullptr, lowerString.length(), lowerString.str());
  1576. MemoryBufferBuilder hibuilder(hibuffer.clear(), minRecordSize);
  1577. fieldType->buildUtf8(hibuilder, 0, nullptr, upperString.length(), upperString.str());
  1578. set.addRange(lobuffer.toByteArray(), hibuffer.toByteArray());
  1579. if (!(lowerMask & CMPeq))
  1580. set.killRange(lobuffer.toByteArray(), lobuffer.toByteArray());
  1581. if (!(upperMask & CMPeq))
  1582. set.killRange(hibuffer.toByteArray(), hibuffer.toByteArray());
  1583. }
  1584. protected:
  1585. IStringSet & set;
  1586. const RtlTypeInfo *fieldType;
  1587. size32_t minRecordSize;
  1588. MemoryBuffer lobuffer;
  1589. MemoryBuffer hibuffer;
  1590. };
  1591. void deserializeSet(IStringSet & set, size32_t minRecordSize, const RtlTypeInfo * fieldType, const char * filter)
  1592. {
  1593. LegacySetCreator creator(set, minRecordSize, fieldType);
  1594. deserializeSet(creator, filter);
  1595. }
  1596. #ifdef _USE_CPPUNIT
  1597. #include <cppunit/extensions/HelperMacros.h>
  1598. /*
  1599. class IStdException : extends std::exception
  1600. {
  1601. Owned<IException> jException;
  1602. public:
  1603. IStdException(IException *E) : jException(E) {};
  1604. };
  1605. */
  1606. class SegmentMonitorTest : public CppUnit::TestFixture
  1607. {
  1608. CPPUNIT_TEST_SUITE( SegmentMonitorTest );
  1609. CPPUNIT_TEST(testOptional);
  1610. CPPUNIT_TEST_SUITE_END();
  1611. protected:
  1612. void testOptional()
  1613. {
  1614. Owned<IKeySegmentMonitor> wild0_20 = createWildKeySegmentMonitor(0, 0, 20);
  1615. Owned<IKeySegmentMonitor> wild10_10 = createWildKeySegmentMonitor(1, 10,10);
  1616. Owned<IStringSet> abcdef = createStringSet(10);
  1617. abcdef->addRange("ABCDEFGHIJ", "ABCDEFGHIJ");
  1618. Owned<IKeySegmentMonitor> opt0_20 = createSingleKeySegmentMonitor(true, 0, 0,20, "abcdefghijklmnopqrst");
  1619. Owned<IKeySegmentMonitor> opt20_10 = createKeySegmentMonitor(true, LINK(abcdef), 1, 20, 10);
  1620. Owned<IKeySegmentMonitor> opt30_10 = createSingleKeySegmentMonitor(true, 2, 30, 10, "KLMNOPQRST");
  1621. Owned<IKeySegmentMonitor> nonOpt0_10 = createSingleKeySegmentMonitor(false, 0, 0,10, "abcdefghij");
  1622. Owned<IKeySegmentMonitor> nonOpt0_20 = createSingleKeySegmentMonitor(false, 0, 0,20, "abcdefghijklmnopqrst");
  1623. Owned<IKeySegmentMonitor> nonOpt20_10 = createKeySegmentMonitor(false, LINK(abcdef), 1, 20, 10);
  1624. Owned<IKeySegmentMonitor> nonOpt30_10 = createSingleKeySegmentMonitor(false, 2, 30, 10, "KLMNOPQRST");
  1625. CPPUNIT_ASSERT(wild0_20->isOptional());
  1626. CPPUNIT_ASSERT(opt20_10->isOptional());
  1627. CPPUNIT_ASSERT(opt30_10->isOptional());
  1628. CPPUNIT_ASSERT(!nonOpt0_10->isOptional());
  1629. CPPUNIT_ASSERT(!nonOpt0_20->isOptional());
  1630. CPPUNIT_ASSERT(!nonOpt20_10->isOptional());
  1631. CPPUNIT_ASSERT(!nonOpt30_10->isOptional());
  1632. #if 0
  1633. IKeySegmentMonitorArray segments;
  1634. segments.append(*LINK(wild0_20));
  1635. segments.append(*LINK(opt20_10));
  1636. CPPUNIT_ASSERT(segments.ordinality() == 1);
  1637. CPPUNIT_ASSERT(segments.item(0).isWild());
  1638. CPPUNIT_ASSERT(segments.item(0).getOffset() == 0);
  1639. CPPUNIT_ASSERT(segments.item(0).getSize() == 30);
  1640. segments.kill();
  1641. segments.append(*LINK(wild0_20));
  1642. segments.append(*LINK(opt20_10));
  1643. segments.append(*LINK(nonOpt30_10));
  1644. CPPUNIT_ASSERT(segments.ordinality() == 2);
  1645. CPPUNIT_ASSERT(segments.item(0).isWild());
  1646. CPPUNIT_ASSERT(segments.item(0).getOffset() == 0);
  1647. CPPUNIT_ASSERT(segments.item(0).getSize() == 30);
  1648. CPPUNIT_ASSERT(!segments.item(1).isWild());
  1649. CPPUNIT_ASSERT(segments.item(1).getOffset() == 30);
  1650. CPPUNIT_ASSERT(segments.item(1).getSize() == 10);
  1651. segments.kill();
  1652. segments.append(*LINK(nonOpt0_20));
  1653. segments.append(*LINK(opt20_10));
  1654. segments.append(*LINK(nonOpt30_10));
  1655. CPPUNIT_ASSERT(segments.ordinality() == 3);
  1656. CPPUNIT_ASSERT(!segments.item(1).isWild());
  1657. CPPUNIT_ASSERT(segments.item(1).getOffset() == 20);
  1658. CPPUNIT_ASSERT(segments.item(1).getSize() == 10);
  1659. segments.kill();
  1660. segments.append(*LINK(nonOpt0_10));
  1661. segments.append(*LINK(wild10_10));
  1662. segments.append(*LINK(opt20_10));
  1663. segments.append(*LINK(nonOpt30_10));
  1664. CPPUNIT_ASSERT(segments.ordinality() == 3);
  1665. CPPUNIT_ASSERT(!segments.item(0).isWild());
  1666. CPPUNIT_ASSERT(segments.item(1).isWild());
  1667. CPPUNIT_ASSERT(segments.item(1).getOffset() == 10);
  1668. CPPUNIT_ASSERT(segments.item(1).getSize() == 20);
  1669. segments.kill();
  1670. segments.append(*LINK(opt0_20));
  1671. segments.append(*LINK(opt20_10));
  1672. segments.append(*LINK(nonOpt30_10));
  1673. CPPUNIT_ASSERT(segments.ordinality() == 3);
  1674. CPPUNIT_ASSERT(!segments.item(0).isWild());
  1675. CPPUNIT_ASSERT(!segments.item(1).isWild());
  1676. CPPUNIT_ASSERT(segments.item(1).getOffset() == 20);
  1677. CPPUNIT_ASSERT(segments.item(1).getSize() == 10);
  1678. #endif
  1679. }
  1680. };
  1681. CPPUNIT_TEST_SUITE_REGISTRATION( SegmentMonitorTest );
  1682. CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( SegmentMonitorTest, "SegmentMonitorTest" );
  1683. #endif