rtlkey.cpp 73 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470
  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. #define KSM_SET 0x01
  21. #define KSM_WILD 0x02
  22. #define KSM_LITTLE_ENDIAN 0x04
  23. #define KSM_SIGNED 0x08
  24. #define KSM_VAROFFSET 0x10
  25. #define KSM_TRANSLATED 0x20
  26. class CKeySegmentMonitor : implements IKeySegmentMonitor, public CInterface
  27. {
  28. protected:
  29. size32_t size;
  30. size32_t offset;
  31. unsigned hash;
  32. public:
  33. IMPLEMENT_IINTERFACE;
  34. CKeySegmentMonitor(unsigned _offset, unsigned _size);
  35. CKeySegmentMonitor(MemoryBuffer &mb)
  36. {
  37. mb.read(size).read(offset).read(hash);
  38. }
  39. virtual bool matchesBuffer(const void * rawRow) const = 0;
  40. virtual bool matches(const RtlRow * rawRow) const
  41. {
  42. return matchesBuffer(rawRow->queryRow());
  43. }
  44. virtual bool increment(void *keyval) const;
  45. virtual unsigned getOffset() const { return offset; }
  46. virtual unsigned getSize() const { return size; }
  47. virtual IKeySegmentMonitor * split(unsigned splitSize) { throwUnexpected(); } // not required in most cases
  48. virtual bool isWild() const { return false; }
  49. virtual bool isEmpty() const { return false; }
  50. virtual void *queryValue() const { return NULL; }
  51. virtual bool isSigned() const { return false; }
  52. virtual bool isLittleEndian() const { return false; }
  53. virtual unsigned numFieldsRequired() const { return 0; } // Fixed offset segmonitors don't care about field numbers
  54. virtual int docompare(const void * l, const void * r) const
  55. {
  56. char *lptr = ((char *) l) + offset;
  57. char *rptr = ((char *) r) + offset;
  58. return memcmp(lptr, rptr, size);
  59. }
  60. virtual int docompareraw(const void *l, const void *r) const
  61. {
  62. char *lptr = ((char *) l) + offset;
  63. char *rptr = ((char *) r) + offset;
  64. return memcmp(lptr, rptr, size);
  65. }
  66. virtual int docompareraw(const RtlRow *l, const RtlRow *r) const
  67. {
  68. return docompareraw(l->queryRow(), r->queryRow());
  69. }
  70. virtual bool equivalentTo(const IKeySegmentMonitor &other) const
  71. {
  72. return offset==other.getOffset()
  73. && size==other.getSize()
  74. && isSigned()==other.isSigned()
  75. && isLittleEndian()==other.isLittleEndian();
  76. }
  77. virtual unsigned queryHashCode() const
  78. {
  79. return hash;
  80. }
  81. virtual bool setOffset(unsigned _offset)
  82. {
  83. offset = _offset;
  84. return true;
  85. }
  86. virtual void setHigh(void *keyval) const;
  87. virtual bool isSimple() const
  88. {
  89. return false; // err on the side of caution
  90. }
  91. virtual void copy(void * l, const void * r) const
  92. {
  93. char *lptr = ((char *) l) + offset;
  94. char *rptr = ((char *) r) + offset;
  95. memcpy(lptr, rptr, size);
  96. }
  97. virtual MemoryBuffer &serialize(MemoryBuffer &mb) const
  98. {
  99. KeySegmentMonitorSerializeType typ = serializeType();
  100. assertex(typ!=KSMST_none);
  101. return mb.append((byte)typ).append(size).append(offset).append(hash);
  102. }
  103. virtual KeySegmentMonitorSerializeType serializeType() const = 0;
  104. };
  105. class CDummyKeySegmentMonitor : public CKeySegmentMonitor
  106. {
  107. bool lisSigned;
  108. bool lisLittleEndian;
  109. public:
  110. CDummyKeySegmentMonitor(unsigned _offset, unsigned _size, bool _isSigned, bool _isLittleEndian)
  111. : CKeySegmentMonitor(_offset, _size), lisSigned(_isSigned), lisLittleEndian(_isLittleEndian)
  112. {
  113. hash = FNV_32_HASHONE_VALUE(hash, (byte) lisSigned);
  114. hash = FNV_32_HASHONE_VALUE(hash, (byte) lisLittleEndian);
  115. }
  116. CDummyKeySegmentMonitor(MemoryBuffer &mb)
  117. : CKeySegmentMonitor(mb)
  118. {
  119. mb.read(lisSigned).read(lisLittleEndian);
  120. }
  121. virtual IKeySegmentMonitor *clone() const
  122. {
  123. return new CDummyKeySegmentMonitor(offset, size, lisSigned, lisLittleEndian);
  124. }
  125. virtual void setLow(void *keyval) const { throwUnexpected(); }
  126. virtual void endRange(void *keyval) const { throwUnexpected(); }
  127. virtual bool matchesBuffer(const void *keyval) const { throwUnexpected(); }
  128. virtual IKeySegmentMonitor *merge(IKeySegmentMonitor *with) const { throwUnexpected(); }
  129. virtual IKeySegmentMonitor *combine(const IKeySegmentMonitor *with) const { throwUnexpected(); }
  130. virtual unsigned getFlags() const
  131. {
  132. unsigned ret = 0;
  133. if (lisLittleEndian)
  134. ret |= KSM_LITTLE_ENDIAN;
  135. if (lisSigned)
  136. ret |= KSM_SIGNED;
  137. return ret;
  138. }
  139. virtual bool isSigned() const { return lisSigned; }
  140. virtual bool isLittleEndian() const { return lisLittleEndian; }
  141. virtual bool isWellKeyed() const { throwUnexpected(); }
  142. virtual bool isOptional() const { return true; }
  143. virtual bool isSimple() const { return true; }
  144. virtual MemoryBuffer &serialize(MemoryBuffer &mb) const
  145. {
  146. return CKeySegmentMonitor::serialize(mb).append(lisSigned).append(lisLittleEndian);
  147. }
  148. virtual KeySegmentMonitorSerializeType serializeType() const { return KSMST_DUMMYKEYSEGMENTMONITOR; }
  149. };
  150. class CWildKeySegmentMonitor : public CKeySegmentMonitor
  151. {
  152. public:
  153. CWildKeySegmentMonitor(unsigned _offset, unsigned _size);
  154. CWildKeySegmentMonitor(MemoryBuffer &mb)
  155. : CKeySegmentMonitor(mb)
  156. {
  157. }
  158. virtual IKeySegmentMonitor * split(unsigned splitSize);
  159. virtual bool matchesBuffer(const void *keyval) const;
  160. virtual int docompare(const void *,const void *) const;
  161. virtual int docompareraw(const void *,const void *) const;
  162. virtual void setLow(void *keyval) const;
  163. virtual void endRange(void *keyval) const;
  164. virtual IKeySegmentMonitor *merge(IKeySegmentMonitor *with) const;
  165. virtual bool isWild() const { return true; }
  166. virtual bool isWellKeyed() const { return false; }
  167. virtual unsigned getFlags() const { return KSM_WILD; }
  168. virtual bool isOptional() const { return true; }
  169. virtual IKeySegmentMonitor *clone() const;
  170. virtual IKeySegmentMonitor *combine(const IKeySegmentMonitor *with) const { throwUnexpected(); }
  171. virtual KeySegmentMonitorSerializeType serializeType() const { return KSMST_WILDKEYSEGMENTMONITOR; }
  172. };
  173. class CSetKeySegmentMonitor : public CKeySegmentMonitor
  174. {
  175. private:
  176. Owned<IStringSet> set;
  177. mutable CriticalSection cacheCrit;
  178. mutable bool lastCompareResult;
  179. mutable bool hasCompareResult;
  180. mutable char *lastCompareValue;
  181. bool optional;
  182. public:
  183. CSetKeySegmentMonitor(bool _optional, IStringSet *set, unsigned _offset, unsigned _size);
  184. CSetKeySegmentMonitor(MemoryBuffer &mb)
  185. : CKeySegmentMonitor(mb)
  186. {
  187. lastCompareResult = false;
  188. hasCompareResult = false;
  189. set.setown(deserializeStringSet(mb));
  190. mb.read(optional);
  191. lastCompareValue = new char[size];
  192. }
  193. ~CSetKeySegmentMonitor();
  194. // IKeySegmentMonitor
  195. virtual bool increment(void *keyval) const;
  196. virtual void setLow(void *keyval) const;
  197. virtual bool matchesBuffer(const void *keyval) const;
  198. virtual void endRange(void *keyval) const;
  199. virtual IKeySegmentMonitor *merge(IKeySegmentMonitor *next) const { return NULL; }
  200. virtual IKeySegmentMonitor *combine(const IKeySegmentMonitor *with) const;
  201. virtual unsigned getFlags() const { return KSM_SET; }
  202. virtual bool isEmpty() const { return set->isEmptySet(); }
  203. virtual bool isWellKeyed() const;
  204. virtual bool isOptional() const { return optional; }
  205. virtual bool isSimple() const { return true; }
  206. virtual bool isSigned() const { return set->isSigned(); }
  207. virtual bool isLittleEndian() const { return !set->isBigEndian(); }
  208. virtual IKeySegmentMonitor *clone() const;
  209. virtual int docompare(const void * l, const void * r) const
  210. {
  211. char *lptr = ((char *) l) + offset;
  212. char *rptr = ((char *) r) + offset;
  213. return set->memcmp(lptr, rptr, size);
  214. }
  215. virtual int docompareraw(const void *l, const void *r) const
  216. {
  217. char *lptr = ((char *) l) + offset;
  218. char *rptr = ((char *) r) + offset;
  219. return set->memcmp(lptr, rptr, size);
  220. }
  221. virtual MemoryBuffer &serialize(MemoryBuffer &mb) const
  222. {
  223. CKeySegmentMonitor::serialize(mb);
  224. set->serialize(mb);
  225. return mb.append(optional);
  226. }
  227. virtual KeySegmentMonitorSerializeType serializeType() const { return KSMST_SETKEYSEGMENTMONITOR; }
  228. };
  229. CKeySegmentMonitor::CKeySegmentMonitor(unsigned _offset, unsigned _size)
  230. {
  231. size = _size;
  232. offset = _offset;
  233. hash = 123456;
  234. hash = hashc((unsigned char *) &offset, sizeof(offset), hash);
  235. hash = hashc((unsigned char *) &size, sizeof(size), hash);
  236. }
  237. bool CKeySegmentMonitor::increment(void *bufptr) const
  238. {
  239. char *ptr = ((char *) bufptr) + offset;
  240. int i = size;
  241. while (i--)
  242. {
  243. ptr[i]++;
  244. if (ptr[i]!=0)
  245. return true;
  246. }
  247. return false;
  248. }
  249. void CKeySegmentMonitor::setHigh(void *bufptr) const
  250. {
  251. // NOTE - effectively whenever this is called we are treating the segmonitor as if it was a wild one
  252. char *ptr = ((char *) bufptr) + offset;
  253. memset(ptr, 0xff, size);
  254. }
  255. CWildKeySegmentMonitor::CWildKeySegmentMonitor(unsigned _offset, unsigned _size)
  256. : CKeySegmentMonitor(_offset, _size)
  257. {
  258. }
  259. IKeySegmentMonitor * CWildKeySegmentMonitor::split(unsigned splitSize)
  260. {
  261. // Modifies current as well as creating a new one - use with care!
  262. assert(!IsShared());
  263. if(splitSize >= size)
  264. return NULL;
  265. unsigned splitOffset = offset;
  266. offset += splitSize;
  267. size -= splitSize;
  268. return new CWildKeySegmentMonitor(splitOffset, splitSize);
  269. }
  270. IKeySegmentMonitor *CWildKeySegmentMonitor::clone() const
  271. {
  272. return new CWildKeySegmentMonitor(offset, size);
  273. }
  274. bool CWildKeySegmentMonitor::matchesBuffer(const void *keyval) const
  275. {
  276. return true;
  277. }
  278. int CWildKeySegmentMonitor::docompare(const void *l, const void *r) const
  279. {
  280. return 0;
  281. }
  282. int CWildKeySegmentMonitor::docompareraw(const void *l, const void *r) const
  283. {
  284. return 0;
  285. }
  286. void CWildKeySegmentMonitor::setLow(void *bufptr) const
  287. {
  288. char *ptr = ((char *) bufptr) + offset;
  289. memset(ptr, 0, size);
  290. }
  291. void CWildKeySegmentMonitor::endRange(void *bufptr) const
  292. {
  293. char *ptr = ((char *) bufptr) + offset;
  294. memset(ptr, 0xff, size);
  295. }
  296. IKeySegmentMonitor *CWildKeySegmentMonitor::merge(IKeySegmentMonitor *next) const
  297. {
  298. if (next->isWild())
  299. {
  300. assertex(offset + size == next->getOffset());
  301. return new CWildKeySegmentMonitor(offset, next->getSize()+size);
  302. }
  303. else
  304. return NULL;
  305. }
  306. CSetKeySegmentMonitor::CSetKeySegmentMonitor(bool _optional, IStringSet *_set, unsigned _offset, unsigned _size)
  307. : set(_set), CKeySegmentMonitor(_offset, _size)
  308. {
  309. lastCompareValue = new char[_size];
  310. hasCompareResult = false;
  311. lastCompareResult = false;
  312. optional = _optional;
  313. hash = FNV_32_HASHONE_VALUE(hash, (byte) set->isSigned());
  314. hash = FNV_32_HASHONE_VALUE(hash, (byte) !set->isBigEndian());
  315. }
  316. CSetKeySegmentMonitor::~CSetKeySegmentMonitor()
  317. {
  318. delete [] lastCompareValue;
  319. }
  320. IKeySegmentMonitor *CSetKeySegmentMonitor::clone() const
  321. {
  322. return new CSetKeySegmentMonitor(optional, set.getLink(), offset, size);
  323. }
  324. IKeySegmentMonitor *CSetKeySegmentMonitor::combine(const IKeySegmentMonitor *with) const
  325. {
  326. assertex(equivalentTo(*with)); // note - badly named - does not mean the condition is equivalent, only the field being compared
  327. const CSetKeySegmentMonitor *withSet = QUERYINTERFACE(with, const CSetKeySegmentMonitor);
  328. if (!withSet)
  329. return with->combine(this); // let the simpler segmonitor do the work
  330. Owned<IStringSet> resultSet = set->intersectSet(withSet->set);
  331. return createKeySegmentMonitor(optional, resultSet.getClear(), offset, size);
  332. }
  333. bool CSetKeySegmentMonitor::increment(void *bufptr) const
  334. {
  335. char *ptr = ((char *) bufptr) + offset;
  336. bool ok = set->increment(ptr);
  337. if (ok)
  338. {
  339. unsigned nextTransition;
  340. bool res = set->inRange(ptr, nextTransition);
  341. if (!res)
  342. {
  343. if (-1 == nextTransition) return false;
  344. set->getTransitionValue(ptr, nextTransition);
  345. }
  346. }
  347. return ok;
  348. }
  349. void CSetKeySegmentMonitor::setLow(void *bufptr) const
  350. {
  351. char *ptr = ((char *) bufptr) + offset;
  352. if (set->transitionCount())
  353. set->getTransitionValue(ptr, 0);
  354. else
  355. memset(ptr, 0, size); // MORE - should really trap earlier
  356. }
  357. void CSetKeySegmentMonitor::endRange(void *bufptr) const
  358. {
  359. char *ptr = ((char *) bufptr) + offset;
  360. unsigned nextTransition;
  361. bool res = set->inRange(ptr, nextTransition);
  362. assertex(res);
  363. verifyex(set->getTransitionValue(ptr, nextTransition));
  364. }
  365. bool CSetKeySegmentMonitor::matchesBuffer(const void *bufptr) const
  366. {
  367. // MORE - should investigate sometime how much benefit we get from this caching...
  368. char *ptr = ((char *) bufptr) + offset;
  369. CriticalBlock b(cacheCrit);
  370. if (hasCompareResult && 0 == memcmp(lastCompareValue, ptr, size))
  371. return lastCompareResult;
  372. lastCompareResult = set->inRange(ptr);
  373. memcpy(lastCompareValue, ptr, size);
  374. hasCompareResult = true;
  375. return lastCompareResult;
  376. }
  377. bool CSetKeySegmentMonitor::isWellKeyed() const
  378. {
  379. // This check determines whether or not keyed, opt considers this field to be keyed.
  380. // The goal is to allow sets but not ranges, slightly complicated by the fact that adjacent values in a set turn into ranges.
  381. return set->numValues() < 50;
  382. }
  383. class CSingleKeySegmentMonitorBase : public CKeySegmentMonitor
  384. {
  385. protected:
  386. void *val;
  387. bool optional;
  388. public:
  389. CSingleKeySegmentMonitorBase(bool _optional, const void *_val, unsigned _offset, unsigned _size)
  390. : CKeySegmentMonitor(_offset, _size)
  391. {
  392. if (_val)
  393. {
  394. val = malloc(_size);
  395. memcpy(val, _val, _size);
  396. }
  397. else
  398. val = NULL;
  399. optional = _optional;
  400. }
  401. CSingleKeySegmentMonitorBase(bool _optional, unsigned _offset, const void *_val1, unsigned _val1size, const void *_val2, unsigned _val2size)
  402. : CKeySegmentMonitor(_offset, _val1size+_val2size)
  403. {
  404. val = malloc(size);
  405. memcpy(val, _val1, _val1size);
  406. memcpy(((char *) val)+_val1size, _val2, _val2size);
  407. optional = _optional;
  408. }
  409. CSingleKeySegmentMonitorBase(bool _optional, unsigned _offset, unsigned _size)
  410. : CKeySegmentMonitor(_offset, _size)
  411. {
  412. val = NULL;
  413. optional = _optional;
  414. }
  415. CSingleKeySegmentMonitorBase(MemoryBuffer &mb)
  416. : CKeySegmentMonitor(mb)
  417. {
  418. bool hasval;
  419. mb.read(hasval);
  420. if (hasval) {
  421. val = malloc(size);
  422. memcpy(val,mb.readDirect(size),size);
  423. }
  424. else
  425. val = NULL;
  426. mb.read(optional);
  427. }
  428. ~CSingleKeySegmentMonitorBase()
  429. {
  430. free(val);
  431. }
  432. // IKeySegmentMonitor
  433. virtual bool increment(void *bufptr) const
  434. {
  435. // Set to next permitted value above current
  436. if (docompare(bufptr, ((char *) val)-offset) < 0)
  437. {
  438. char *ptr = ((char *) bufptr) + offset;
  439. memcpy(ptr, val, size);
  440. return true;
  441. }
  442. else
  443. return false;
  444. }
  445. virtual void setLow(void *bufptr) const
  446. {
  447. // Set to lowest permitted value
  448. char *ptr = ((char *) bufptr) + offset;
  449. memcpy(ptr, val, size);
  450. }
  451. virtual bool matchesBuffer(const void *bufptr) const
  452. {
  453. // Is current a permitted value?
  454. char *ptr = ((char *) bufptr) + offset;
  455. return memcmp(ptr, val, size) == 0;
  456. }
  457. virtual void endRange(void *bufptr) const
  458. {
  459. // Set to last permitted value in the range that includes current (which is asserted to be valid)
  460. #ifdef DEBUG
  461. assertex(matchesBuffer(bufptr));
  462. #endif
  463. }
  464. virtual void *queryValue() const
  465. {
  466. return val;
  467. }
  468. virtual bool isWellKeyed() const { return true; }
  469. virtual bool isOptional() const { return optional; }
  470. virtual IKeySegmentMonitor *merge(IKeySegmentMonitor *next) const { return NULL; }
  471. virtual IKeySegmentMonitor *combine(const IKeySegmentMonitor *with) const { throwUnexpected(); };
  472. virtual bool isSimple() const { return true; }
  473. virtual MemoryBuffer &serialize(MemoryBuffer &mb) const override
  474. {
  475. CKeySegmentMonitor::serialize(mb);
  476. if (val)
  477. mb.append((bool)true).append(size,val);
  478. else
  479. mb.append((bool)false);
  480. return mb.append(optional);
  481. }
  482. };
  483. class CSingleKeySegmentMonitor : public CSingleKeySegmentMonitorBase
  484. {
  485. public:
  486. CSingleKeySegmentMonitor(bool _optional, const void *_val, unsigned _offset, unsigned _size)
  487. : CSingleKeySegmentMonitorBase(_optional, _val, _offset, _size)
  488. {
  489. hash = FNV_32_HASHONE_VALUE(hash, (byte) 0);
  490. hash = FNV_32_HASHONE_VALUE(hash, (byte) 0);
  491. }
  492. CSingleKeySegmentMonitor(bool _optional, unsigned _offset, const void *_val1, unsigned _val1size, const void *_val2, unsigned _val2size)
  493. : CSingleKeySegmentMonitorBase(_optional, _offset, _val1, _val1size, _val2, _val2size)
  494. {
  495. hash = FNV_32_HASHONE_VALUE(hash, (byte) 0);
  496. hash = FNV_32_HASHONE_VALUE(hash, (byte) 0);
  497. }
  498. CSingleKeySegmentMonitor(MemoryBuffer &mb)
  499. : CSingleKeySegmentMonitorBase(mb)
  500. {
  501. }
  502. virtual IKeySegmentMonitor *clone() const
  503. {
  504. return new CSingleKeySegmentMonitor(optional, val, offset, size);
  505. }
  506. virtual unsigned getFlags() const
  507. {
  508. return 0;
  509. }
  510. virtual IKeySegmentMonitor *merge(IKeySegmentMonitor *_next) const
  511. {
  512. CSingleKeySegmentMonitor *next = QUERYINTERFACE(_next, CSingleKeySegmentMonitor);
  513. if(next)
  514. {
  515. void *nextval = next->queryValue();
  516. assertex(nextval != NULL && offset + size == next->getOffset());
  517. return new CSingleKeySegmentMonitor(optional, offset, val, size, nextval, next->getSize());
  518. }
  519. else
  520. return NULL;
  521. }
  522. virtual IKeySegmentMonitor *combine(const IKeySegmentMonitor *with) const
  523. {
  524. assertex(equivalentTo(*with)); // note - badly named - does not mean the condition is equivalent, only the field being compared
  525. // result is either clone of myself, or emptySet
  526. if (with->matchesBuffer(val)) // MORE - this looks wrong! Only works with offset=0 ??
  527. return clone();
  528. else
  529. return createEmptyKeySegmentMonitor(optional, offset, size);
  530. }
  531. virtual IKeySegmentMonitor * split(unsigned splitSize)
  532. {
  533. if(splitSize >= size)
  534. return NULL;
  535. unsigned splitOffset = offset;
  536. offset += splitSize;
  537. size -= splitSize;
  538. Owned<IKeySegmentMonitor> ret = new CSingleKeySegmentMonitor(optional, val, splitOffset, splitSize);
  539. void * newval = malloc(size);
  540. memcpy(newval, static_cast<byte *>(val)+splitSize, size);
  541. free(val);
  542. val = newval;
  543. return ret.getClear();
  544. }
  545. virtual bool isSigned() const { return false; }
  546. virtual bool isLittleEndian() const { return false; }
  547. virtual KeySegmentMonitorSerializeType serializeType() const { return KSMST_SINGLEKEYSEGMENTMONITOR; }
  548. };
  549. class CSingleBigSignedKeySegmentMonitor : public CSingleKeySegmentMonitorBase
  550. {
  551. public:
  552. CSingleBigSignedKeySegmentMonitor(bool _optional, const void *_val, unsigned _offset, unsigned _size)
  553. : CSingleKeySegmentMonitorBase(_optional, _val, _offset, _size)
  554. {
  555. hash = FNV_32_HASHONE_VALUE(hash, (byte) 1);
  556. hash = FNV_32_HASHONE_VALUE(hash, (byte) 0);
  557. }
  558. CSingleBigSignedKeySegmentMonitor(MemoryBuffer &mb)
  559. : CSingleKeySegmentMonitorBase(mb)
  560. {
  561. }
  562. virtual IKeySegmentMonitor *clone() const
  563. {
  564. return new CSingleBigSignedKeySegmentMonitor(optional, val, offset, size);
  565. }
  566. virtual unsigned getFlags() const
  567. {
  568. return KSM_SIGNED;
  569. }
  570. virtual int docompare(const void *l, const void *r) const
  571. {
  572. return memcmpbigsigned(((char *) l) + offset, ((char *) r) + offset, size);
  573. }
  574. virtual int docompareraw(const void *l, const void *r) const
  575. {
  576. return memcmpbigsigned(((char *) l) + offset, ((char *) r) + offset, size);
  577. }
  578. virtual bool isSigned() const { return true; }
  579. virtual bool isLittleEndian() const { return false; }
  580. virtual KeySegmentMonitorSerializeType serializeType() const { return KSMST_SINGLEBIGSIGNEDKEYSEGMENTMONITOR; }
  581. };
  582. class CSingleLittleSignedKeySegmentMonitor : public CSingleKeySegmentMonitorBase
  583. {
  584. public:
  585. CSingleLittleSignedKeySegmentMonitor(bool _optional, const void *_val, unsigned _offset, unsigned _size)
  586. : CSingleKeySegmentMonitorBase(_optional, _val, _offset, _size)
  587. {
  588. hash = FNV_32_HASHONE_VALUE(hash, (byte) 1);
  589. hash = FNV_32_HASHONE_VALUE(hash, (byte) 1);
  590. }
  591. CSingleLittleSignedKeySegmentMonitor(MemoryBuffer &mb)
  592. : CSingleKeySegmentMonitorBase(mb)
  593. {
  594. }
  595. virtual IKeySegmentMonitor *clone() const
  596. {
  597. return new CSingleLittleSignedKeySegmentMonitor(optional, val, offset, size);
  598. }
  599. virtual unsigned getFlags() const
  600. {
  601. return KSM_LITTLE_ENDIAN | KSM_SIGNED;
  602. }
  603. virtual int docompare(const void *l, const void *r) const
  604. {
  605. return memcmplittlesigned(((char *) l) + offset, ((char *) r) + offset, size);
  606. }
  607. virtual int docompareraw(const void *l, const void *r) const
  608. {
  609. return memcmplittlesigned(((char *) l) + offset, ((char *) r) + offset, size);
  610. }
  611. virtual bool isSigned() const { return true; }
  612. virtual bool isLittleEndian() const { return true; }
  613. virtual KeySegmentMonitorSerializeType serializeType() const { return KSMST_SINGLELITTLESIGNEDKEYSEGMENTMONITOR; }
  614. };
  615. class CSingleLittleKeySegmentMonitor : public CSingleKeySegmentMonitorBase
  616. {
  617. public:
  618. CSingleLittleKeySegmentMonitor(bool _optional, const void *_val, unsigned _offset, unsigned _size)
  619. : CSingleKeySegmentMonitorBase(_optional, _val, _offset, _size)
  620. {
  621. hash = FNV_32_HASHONE_VALUE(hash, (byte) 0);
  622. hash = FNV_32_HASHONE_VALUE(hash, (byte) 1);
  623. }
  624. CSingleLittleKeySegmentMonitor(MemoryBuffer &mb)
  625. : CSingleKeySegmentMonitorBase(mb)
  626. {
  627. }
  628. virtual IKeySegmentMonitor *clone() const
  629. {
  630. return new CSingleLittleKeySegmentMonitor(optional, val, offset, size);
  631. }
  632. virtual unsigned getFlags() const
  633. {
  634. return KSM_LITTLE_ENDIAN;
  635. }
  636. virtual int docompare(const void *l, const void *r) const
  637. {
  638. return memcmplittleunsigned(((char *) l) + offset, ((char *) r) + offset, size);
  639. }
  640. virtual int docompareraw(const void *l, const void *r) const
  641. {
  642. return memcmplittleunsigned(((char *) l) + offset, ((char *) r) + offset, size);
  643. }
  644. virtual bool isSigned() const { return false; }
  645. virtual bool isLittleEndian() const { return true; }
  646. virtual KeySegmentMonitorSerializeType serializeType() const { return KSMST_CSINGLELITTLEKEYSEGMENTMONITOR; }
  647. };
  648. class CIndirectKeySegmentMonitor : implements IKeySegmentMonitor, public CInterface
  649. {
  650. protected:
  651. unsigned hash;
  652. public:
  653. CIndirectKeySegmentMonitor(IKeySegmentMonitor * _base, unsigned _offset)
  654. {
  655. base.setown(_base);
  656. offset = _offset;
  657. hash = hashc((unsigned char *) &offset, sizeof(offset), base->queryHashCode());
  658. }
  659. CIndirectKeySegmentMonitor(MemoryBuffer &mb)
  660. {
  661. mb.read(offset).read(hash);
  662. base.setown(deserializeKeySegmentMonitor(mb));
  663. }
  664. IMPLEMENT_IINTERFACE
  665. virtual bool increment(void *keyval) const
  666. {
  667. return base->increment((byte *)keyval + offset);
  668. }
  669. virtual void setLow(void *keyval) const
  670. {
  671. base->setLow((byte *)keyval + offset);
  672. }
  673. virtual void setHigh(void *keyval) const
  674. {
  675. base->setHigh((byte *)keyval + offset);
  676. }
  677. virtual void endRange(void *keyval) const
  678. {
  679. base->endRange((byte *)keyval + offset);
  680. }
  681. virtual IKeySegmentMonitor *merge(IKeySegmentMonitor *with) const { return NULL; } // MORE?
  682. virtual IKeySegmentMonitor *combine(const IKeySegmentMonitor *with) const { throwUnexpected(); }
  683. virtual IKeySegmentMonitor * split(unsigned splitSize) { return NULL; } // not required in most cases
  684. virtual bool isWild() const { return base->isWild(); }
  685. virtual unsigned getOffset() const { return offset; }
  686. virtual unsigned getSize() const { return base->getSize(); }
  687. virtual void *queryValue() const { return NULL; }
  688. virtual bool isEmpty() const { return base->isEmpty(); }
  689. virtual bool equivalentTo(const IKeySegmentMonitor &other) const { return false; } // MORE?
  690. virtual bool isSigned() const { return base->isSigned(); }
  691. virtual bool isLittleEndian() const { return base->isLittleEndian(); }
  692. virtual bool isWellKeyed() const { return base->isWellKeyed(); }
  693. virtual bool isOptional() const { return base->isOptional(); }
  694. virtual unsigned numFieldsRequired() const { return base->numFieldsRequired(); }
  695. virtual unsigned queryHashCode() const
  696. {
  697. return hash;
  698. }
  699. virtual bool setOffset(unsigned _offset) { return false; }
  700. virtual MemoryBuffer &serialize(MemoryBuffer &mb) const
  701. {
  702. KeySegmentMonitorSerializeType typ = serializeType();
  703. assertex(typ!=KSMST_none);
  704. mb.append((byte)typ).append(offset).append(hash);
  705. return base->serialize(mb);
  706. }
  707. virtual KeySegmentMonitorSerializeType serializeType() const = 0;
  708. protected:
  709. Owned<IKeySegmentMonitor> base;
  710. unsigned offset;
  711. };
  712. // The base monitor provided to this segment monitor is constructed with offsets of 0
  713. class CNewVarOffsetKeySegmentMonitor : public CIndirectKeySegmentMonitor
  714. {
  715. public:
  716. CNewVarOffsetKeySegmentMonitor(IKeySegmentMonitor * _base, unsigned _offset, unsigned _fieldIdx)
  717. : CIndirectKeySegmentMonitor(_base, 0), fieldIdx(_fieldIdx)
  718. {
  719. assert(_offset = 0); // We no longer use partial size for offset
  720. }
  721. CNewVarOffsetKeySegmentMonitor(MemoryBuffer &mb)
  722. : CIndirectKeySegmentMonitor(mb)
  723. {
  724. mb.read(fieldIdx);
  725. }
  726. virtual bool matches(const RtlRow *keyval) const override
  727. {
  728. return base->matchesBuffer(getSegmentBase(keyval));
  729. }
  730. virtual unsigned numFieldsRequired() const override { return fieldIdx+1; }
  731. // We can't presently build in-memory indexes for varoffset fields, as we don't have a way to
  732. // translate the offsets in the lhs (keybuffer) side of the compare.
  733. // I suppose if we wanted to lift that we could pass in RtlRow for both parameters?
  734. // For now, these methods can never be called
  735. virtual bool matchesBuffer(const void *keyval) const override
  736. {
  737. throwUnexpected();
  738. }
  739. virtual int docompare(const void * expandedLeft, const void * rawRight) const override
  740. {
  741. throwUnexpected();
  742. }
  743. virtual void copy(void * expandedRow, const void * rawRight) const override
  744. {
  745. throwUnexpected();
  746. }
  747. virtual int docompareraw(const void * left, const void * right) const override
  748. {
  749. throwUnexpected();
  750. }
  751. virtual bool isSimple() const override
  752. {
  753. return false; // Does not support in-memory indexes
  754. }
  755. virtual unsigned getFlags() const { return KSM_VAROFFSET; }
  756. virtual MemoryBuffer &serialize(MemoryBuffer &mb) const override
  757. {
  758. return CIndirectKeySegmentMonitor::serialize(mb).append(fieldIdx);
  759. }
  760. virtual KeySegmentMonitorSerializeType serializeType() const override
  761. {
  762. if ((base->serializeType()==KSMST_none))
  763. return KSMST_none;
  764. return KSMST_VAROFFSETKEYSEGMENTMONITOR;
  765. }
  766. virtual IKeySegmentMonitor *clone() const override
  767. {
  768. return NULL; // MORE - can probably be done now
  769. }
  770. protected:
  771. const void *getSegmentBase(const RtlRow *inRec) const
  772. {
  773. return ((const byte *) inRec->queryRow()) + inRec->getOffset(fieldIdx);
  774. }
  775. unsigned fieldIdx;
  776. };
  777. class CTranslatedKeySegmentMonitor : public CIndirectKeySegmentMonitor
  778. {
  779. public:
  780. CTranslatedKeySegmentMonitor(IKeySegmentMonitor * _base, unsigned _offset, IKeySegmentFormatTranslator * _formatTranslator) : CIndirectKeySegmentMonitor(_base, _offset)
  781. {
  782. formatTranslator.setown(_formatTranslator);
  783. size = base->getSize();
  784. unsigned formatHash = formatTranslator->queryHashCode();
  785. hash = hashc((unsigned char *)&formatHash, sizeof(formatHash), hash);
  786. }
  787. CTranslatedKeySegmentMonitor(MemoryBuffer &mb)
  788. : CIndirectKeySegmentMonitor(mb)
  789. {
  790. throwUnexpected();
  791. }
  792. virtual IKeySegmentMonitor *clone() const
  793. {
  794. return NULL;
  795. }
  796. virtual bool matchesBuffer(const void *keyval) const
  797. {
  798. void *expandedLeft = alloca(size);
  799. formatTranslator->extractField(expandedLeft, keyval);
  800. return base->matchesBuffer(expandedLeft);
  801. }
  802. virtual int docompare(const void * left,const void * right) const
  803. {
  804. void *expandedRight = alloca(size);
  805. formatTranslator->extractField(expandedRight, right);
  806. return base->docompare((const byte *)left + offset, expandedRight);
  807. }
  808. virtual void copy(void * left,const void * right) const
  809. {
  810. void *expandedRight = alloca(size);
  811. formatTranslator->extractField(expandedRight, right);
  812. base->copy((byte *)left + offset, expandedRight);
  813. }
  814. virtual int docompareraw(const void * left,const void * right) const
  815. {
  816. void *expandedLeft = alloca(size);
  817. void *expandedRight = alloca(size);
  818. formatTranslator->extractField(expandedLeft, left);
  819. formatTranslator->extractField(expandedRight, right);
  820. return base->docompare(expandedLeft, expandedRight);
  821. }
  822. virtual bool matches(const RtlRow *keyval) const
  823. {
  824. return matchesBuffer(keyval->queryRow());
  825. }
  826. virtual int docompare(const void * left,const RtlRow * right) const
  827. {
  828. return docompare(left, right->queryRow());
  829. }
  830. virtual void copy(void * left,const RtlRow * right) const
  831. {
  832. copy(left, right->queryRow());
  833. }
  834. virtual int docompareraw(const RtlRow * left,const RtlRow * right) const
  835. {
  836. return docompareraw(left->queryRow(), right->queryRow());
  837. }
  838. virtual bool isSimple() const
  839. {
  840. return false; // No way to serialize/persist at present
  841. }
  842. virtual unsigned getFlags() const { return KSM_TRANSLATED; }
  843. virtual KeySegmentMonitorSerializeType serializeType() const
  844. {
  845. return KSMST_none;
  846. }
  847. protected:
  848. Owned<IKeySegmentFormatTranslator> formatTranslator;
  849. size_t size;
  850. };
  851. class COverrideableKeySegmentMonitor : public IOverrideableKeySegmentMonitor, public CInterface
  852. {
  853. const void *overridden;
  854. unsigned hash;
  855. public:
  856. IMPLEMENT_IINTERFACE
  857. COverrideableKeySegmentMonitor(IKeySegmentMonitor * _base)
  858. {
  859. base.setown(_base);
  860. overridden = NULL;
  861. hash = base->queryHashCode();
  862. hash = FNV_32_HASHONE_VALUE(hash, (byte) 123);
  863. }
  864. COverrideableKeySegmentMonitor(MemoryBuffer &mb)
  865. {
  866. mb.read(hash);
  867. base.setown(deserializeKeySegmentMonitor(mb));
  868. overridden = NULL;
  869. }
  870. virtual void setOverrideBuffer(const void *ptr)
  871. {
  872. overridden = ptr;
  873. }
  874. virtual unsigned queryHashCode() const
  875. {
  876. return hash;
  877. }
  878. virtual bool matchesBuffer(const void *keyval) const
  879. {
  880. if (overridden)
  881. {
  882. unsigned offset = base->getOffset();
  883. return memcmp((char *) keyval+offset, (char *) overridden+offset, base->getSize()) == 0;
  884. }
  885. else
  886. return base->matchesBuffer(keyval);
  887. }
  888. virtual bool matches(const RtlRow *keyval) const
  889. {
  890. return matchesBuffer(keyval->queryRow());
  891. }
  892. virtual bool increment(void *keyval) const
  893. {
  894. if (overridden)
  895. {
  896. // Set to next permitted value above current
  897. unsigned offset = base->getOffset();
  898. if (memcmp((char *) keyval+offset, (char *) overridden+offset, base->getSize()) < 0)
  899. {
  900. memcpy((char *) keyval+offset, (char *) overridden+offset, base->getSize());
  901. return true;
  902. }
  903. return false;
  904. }
  905. else
  906. return base->increment(keyval);
  907. }
  908. virtual void setLow(void *keyval) const
  909. {
  910. if (overridden)
  911. {
  912. unsigned offset = base->getOffset();
  913. memcpy((char *) keyval+offset, (char *) overridden+offset, base->getSize());
  914. }
  915. else
  916. base->setLow(keyval);
  917. }
  918. virtual void setHigh(void *keyval) const
  919. {
  920. if (overridden)
  921. {
  922. unsigned offset = base->getOffset();
  923. memcpy((char *) keyval+offset, (char *) overridden+offset, base->getSize());
  924. }
  925. else
  926. base->setHigh(keyval);
  927. }
  928. virtual void endRange(void *keyval) const
  929. {
  930. if (overridden)
  931. {
  932. unsigned offset = base->getOffset();
  933. memcpy((char *) keyval+offset, (char *) overridden+offset, base->getSize());
  934. }
  935. base->endRange(keyval);
  936. }
  937. virtual IKeySegmentMonitor *merge(IKeySegmentMonitor *with) const { return NULL; } // MORE?
  938. virtual IKeySegmentMonitor *combine(const IKeySegmentMonitor *with) const { throwUnexpected(); }
  939. virtual IKeySegmentMonitor * split(unsigned splitSize) { return NULL; } // not required in most cases
  940. virtual bool isWild() const { return overridden ? false : base->isWild(); }
  941. virtual unsigned getOffset() const { return base->getOffset(); }
  942. virtual unsigned getSize() const { return base->getSize(); }
  943. virtual void *queryValue() const { return NULL; }
  944. // virtual unsigned getFlags() const { return base->getFlags(); }
  945. virtual bool isEmpty() const { return base->isEmpty(); }
  946. virtual bool equivalentTo(const IKeySegmentMonitor &other) const { return false; } // MORE?
  947. virtual bool isSigned() const { return base->isSigned(); }
  948. virtual bool isLittleEndian() const { return base->isLittleEndian(); }
  949. virtual bool isWellKeyed() const { return overridden ? true : base->isWellKeyed(); }
  950. virtual bool isOptional() const { return base->isOptional(); }
  951. virtual unsigned numFieldsRequired() const { return base->numFieldsRequired(); }
  952. virtual int docompare(const void * expandedLeft, const void *rawRight) const
  953. {
  954. return base->docompare(expandedLeft, rawRight);
  955. }
  956. virtual void copy(void * expandedRow, const void *rawRight) const
  957. {
  958. base->copy(expandedRow, rawRight); // MORE - is this right?
  959. }
  960. virtual int docompareraw(const void * left, const void * right) const
  961. {
  962. return base->docompare(left, right);
  963. }
  964. virtual int docompare(const void * expandedLeft, const RtlRow *rawRight) const
  965. {
  966. return base->docompare(expandedLeft, rawRight);
  967. }
  968. virtual void copy(void * expandedRow, const RtlRow *rawRight) const
  969. {
  970. base->copy(expandedRow, rawRight); // MORE - is this right?
  971. }
  972. virtual int docompareraw(const RtlRow * left, const RtlRow * right) const
  973. {
  974. return base->docompare(left, right);
  975. }
  976. virtual bool setOffset(unsigned _offset)
  977. {
  978. throwUnexpected();
  979. }
  980. virtual bool isSimple() const
  981. {
  982. return base->isSimple();
  983. }
  984. virtual MemoryBuffer &serialize(MemoryBuffer &mb) const
  985. {
  986. KeySegmentMonitorSerializeType subtyp = base->serializeType();
  987. assertex(subtyp!=KSMST_none);
  988. mb.append((byte)KSMST_OVERRIDEABLEKEYSEGMENTMONITOR).append(hash);
  989. return base->serialize(mb);
  990. }
  991. virtual KeySegmentMonitorSerializeType serializeType() const
  992. {
  993. if ((base->serializeType()==KSMST_none)||overridden) // don't think we can support overridden (TBD revisit)
  994. return KSMST_none;
  995. return KSMST_OVERRIDEABLEKEYSEGMENTMONITOR;
  996. }
  997. virtual IKeySegmentMonitor *clone() const
  998. {
  999. return NULL;
  1000. }
  1001. protected:
  1002. Owned<IKeySegmentMonitor> base;
  1003. };
  1004. ECLRTL_API IStringSet *createRtlStringSet(size32_t size)
  1005. {
  1006. return createStringSet(size);
  1007. }
  1008. ECLRTL_API IStringSet *createRtlStringSetEx(size32_t size, bool bigEndian, bool isSigned)
  1009. {
  1010. return createStringSet(size, bigEndian, isSigned);
  1011. }
  1012. ECLRTL_API IStringSet * rtlUnionSet(IStringSet * lhs, IStringSet * rhs)
  1013. {
  1014. if (lhs->isEmptySet())
  1015. return LINK(rhs);
  1016. else if (lhs->isFullSet())
  1017. return LINK(lhs);
  1018. if (rhs->isEmptySet())
  1019. return LINK(lhs);
  1020. else if (rhs->isFullSet())
  1021. return LINK(rhs);
  1022. return lhs->unionSet(rhs);
  1023. }
  1024. ECLRTL_API IStringSet * rtlIntersectSet(IStringSet * lhs, IStringSet * rhs)
  1025. {
  1026. if (lhs->isFullSet())
  1027. return LINK(rhs);
  1028. else if (lhs->isEmptySet())
  1029. return LINK(lhs);
  1030. if (rhs->isFullSet())
  1031. return LINK(lhs);
  1032. else if (rhs->isEmptySet())
  1033. return LINK(rhs);
  1034. return lhs->intersectSet(rhs);
  1035. }
  1036. IKeySegmentMonitor *createKeySegmentMonitor(bool optional, IStringSet *set, unsigned _offset, unsigned _size)
  1037. {
  1038. if (!set)
  1039. return new CWildKeySegmentMonitor(_offset, _size);
  1040. Owned<IStringSet> removeSet = set; // make sure set is released if optimized out.
  1041. if (set->isSingleValue())
  1042. {
  1043. void *data = alloca(_size);
  1044. set->getTransitionValue(data, 0);
  1045. if (set->isSigned())
  1046. {
  1047. if (set->isBigEndian())
  1048. return createSingleBigSignedKeySegmentMonitor(optional, _offset, _size, data);
  1049. else
  1050. return createSingleLittleSignedKeySegmentMonitor(optional, _offset, _size, data);
  1051. }
  1052. else
  1053. {
  1054. if (set->isBigEndian())
  1055. return createSingleKeySegmentMonitor(optional, _offset, _size, data);
  1056. else
  1057. return createSingleLittleKeySegmentMonitor(optional, _offset, _size, data);
  1058. }
  1059. }
  1060. else if (set->isFullSet())
  1061. return new CWildKeySegmentMonitor(_offset, _size);
  1062. else
  1063. return new CSetKeySegmentMonitor(optional, removeSet.getClear(), _offset, _size);
  1064. }
  1065. ECLRTL_API IStringSet *createRtlStringValue(size32_t size, const char * value)
  1066. {
  1067. IStringSet * set = createStringSet(size);
  1068. set->addRange(value, value);
  1069. return set;
  1070. }
  1071. IKeySegmentMonitor *createWildKeySegmentMonitor(unsigned _offset, unsigned _size)
  1072. {
  1073. return new CWildKeySegmentMonitor(_offset, _size);
  1074. }
  1075. IKeySegmentMonitor *createEmptyKeySegmentMonitor(bool optional, unsigned _offset, unsigned _size)
  1076. {
  1077. return new CSetKeySegmentMonitor(optional, createStringSet(_size), _offset, _size);
  1078. }
  1079. ECLRTL_API IKeySegmentMonitor *createSingleKeySegmentMonitor(bool optional, unsigned offset, unsigned size, const void * value)
  1080. {
  1081. return new CSingleKeySegmentMonitor(optional, value, offset, size);
  1082. }
  1083. ECLRTL_API IOverrideableKeySegmentMonitor *createOverrideableKeySegmentMonitor(IKeySegmentMonitor *base)
  1084. {
  1085. return new COverrideableKeySegmentMonitor(base);
  1086. }
  1087. ECLRTL_API IKeySegmentMonitor *createSingleBigSignedKeySegmentMonitor(bool optional, unsigned offset, unsigned size, const void * value)
  1088. {
  1089. return new CSingleBigSignedKeySegmentMonitor(optional, value, offset, size);
  1090. }
  1091. ECLRTL_API IKeySegmentMonitor *createSingleLittleSignedKeySegmentMonitor(bool optional, unsigned offset, unsigned size, const void * value)
  1092. {
  1093. // MORE - common int sizes 1,2,4 (8?) might be better done with dedicated subclasses
  1094. return new CSingleLittleSignedKeySegmentMonitor(optional, value, offset, size);
  1095. }
  1096. ECLRTL_API IKeySegmentMonitor *createSingleLittleKeySegmentMonitor(bool optional, unsigned offset, unsigned size, const void * value)
  1097. {
  1098. // MORE - common int sizes 1,2,4 (8?) might be better done with dedicated subclasses
  1099. return new CSingleLittleKeySegmentMonitor(optional, value, offset, size);
  1100. }
  1101. ECLRTL_API IKeySegmentMonitor *createDummyKeySegmentMonitor(unsigned _offset, unsigned _size, bool isSigned, bool isLittleEndian)
  1102. {
  1103. if (isSigned)
  1104. if (isLittleEndian)
  1105. return new CSingleLittleSignedKeySegmentMonitor(false, NULL, _offset, _size);
  1106. else
  1107. return new CSingleBigSignedKeySegmentMonitor(false, NULL, _offset, _size);
  1108. else
  1109. if (isLittleEndian)
  1110. return new CSingleLittleKeySegmentMonitor(false, NULL, _offset, _size);
  1111. else
  1112. return new CSingleKeySegmentMonitor(false, NULL, _offset, _size);
  1113. // return new CDummyKeySegmentMonitor(_offset, _size, isSigned, isLittleEndian);
  1114. }
  1115. ECLRTL_API IKeySegmentMonitor *createNewVarOffsetKeySegmentMonitor(IKeySegmentMonitor * base, unsigned offset, unsigned fieldIdx)
  1116. {
  1117. return new CNewVarOffsetKeySegmentMonitor(base, offset, fieldIdx);
  1118. }
  1119. ECLRTL_API IKeySegmentMonitor *createTranslatedKeySegmentMonitor(IKeySegmentMonitor * base, unsigned offset, IKeySegmentFormatTranslator * translator)
  1120. {
  1121. return new CTranslatedKeySegmentMonitor(base, offset, translator);
  1122. }
  1123. ECLRTL_API IKeySegmentMonitor *deserializeKeySegmentMonitor(MemoryBuffer &mb)
  1124. {
  1125. byte typ;
  1126. mb.read(typ);
  1127. switch ((KeySegmentMonitorSerializeType)typ) {
  1128. case KSMST_WILDKEYSEGMENTMONITOR:
  1129. return new CWildKeySegmentMonitor(mb);
  1130. case KSMST_SETKEYSEGMENTMONITOR:
  1131. return new CSetKeySegmentMonitor(mb);
  1132. case KSMST_SINGLEKEYSEGMENTMONITOR:
  1133. return new CSingleKeySegmentMonitor(mb);
  1134. case KSMST_SINGLEBIGSIGNEDKEYSEGMENTMONITOR:
  1135. return new CSingleBigSignedKeySegmentMonitor(mb);
  1136. case KSMST_SINGLELITTLESIGNEDKEYSEGMENTMONITOR:
  1137. return new CSingleLittleSignedKeySegmentMonitor(mb);
  1138. case KSMST_CSINGLELITTLEKEYSEGMENTMONITOR:
  1139. return new CSingleLittleKeySegmentMonitor(mb);
  1140. case KSMST_DUMMYKEYSEGMENTMONITOR:
  1141. return new CDummyKeySegmentMonitor(mb);
  1142. case KSMST_VAROFFSETKEYSEGMENTMONITOR:
  1143. return new CNewVarOffsetKeySegmentMonitor(mb);
  1144. case KSMST_OVERRIDEABLEKEYSEGMENTMONITOR:
  1145. return new COverrideableKeySegmentMonitor(mb);
  1146. }
  1147. return NULL; // up to caller to check
  1148. }
  1149. enum StringSetSerializeType
  1150. {
  1151. SSST_none,
  1152. SSST_BIGUNSIGNEDSTRINGSET,
  1153. SSST_BIGSIGNEDSTRINGSET,
  1154. SSST_LITTLEUNSIGNEDSTRINGSET,
  1155. SSST_LITTLESIGNEDSTRINGSET,
  1156. SSST_max
  1157. };
  1158. ECLRTL_API int memcmpbigsigned(const void *l, const void *r, unsigned size)
  1159. {
  1160. signed int diff = ((signed char *) l)[0]-((signed char *) r)[0];
  1161. if (diff)
  1162. return diff;
  1163. for(unsigned i = 1; i < size; i++)
  1164. {
  1165. diff = ((unsigned char *) l)[i]-((unsigned char *) r)[i];
  1166. if (diff)
  1167. return diff;
  1168. }
  1169. return 0;
  1170. }
  1171. ECLRTL_API int memcmplittleunsigned(const void *l, const void *r, unsigned size)
  1172. {
  1173. while (size)
  1174. {
  1175. size--;
  1176. int diff = ((unsigned char *) l)[size]-((unsigned char *) r)[size];
  1177. if (diff)
  1178. return diff;
  1179. }
  1180. return 0;
  1181. }
  1182. ECLRTL_API int memcmplittlesigned(const void *l, const void *r, unsigned size)
  1183. {
  1184. size--;
  1185. signed int diff = ((signed char *) l)[size]-((signed char *) r)[size];
  1186. if (diff)
  1187. return diff;
  1188. while (size)
  1189. {
  1190. size--;
  1191. diff = ((unsigned char *) l)[size]-((unsigned char *) r)[size];
  1192. if (diff)
  1193. return diff;
  1194. }
  1195. return 0;
  1196. }
  1197. class CStringSet : implements IStringSet, public CInterface
  1198. {
  1199. protected:
  1200. size32_t size;
  1201. IArrayOf<ITransition> transitions;
  1202. IStringSet *unionOrIntersect(IStringSet *r, bool isUnion);
  1203. virtual CStringSet *createEmptySet() = 0;
  1204. virtual bool decrement(void *val) const = 0;
  1205. virtual bool increment(void *val) const = 0;
  1206. virtual int memcmp(const void *val1, const void *val2, size32_t size) const = 0;
  1207. virtual unsigned getCardinality(const void *val1, const void *val2, size32_t size) const = 0;
  1208. virtual void memset(void *ptr, int val, size32_t size) const = 0;
  1209. virtual bool isLowVal(const void *val) const = 0;
  1210. virtual bool isHighVal(const void *val) const = 0;
  1211. bool oneless(const void *l, const void *r) const;
  1212. void addTransitionAt(const void *val, bool state, unsigned pos);
  1213. void appendTransition(ITransition *t);
  1214. public:
  1215. IMPLEMENT_IINTERFACE;
  1216. CStringSet(size32_t size);
  1217. CStringSet(MemoryBuffer &mb);
  1218. // IStringSet
  1219. virtual void addRange(const void *loval, const void *hival);
  1220. virtual void addAll();
  1221. virtual ITransition *queryTransition(unsigned idx);
  1222. virtual bool getTransitionValue(void *value, unsigned idx);
  1223. virtual void killRange(const void *loval, const void *hival);
  1224. virtual bool inRange(const void *val) const;
  1225. virtual bool inRange(const void *val, unsigned &transition) const;
  1226. virtual size32_t getSize() { return size; };
  1227. virtual void reset();
  1228. virtual unsigned transitionCount();
  1229. virtual IStringSet *invertSet();
  1230. virtual IStringSet *unionSet(IStringSet *);
  1231. virtual IStringSet *intersectSet(IStringSet *);
  1232. virtual const char *describe(StringBuffer &ret);
  1233. virtual bool isEmptySet() const { return transitions.length()==0; }
  1234. virtual bool isFullSet() const
  1235. {
  1236. return transitions.length()==2 &&
  1237. isLowVal(transitions.item(0).getValue()) &&
  1238. isHighVal(transitions.item(1).getValue());
  1239. }
  1240. virtual bool isSingleValue() const
  1241. {
  1242. return transitions.length()==2 &&
  1243. memcmp(transitions.item(0).getValue(), transitions.item(1).getValue(), size) == 0;
  1244. }
  1245. virtual unsigned numValues() const
  1246. {
  1247. unsigned ret = 0;
  1248. unsigned idx = 0;
  1249. while (transitions.isItem(idx+1))
  1250. {
  1251. unsigned thisrange = getCardinality(transitions.item(idx).getValue(), transitions.item(idx+1).getValue(), size);
  1252. if (thisrange + ret < ret)
  1253. return (unsigned) -1;
  1254. ret += thisrange;
  1255. idx += 2;
  1256. }
  1257. return ret;
  1258. }
  1259. virtual MemoryBuffer &serialize(MemoryBuffer &mb) const
  1260. {
  1261. StringSetSerializeType typ = serializeType();
  1262. assertex(typ!=SSST_none);
  1263. mb.append((byte)typ).append(size).append(transitions.ordinality());
  1264. ForEachItemIn(i,transitions) {
  1265. transitions.item(i).serialize(size,mb);
  1266. }
  1267. return mb;
  1268. }
  1269. virtual StringSetSerializeType serializeType() const = 0;
  1270. };
  1271. class CBigUnsignedStringSet : public CStringSet
  1272. {
  1273. protected:
  1274. virtual CStringSet *createEmptySet()
  1275. {
  1276. return new CBigUnsignedStringSet(size);
  1277. }
  1278. virtual bool increment(void *_val) const
  1279. {
  1280. unsigned char *val = (unsigned char *)_val;
  1281. int i = size;
  1282. while (i--)
  1283. {
  1284. val[i]++;
  1285. if (val[i]!=0)
  1286. return true;
  1287. }
  1288. return false;
  1289. }
  1290. virtual bool decrement(void *_val) const
  1291. {
  1292. unsigned char *val = (unsigned char *)_val;
  1293. int i = size;
  1294. while (i--)
  1295. {
  1296. val[i]--;
  1297. if ((unsigned char)val[i]!=0xff)
  1298. return true;
  1299. }
  1300. return false;
  1301. }
  1302. virtual int memcmp(const void *val1, const void *val2, size32_t size) const
  1303. {
  1304. return ::memcmp(val1, val2, size);
  1305. }
  1306. virtual void memset(void *ptr, int val, size32_t size) const
  1307. {
  1308. ::memset(ptr, val, size);
  1309. }
  1310. virtual unsigned getCardinality(const void *val1, const void *val2, size32_t size) const
  1311. {
  1312. unsigned char *p1 = (unsigned char *) val1;
  1313. unsigned char *p2 = (unsigned char *) val2;
  1314. unsigned ret = 1;
  1315. unsigned mult = 1;
  1316. while (size--)
  1317. {
  1318. unsigned diff = p2[size] - p1[size];
  1319. if (diff)
  1320. {
  1321. if (!mult)
  1322. return (unsigned) -1;
  1323. else
  1324. ret += diff * mult;
  1325. }
  1326. if (mult*256 < mult)
  1327. mult = 0;
  1328. else
  1329. mult *= 256;
  1330. }
  1331. return ret;
  1332. }
  1333. virtual bool isHighVal(const void *val) const
  1334. {
  1335. const unsigned char *vval = (const unsigned char *) val;
  1336. for (unsigned i = 0; i < size; i++)
  1337. if (vval[i] != 0xff)
  1338. return false;
  1339. return true;
  1340. }
  1341. virtual bool isLowVal(const void *val) const
  1342. {
  1343. const unsigned char *vval = (const unsigned char *) val;
  1344. for (unsigned i = 0; i < size; i++)
  1345. if (vval[i] != 0x00)
  1346. return false;
  1347. return true;
  1348. }
  1349. virtual bool isSigned() const { return false; }
  1350. virtual bool isBigEndian() const { return true; }
  1351. virtual StringSetSerializeType serializeType() const
  1352. {
  1353. return SSST_BIGUNSIGNEDSTRINGSET;
  1354. }
  1355. public:
  1356. CBigUnsignedStringSet(unsigned size) : CStringSet(size) {}
  1357. CBigUnsignedStringSet(MemoryBuffer &mb) : CStringSet(mb) {}
  1358. };
  1359. class CBigSignedStringSet : public CBigUnsignedStringSet
  1360. {
  1361. protected:
  1362. virtual CStringSet *createEmptySet()
  1363. {
  1364. return new CBigSignedStringSet(size);
  1365. }
  1366. // increment and decrement are same as unsigned
  1367. virtual int memcmp(const void *val1, const void *val2, size32_t size) const
  1368. {
  1369. return ::memcmpbigsigned(val1, val2, size);
  1370. }
  1371. virtual void memset(void *ptr, int val, size32_t size) const
  1372. {
  1373. ::memset(ptr, val, size);
  1374. switch(val)
  1375. {
  1376. case 0:
  1377. *(unsigned char *) ptr = 0x80;
  1378. break;
  1379. case 0xff:
  1380. *(unsigned char *) ptr = 0x7f;
  1381. break;
  1382. default:
  1383. throwUnexpected();
  1384. }
  1385. }
  1386. virtual bool isHighVal(const void *val) const
  1387. {
  1388. const unsigned char *vval = (const unsigned char *) val;
  1389. if (vval[0] != 0x7f)
  1390. return false;
  1391. for (unsigned i = 1; i < size; i++)
  1392. if (vval[i] != 0xff)
  1393. return false;
  1394. return true;
  1395. }
  1396. virtual bool isLowVal(const void *val) const
  1397. {
  1398. const unsigned char *vval = (const unsigned char *) val;
  1399. if (vval[0] != 0x80)
  1400. return false;
  1401. for (unsigned i = 1; i < size; i++)
  1402. if (vval[i] != 0x00)
  1403. return false;
  1404. return true;
  1405. }
  1406. virtual bool isSigned() const { return true; }
  1407. virtual bool isBigEndian() const { return true; }
  1408. virtual StringSetSerializeType serializeType() const
  1409. {
  1410. return SSST_BIGSIGNEDSTRINGSET;
  1411. }
  1412. public:
  1413. CBigSignedStringSet(unsigned size) : CBigUnsignedStringSet(size) {}
  1414. CBigSignedStringSet(MemoryBuffer &mb) : CBigUnsignedStringSet(mb) {}
  1415. };
  1416. class CLittleUnsignedStringSet : public CStringSet
  1417. {
  1418. protected:
  1419. virtual CStringSet *createEmptySet()
  1420. {
  1421. return new CLittleUnsignedStringSet(size);
  1422. }
  1423. virtual bool increment(void *_val) const
  1424. {
  1425. unsigned char *val = (unsigned char *)_val;
  1426. unsigned i = 0;
  1427. while (i < size)
  1428. {
  1429. val[i]++;
  1430. if (val[i]!=0)
  1431. return true;
  1432. i++;
  1433. }
  1434. return false;
  1435. }
  1436. virtual unsigned getCardinality(const void *val1, const void *val2, size32_t size) const
  1437. {
  1438. unsigned char *p1 = (unsigned char *) val1;
  1439. unsigned char *p2 = (unsigned char *) val2;
  1440. unsigned ret = 1;
  1441. unsigned mult = 1;
  1442. unsigned i = 0;
  1443. while (i < size)
  1444. {
  1445. unsigned diff = p2[i] - p1[i];
  1446. if (diff)
  1447. {
  1448. if (!mult)
  1449. return (unsigned) -1;
  1450. else
  1451. ret += diff * mult;
  1452. }
  1453. if (mult*256 < mult)
  1454. mult = 0;
  1455. else
  1456. mult *= 256;
  1457. i++;
  1458. }
  1459. return ret;
  1460. }
  1461. virtual bool decrement(void *_val) const
  1462. {
  1463. unsigned char *val = (unsigned char *)_val;
  1464. unsigned i = 0;
  1465. while (i < size)
  1466. {
  1467. val[i]--;
  1468. if ((unsigned char)val[i]!=0xff)
  1469. return true;
  1470. i++;
  1471. }
  1472. return false;
  1473. }
  1474. virtual int memcmp(const void *val1, const void *val2, size32_t size) const
  1475. {
  1476. return ::memcmplittleunsigned(val1, val2, size);
  1477. }
  1478. virtual void memset(void *ptr, int val, size32_t size) const
  1479. {
  1480. ::memset(ptr, val, size);
  1481. }
  1482. virtual bool isHighVal(const void *val) const
  1483. {
  1484. const unsigned char *vval = (const unsigned char *) val;
  1485. for (unsigned i = 0; i < size; i++)
  1486. if (vval[i] != 0xff)
  1487. return false;
  1488. return true;
  1489. }
  1490. virtual bool isLowVal(const void *val) const
  1491. {
  1492. const unsigned char *vval = (const unsigned char *) val;
  1493. for (unsigned i = 0; i < size; i++)
  1494. if (vval[i] != 0x00)
  1495. return false;
  1496. return true;
  1497. }
  1498. virtual bool isSigned() const { return false; }
  1499. virtual bool isBigEndian() const { return false; }
  1500. virtual StringSetSerializeType serializeType() const
  1501. {
  1502. return SSST_LITTLEUNSIGNEDSTRINGSET;
  1503. }
  1504. public:
  1505. CLittleUnsignedStringSet(unsigned size) : CStringSet(size) {}
  1506. CLittleUnsignedStringSet(MemoryBuffer &mb) : CStringSet(mb) {}
  1507. };
  1508. class CLittleSignedStringSet : public CLittleUnsignedStringSet
  1509. {
  1510. protected:
  1511. virtual CStringSet *createEmptySet()
  1512. {
  1513. return new CLittleSignedStringSet(size);
  1514. }
  1515. // increment and decrement are same as unsigned
  1516. virtual int memcmp(const void *val1, const void *val2, size32_t size) const
  1517. {
  1518. return ::memcmplittlesigned(val1, val2, size);
  1519. }
  1520. virtual void memset(void *ptr, int val, size32_t size) const
  1521. {
  1522. if (size > 1)
  1523. ::memset(ptr, val, size);
  1524. unsigned char *pptr = (unsigned char *) ptr;
  1525. switch(val)
  1526. {
  1527. case 0:
  1528. pptr[size-1] = 0x80;
  1529. break;
  1530. case 0xff:
  1531. pptr[size-1] = 0x7f;
  1532. break;
  1533. default:
  1534. throwUnexpected();
  1535. }
  1536. }
  1537. virtual bool isHighVal(const void *val) const
  1538. {
  1539. const unsigned char *vval = (const unsigned char *) val;
  1540. if (vval[size-1] != 0x7f)
  1541. return false;
  1542. for (unsigned i = 0; i < size-1; i++)
  1543. if (vval[i] != 0xff)
  1544. return false;
  1545. return true;
  1546. }
  1547. virtual bool isLowVal(const void *val) const
  1548. {
  1549. const unsigned char *vval = (const unsigned char *) val;
  1550. if (vval[size-1] != 0x80)
  1551. return false;
  1552. for (unsigned i = 0; i < size-1; i++)
  1553. if (vval[i] != 0x00)
  1554. return false;
  1555. return true;
  1556. }
  1557. virtual bool isSigned() const { return true; }
  1558. virtual bool isBigEndian() const { return false; }
  1559. virtual StringSetSerializeType serializeType() const
  1560. {
  1561. return SSST_LITTLESIGNEDSTRINGSET;
  1562. }
  1563. public:
  1564. CLittleSignedStringSet(unsigned size) : CLittleUnsignedStringSet(size) {}
  1565. CLittleSignedStringSet(MemoryBuffer &mb) : CLittleUnsignedStringSet(mb) {}
  1566. };
  1567. class CTransition : implements ITransition, public CInterface
  1568. {
  1569. private:
  1570. bool state; // note: should move before ITransition to pack better in 64bit
  1571. const void *val;
  1572. public:
  1573. IMPLEMENT_IINTERFACE;
  1574. CTransition(const void *_val, bool _state)
  1575. {
  1576. val = _val;
  1577. state = _state;
  1578. }
  1579. CTransition(MemoryBuffer &mb,size32_t size)
  1580. {
  1581. mb.read(state);
  1582. val = malloc(size);
  1583. memcpy((void *)val,mb.readDirect(size),size);
  1584. }
  1585. ~CTransition() { free((void *) val); }
  1586. // ITransition
  1587. bool getState() const { return state; }
  1588. const void *getValue() const { return val; }
  1589. MemoryBuffer &serialize(size32_t size, MemoryBuffer &mb) const
  1590. {
  1591. mb.append(state);
  1592. memcpy(mb.reserve(size),val,size);
  1593. return mb;
  1594. }
  1595. bool canSerialize() const { return true; }
  1596. };
  1597. //======================================================================================
  1598. CStringSet::CStringSet(size32_t _size)
  1599. {
  1600. size = _size;
  1601. }
  1602. CStringSet::CStringSet(MemoryBuffer &mb)
  1603. {
  1604. mb.read(size);
  1605. unsigned n;
  1606. mb.read(n);
  1607. while(n--)
  1608. transitions.append(*new CTransition(mb,size));
  1609. }
  1610. void CStringSet::reset()
  1611. {
  1612. transitions.kill();
  1613. }
  1614. bool CStringSet::oneless(const void *l, const void *r) const
  1615. {
  1616. // MORE - would be more efficient to make this virtual like the memcmp...
  1617. void *t = alloca(size);
  1618. memcpy(t, r, size);
  1619. decrement(t);
  1620. return memcmp(l, t, size)==0;
  1621. }
  1622. unsigned CStringSet::transitionCount()
  1623. {
  1624. return transitions.ordinality();
  1625. }
  1626. void CStringSet::addTransitionAt(const void *val, bool state, unsigned pos)
  1627. {
  1628. void *newval = malloc(size);
  1629. memcpy(newval, val, size);
  1630. transitions.add(* new CTransition(newval, state), pos);
  1631. }
  1632. void CStringSet::appendTransition(ITransition *t)
  1633. {
  1634. if (t->getState() && transitions.length())
  1635. {
  1636. unsigned lastidx = transitions.length()-1;
  1637. ITransition &prev = transitions.item(lastidx);
  1638. assertex(prev.getState()==!t->getState());
  1639. if (oneless(prev.getValue(), t->getValue()))
  1640. {
  1641. transitions.remove(lastidx);
  1642. t->Release();
  1643. return;
  1644. }
  1645. }
  1646. transitions.append(*t);
  1647. }
  1648. void CStringSet::addRange(const void *loval, const void *hival)
  1649. {
  1650. if (!loval)
  1651. {
  1652. void *x = alloca(size);
  1653. memset(x, 0, size);
  1654. loval = x;
  1655. }
  1656. if (!hival)
  1657. {
  1658. void *x = alloca(size);
  1659. memset(x, 0xff, size);
  1660. hival = x;
  1661. }
  1662. if (memcmp(loval, hival, size) > 0)
  1663. return;
  1664. unsigned idx;
  1665. bool inset = false;
  1666. int b = transitions.ordinality();
  1667. if (!b)
  1668. {
  1669. addTransitionAt(loval, true, 0);
  1670. addTransitionAt(hival, false, 1);
  1671. return;
  1672. }
  1673. else
  1674. {
  1675. // binchop to find last transition > val...
  1676. unsigned int a = 0;
  1677. int rc;
  1678. while ((int)a<b)
  1679. {
  1680. int i = a+(b+1-a)/2;
  1681. rc = memcmp(loval, transitions.item(i-1).getValue(), size);
  1682. if (rc>0)
  1683. a = i;
  1684. else
  1685. b = i-1;
  1686. }
  1687. if (a>0)
  1688. {
  1689. idx = a;
  1690. ITransition &t = transitions.item(idx-1);
  1691. if(!t.getState())
  1692. {
  1693. if (oneless(t.getValue(), loval))
  1694. transitions.remove(--idx);
  1695. else
  1696. addTransitionAt(loval, true, idx++);
  1697. }
  1698. else
  1699. inset = true;
  1700. }
  1701. else
  1702. {
  1703. addTransitionAt(loval, true, 0);
  1704. idx = 1;
  1705. }
  1706. }
  1707. while (transitions.isItem(idx))
  1708. {
  1709. ITransition &t = transitions.item(idx);
  1710. int diff = memcmp(t.getValue(), hival, size);
  1711. if (diff <= 0)
  1712. {
  1713. inset = t.getState();
  1714. transitions.remove(idx);
  1715. }
  1716. else
  1717. break;
  1718. }
  1719. if (!inset)
  1720. {
  1721. if (transitions.isItem(idx))
  1722. {
  1723. ITransition &t = transitions.item(idx);
  1724. assertex(t.getState());
  1725. if (oneless(hival, t.getValue()))
  1726. {
  1727. transitions.remove(idx);
  1728. return;
  1729. }
  1730. }
  1731. addTransitionAt(hival, false, idx);
  1732. }
  1733. }
  1734. void CStringSet::killRange(const void *loval, const void *hival)
  1735. {
  1736. if (!loval)
  1737. {
  1738. void *x = alloca(size);
  1739. memset(x, 0, size);
  1740. loval = x;
  1741. }
  1742. if (!hival)
  1743. {
  1744. void *x = alloca(size);
  1745. memset(x, 0xff, size);
  1746. hival = x;
  1747. }
  1748. assertex(memcmp(loval, hival, size) <= 0);
  1749. bool inset = false;
  1750. ForEachItemIn(idx, transitions)
  1751. {
  1752. ITransition &t = transitions.item(idx);
  1753. int diff = memcmp(t.getValue(), loval, size);
  1754. if (diff < 0)
  1755. inset = t.getState();
  1756. else
  1757. break;
  1758. }
  1759. if (inset)
  1760. {
  1761. void *nlo = alloca(size);
  1762. memcpy(nlo, loval, size);
  1763. decrement(nlo);
  1764. addTransitionAt(nlo, false, idx++);
  1765. }
  1766. while (transitions.isItem(idx))
  1767. {
  1768. ITransition &t = transitions.item(idx);
  1769. int diff = memcmp(t.getValue(), hival, size);
  1770. if (diff <= 0)
  1771. {
  1772. inset = t.getState();
  1773. transitions.remove(idx);
  1774. }
  1775. else
  1776. break;
  1777. }
  1778. if (inset)
  1779. {
  1780. void *nhi = alloca(size);
  1781. memcpy(nhi, hival, size);
  1782. increment(nhi);
  1783. addTransitionAt(nhi, true, idx);
  1784. }
  1785. }
  1786. void CStringSet::addAll()
  1787. {
  1788. reset();
  1789. void *val = alloca(size);
  1790. memset(val, 0, size);
  1791. addTransitionAt(val, true, 0);
  1792. memset(val, 0xff, size);
  1793. addTransitionAt(val, false, 1);
  1794. }
  1795. const char *CStringSet::describe(StringBuffer &ret)
  1796. {
  1797. ret.append('[');
  1798. ForEachItemIn(idx, transitions)
  1799. {
  1800. ITransition &t = transitions.item(idx);
  1801. if (t.getState())
  1802. {
  1803. if (idx)
  1804. ret.append(',');
  1805. }
  1806. else
  1807. ret.append("..");
  1808. appendURL(&ret, (char *) t.getValue(), size, true);
  1809. }
  1810. ret.append(']');
  1811. return ret.str();
  1812. }
  1813. bool CStringSet::inRange(const void *val) const
  1814. {
  1815. unsigned nextTransition;
  1816. return inRange(val, nextTransition);
  1817. }
  1818. bool CStringSet::inRange(const void *val, unsigned &nextTransition) const
  1819. {
  1820. int b = transitions.ordinality();
  1821. if (!b)
  1822. {
  1823. nextTransition = (unsigned) -1;
  1824. return false;
  1825. }
  1826. else if (b >= 4)
  1827. {
  1828. // binchop to find last transition >= val...
  1829. unsigned int a = 0;
  1830. int rc;
  1831. while ((int)a<b)
  1832. {
  1833. int i = a+(b+1-a)/2;
  1834. rc = memcmp(val, transitions.item(i-1).getValue(), size);
  1835. if (rc>=0)
  1836. a = i;
  1837. else
  1838. b = i-1;
  1839. }
  1840. if (a>0)
  1841. {
  1842. nextTransition = (a>=transitions.ordinality())? (unsigned) -1: a; // a is first transition that is > val
  1843. a--;
  1844. if (transitions.item(a).getState())
  1845. return true;
  1846. if (memcmp(val, transitions.item(a).getValue(), size)==0)
  1847. {
  1848. nextTransition = a;
  1849. return true;
  1850. }
  1851. return false;
  1852. }
  1853. else
  1854. {
  1855. nextTransition = 0;
  1856. return false;
  1857. }
  1858. }
  1859. else
  1860. {
  1861. bool inset = false;
  1862. ForEachItemIn(idx, transitions)
  1863. {
  1864. ITransition &t = transitions.item(idx);
  1865. int diff = memcmp(t.getValue(), val, size);
  1866. if (t.getState())
  1867. {
  1868. if (diff <= 0)
  1869. inset = true;
  1870. if (diff == 0)
  1871. {
  1872. idx++;
  1873. break;
  1874. }
  1875. else if (diff > 0)
  1876. break;
  1877. }
  1878. else
  1879. {
  1880. if (diff >= 0)
  1881. break;
  1882. if (diff < 0)
  1883. inset = false;
  1884. }
  1885. }
  1886. nextTransition = (idx>=transitions.ordinality())? (unsigned) -1: idx;
  1887. return inset;
  1888. }
  1889. }
  1890. IStringSet *CStringSet::unionOrIntersect(IStringSet *r, bool isUnion)
  1891. {
  1892. bool inA = false;
  1893. bool inB = false;
  1894. bool state = false;
  1895. assertex(r->getSize()==size);
  1896. int idxA = 0;
  1897. int idxB = 0;
  1898. ITransition *tA = queryTransition(idxA);
  1899. ITransition *tB = r->queryTransition(idxB);
  1900. CStringSet *result = createEmptySet();
  1901. for (;;)
  1902. {
  1903. int diff;
  1904. if (tA == NULL)
  1905. {
  1906. if (tB == NULL)
  1907. break;
  1908. else
  1909. diff = 1;
  1910. }
  1911. else if (tB == NULL)
  1912. diff = -1;
  1913. else
  1914. diff = memcmp(tA->getValue(), tB->getValue(), size);
  1915. ITransition *t = NULL;
  1916. if (!diff)
  1917. {
  1918. diff = (int) tB->getState() - (int) tA->getState(); // leading edge sorts before trailing edge for intersect...
  1919. if (isUnion)
  1920. diff = -diff; // trailing edge sorts before leading edge for union...
  1921. }
  1922. if (diff <= 0)
  1923. {
  1924. inA = tA->getState();
  1925. t = tA;
  1926. idxA++;
  1927. tA = queryTransition(idxA);
  1928. }
  1929. if (diff >= 0)
  1930. {
  1931. inB = tB->getState();
  1932. t = tB;
  1933. idxB++;
  1934. tB = r->queryTransition(idxB);
  1935. }
  1936. bool newState;
  1937. if (isUnion)
  1938. newState = inA || inB;
  1939. else
  1940. newState = inA && inB;
  1941. if (newState != state)
  1942. {
  1943. state = newState;
  1944. t->Link();
  1945. result->appendTransition(t);
  1946. }
  1947. }
  1948. return result;
  1949. }
  1950. IStringSet *CStringSet::invertSet()
  1951. {
  1952. CStringSet *result = createEmptySet();
  1953. result->addAll();
  1954. bool inset = false;
  1955. void *loval = alloca(size);
  1956. void *hival = alloca(size);
  1957. memset(loval, 0, size);
  1958. ForEachItemIn(idx, transitions)
  1959. {
  1960. ITransition &t = transitions.item(idx);
  1961. assertex(t.getState() == !inset);
  1962. if (inset)
  1963. {
  1964. memcpy(hival, t.getValue(), size);
  1965. result->killRange(loval, hival);
  1966. }
  1967. else
  1968. memcpy(loval, t.getValue(), size);
  1969. inset = t.getState();
  1970. }
  1971. if (inset)
  1972. {
  1973. memset(hival, 0xff, size);
  1974. result->killRange(loval, hival);
  1975. }
  1976. return result;
  1977. }
  1978. IStringSet *CStringSet::unionSet(IStringSet *other)
  1979. {
  1980. return unionOrIntersect(other, true);
  1981. }
  1982. IStringSet *CStringSet::intersectSet(IStringSet *other)
  1983. {
  1984. return unionOrIntersect(other, false);
  1985. }
  1986. ITransition *CStringSet::queryTransition(unsigned int idx)
  1987. {
  1988. if (transitions.isItem(idx))
  1989. {
  1990. ITransition *t = &transitions.item(idx);
  1991. return t;
  1992. }
  1993. else
  1994. return NULL;
  1995. }
  1996. bool CStringSet::getTransitionValue(void *value, unsigned int idx)
  1997. {
  1998. if (idx == (unsigned) -1 || idx >= transitions.ordinality()) return false;
  1999. ITransition &t = transitions.item(idx);
  2000. memcpy(value, t.getValue(), size);
  2001. return true;
  2002. }
  2003. IStringSet *createStringSet(size32_t size)
  2004. {
  2005. return new CBigUnsignedStringSet(size);
  2006. }
  2007. IStringSet *createStringSet(size32_t size, bool bigEndian, bool isSigned)
  2008. {
  2009. if (bigEndian)
  2010. {
  2011. if (isSigned)
  2012. return new CBigSignedStringSet(size);
  2013. else
  2014. return new CBigUnsignedStringSet(size);
  2015. }
  2016. else
  2017. {
  2018. if (isSigned)
  2019. return new CLittleSignedStringSet(size);
  2020. else
  2021. return new CLittleUnsignedStringSet(size);
  2022. }
  2023. }
  2024. ECLRTL_API IStringSet *deserializeStringSet(MemoryBuffer &mb)
  2025. {
  2026. byte typ;
  2027. mb.read(typ);
  2028. switch((StringSetSerializeType)typ) {
  2029. case SSST_BIGUNSIGNEDSTRINGSET:
  2030. return new CBigUnsignedStringSet(mb);
  2031. case SSST_BIGSIGNEDSTRINGSET:
  2032. return new CBigSignedStringSet(mb);
  2033. case SSST_LITTLEUNSIGNEDSTRINGSET:
  2034. return new CLittleUnsignedStringSet(mb);
  2035. case SSST_LITTLESIGNEDSTRINGSET:
  2036. return new CLittleSignedStringSet(mb);
  2037. }
  2038. return NULL; // up to caller to check
  2039. };
  2040. #ifdef _USE_CPPUNIT
  2041. #include <cppunit/extensions/HelperMacros.h>
  2042. /*
  2043. class IStdException : extends std::exception
  2044. {
  2045. Owned<IException> jException;
  2046. public:
  2047. IStdException(IException *E) : jException(E) {};
  2048. };
  2049. */
  2050. class SegmentMonitorTest : public CppUnit::TestFixture
  2051. {
  2052. CPPUNIT_TEST_SUITE( SegmentMonitorTest );
  2053. CPPUNIT_TEST(testOptional);
  2054. CPPUNIT_TEST(testCombine);
  2055. CPPUNIT_TEST_SUITE_END();
  2056. protected:
  2057. void testOptional()
  2058. {
  2059. Owned<IKeySegmentMonitor> wild0_20 = createWildKeySegmentMonitor(0, 20);
  2060. Owned<IKeySegmentMonitor> wild10_10 = createWildKeySegmentMonitor(10,10);
  2061. Owned<IStringSet> abcdef = createStringSet(10);
  2062. abcdef->addRange("ABCDEFGHIJ", "ABCDEFGHIJ");
  2063. Owned<IKeySegmentMonitor> opt0_20 = createSingleKeySegmentMonitor(true, 0,20, "abcdefghijklmnopqrst");
  2064. Owned<IKeySegmentMonitor> opt20_10 = createKeySegmentMonitor(true, LINK(abcdef), 20, 10);
  2065. Owned<IKeySegmentMonitor> opt30_10 = createSingleKeySegmentMonitor(true, 30, 10, "KLMNOPQRST");
  2066. Owned<IKeySegmentMonitor> nonOpt0_10 = createSingleKeySegmentMonitor(false, 0,10, "abcdefghij");
  2067. Owned<IKeySegmentMonitor> nonOpt0_20 = createSingleKeySegmentMonitor(false, 0,20, "abcdefghijklmnopqrst");
  2068. Owned<IKeySegmentMonitor> nonOpt20_10 = createKeySegmentMonitor(false, LINK(abcdef), 20, 10);
  2069. Owned<IKeySegmentMonitor> nonOpt30_10 = createSingleKeySegmentMonitor(false, 30, 10, "KLMNOPQRST");
  2070. CPPUNIT_ASSERT(wild0_20->isOptional());
  2071. CPPUNIT_ASSERT(opt20_10->isOptional());
  2072. CPPUNIT_ASSERT(opt30_10->isOptional());
  2073. CPPUNIT_ASSERT(!nonOpt0_10->isOptional());
  2074. CPPUNIT_ASSERT(!nonOpt0_20->isOptional());
  2075. CPPUNIT_ASSERT(!nonOpt20_10->isOptional());
  2076. CPPUNIT_ASSERT(!nonOpt30_10->isOptional());
  2077. #if 0
  2078. IKeySegmentMonitorArray segments;
  2079. segments.append(*LINK(wild0_20));
  2080. segments.append(*LINK(opt20_10));
  2081. CPPUNIT_ASSERT(segments.ordinality() == 1);
  2082. CPPUNIT_ASSERT(segments.item(0).isWild());
  2083. CPPUNIT_ASSERT(segments.item(0).getOffset() == 0);
  2084. CPPUNIT_ASSERT(segments.item(0).getSize() == 30);
  2085. segments.kill();
  2086. segments.append(*LINK(wild0_20));
  2087. segments.append(*LINK(opt20_10));
  2088. segments.append(*LINK(nonOpt30_10));
  2089. CPPUNIT_ASSERT(segments.ordinality() == 2);
  2090. CPPUNIT_ASSERT(segments.item(0).isWild());
  2091. CPPUNIT_ASSERT(segments.item(0).getOffset() == 0);
  2092. CPPUNIT_ASSERT(segments.item(0).getSize() == 30);
  2093. CPPUNIT_ASSERT(!segments.item(1).isWild());
  2094. CPPUNIT_ASSERT(segments.item(1).getOffset() == 30);
  2095. CPPUNIT_ASSERT(segments.item(1).getSize() == 10);
  2096. segments.kill();
  2097. segments.append(*LINK(nonOpt0_20));
  2098. segments.append(*LINK(opt20_10));
  2099. segments.append(*LINK(nonOpt30_10));
  2100. CPPUNIT_ASSERT(segments.ordinality() == 3);
  2101. CPPUNIT_ASSERT(!segments.item(1).isWild());
  2102. CPPUNIT_ASSERT(segments.item(1).getOffset() == 20);
  2103. CPPUNIT_ASSERT(segments.item(1).getSize() == 10);
  2104. segments.kill();
  2105. segments.append(*LINK(nonOpt0_10));
  2106. segments.append(*LINK(wild10_10));
  2107. segments.append(*LINK(opt20_10));
  2108. segments.append(*LINK(nonOpt30_10));
  2109. CPPUNIT_ASSERT(segments.ordinality() == 3);
  2110. CPPUNIT_ASSERT(!segments.item(0).isWild());
  2111. CPPUNIT_ASSERT(segments.item(1).isWild());
  2112. CPPUNIT_ASSERT(segments.item(1).getOffset() == 10);
  2113. CPPUNIT_ASSERT(segments.item(1).getSize() == 20);
  2114. segments.kill();
  2115. segments.append(*LINK(opt0_20));
  2116. segments.append(*LINK(opt20_10));
  2117. segments.append(*LINK(nonOpt30_10));
  2118. CPPUNIT_ASSERT(segments.ordinality() == 3);
  2119. CPPUNIT_ASSERT(!segments.item(0).isWild());
  2120. CPPUNIT_ASSERT(!segments.item(1).isWild());
  2121. CPPUNIT_ASSERT(segments.item(1).getOffset() == 20);
  2122. CPPUNIT_ASSERT(segments.item(1).getSize() == 10);
  2123. #endif
  2124. }
  2125. void testCombine()
  2126. {
  2127. Owned<IStringSet> az = createStringSet(1);
  2128. az->addRange("A", "Z");
  2129. Owned<IStringSet> dj = createStringSet(1);
  2130. dj->addRange("D", "J");
  2131. Owned<IStringSet> hz = createStringSet(1);
  2132. hz->addRange("H", "Z");
  2133. Owned<IStringSet> jk = createStringSet(1);
  2134. jk->addRange("J", "K");
  2135. Owned<IKeySegmentMonitor> segA = createSingleKeySegmentMonitor(true, 0,1, "A");
  2136. Owned<IKeySegmentMonitor> segA2 = createSingleKeySegmentMonitor(true, 0,1, "A");
  2137. Owned<IKeySegmentMonitor> segJ = createSingleKeySegmentMonitor(true, 0,1, "J");
  2138. Owned<IKeySegmentMonitor> segAZ = createKeySegmentMonitor(true, az.getLink(), 0,1);
  2139. Owned<IKeySegmentMonitor> segDJ = createKeySegmentMonitor(true, dj.getLink(), 0,1);
  2140. Owned<IKeySegmentMonitor> segHZ = createKeySegmentMonitor(true, hz.getLink(), 0,1);
  2141. Owned<IKeySegmentMonitor> segJK = createKeySegmentMonitor(true, jk.getLink(), 0,1);
  2142. Owned<IKeySegmentMonitor> result;
  2143. result.setown(segA->combine(segA2));
  2144. CPPUNIT_ASSERT(!result->isEmpty());
  2145. CPPUNIT_ASSERT(result->matchesBuffer("A"));
  2146. result.setown(segA->combine(segJ));
  2147. CPPUNIT_ASSERT(result->isEmpty());
  2148. result.setown(segA->combine(segAZ));
  2149. CPPUNIT_ASSERT(!result->isEmpty());
  2150. CPPUNIT_ASSERT(result->matchesBuffer("A"));
  2151. CPPUNIT_ASSERT(!result->matchesBuffer("B"));
  2152. result.setown(segAZ->combine(segDJ));
  2153. CPPUNIT_ASSERT(!result->isEmpty());
  2154. CPPUNIT_ASSERT(!result->matchesBuffer("C"));
  2155. CPPUNIT_ASSERT(result->matchesBuffer("D"));
  2156. CPPUNIT_ASSERT(result->matchesBuffer("J"));
  2157. CPPUNIT_ASSERT(!result->matchesBuffer("K"));
  2158. result.setown(segHZ->combine(segDJ));
  2159. CPPUNIT_ASSERT(!result->isEmpty());
  2160. CPPUNIT_ASSERT(!result->matchesBuffer("G"));
  2161. CPPUNIT_ASSERT(result->matchesBuffer("H"));
  2162. CPPUNIT_ASSERT(result->matchesBuffer("J"));
  2163. CPPUNIT_ASSERT(!result->matchesBuffer("K"));
  2164. }
  2165. };
  2166. CPPUNIT_TEST_SUITE_REGISTRATION( SegmentMonitorTest );
  2167. CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( SegmentMonitorTest, "SegmentMonitorTest" );
  2168. #endif