rtlkey.cpp 71 KB

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