SparseBitVector.h 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #pragma once
  6. typedef BVUnit64 SparseBVUnit;
  7. #define FOREACH_BITSET_IN_SPARSEBV(index, bv) \
  8. { \
  9. BVIndex index; \
  10. for(auto * _curNode = (bv)->head; _curNode != 0 ; _curNode = _curNode->next) \
  11. { \
  12. BVIndex _offset; \
  13. BVIndex _startIndex = _curNode->startIndex; \
  14. SparseBVUnit _unit = _curNode->data; \
  15. for(_offset = _unit.GetNextBit(); _offset != BVInvalidIndex; _offset = _unit.GetNextBit()) \
  16. { \
  17. index = _startIndex + _offset; \
  18. _unit.Clear(_offset); \
  19. \
  20. #define BREAK_BITSET_IN_SPARSEBV \
  21. _curNode = 0; \
  22. break;
  23. #define NEXT_BITSET_IN_SPARSEBV \
  24. } \
  25. if(_curNode == 0) \
  26. { \
  27. break; \
  28. } \
  29. } \
  30. }
  31. #define FOREACH_BITSET_IN_SPARSEBV_EDITING(index, bv) \
  32. { \
  33. BVIndex index; \
  34. auto * _curNodeEdit = (bv)->head; \
  35. while (_curNodeEdit != nullptr) \
  36. { \
  37. auto * _next = _curNodeEdit->next; \
  38. BVIndex _offset; \
  39. BVIndex _startIndex = _curNodeEdit->startIndex; \
  40. SparseBVUnit _unit = _curNodeEdit->data; \
  41. for(_offset = _unit.GetNextBit(); _offset != BVInvalidIndex; _offset = _unit.GetNextBit()) \
  42. { \
  43. index = _startIndex + _offset; \
  44. _unit.Clear(_offset); \
  45. \
  46. #define NEXT_BITSET_IN_SPARSEBV_EDITING \
  47. } \
  48. _curNodeEdit = _next; \
  49. } \
  50. }
  51. #define SPARSEBV_CLEAR_CURRENT_BIT() _curNodeEdit->data.Clear(_offset)
  52. template <class TAllocator>
  53. struct BVSparseNode
  54. {
  55. Field(BVSparseNode*, TAllocator) next;
  56. Field(BVIndex) startIndex;
  57. Field(SparseBVUnit) data;
  58. BVSparseNode(BVIndex beginIndex, BVSparseNode * nextNode);
  59. void init(BVIndex beginIndex, BVSparseNode * nextNode);
  60. // Needed for the NatVis Extension for visualizing BitVectors
  61. // in Visual Studio
  62. #ifdef _WIN32
  63. bool ToString(
  64. __out_ecount(strSize) char *const str,
  65. const size_t strSize,
  66. size_t *const writtenLengthRef = nullptr,
  67. const bool isInSequence = false,
  68. const bool isFirstInSequence = false,
  69. const bool isLastInSequence = false) const;
  70. #endif
  71. };
  72. template <class TAllocator>
  73. class BVSparse
  74. {
  75. typedef BVSparseNode<TAllocator> BVSparseNode;
  76. // Data
  77. public:
  78. Field(BVSparseNode*, TAllocator) head;
  79. Field(BVSparseNode*, TAllocator) lastFoundIndex;
  80. private:
  81. FieldNoBarrier(TAllocator*) alloc;
  82. Field(Field(BVSparseNode*, TAllocator)*, TAllocator) lastUsedNodePrevNextField;
  83. static const SparseBVUnit s_EmptyUnit;
  84. // Constructor
  85. public:
  86. BVSparse(TAllocator* allocator);
  87. ~BVSparse();
  88. // Implementation
  89. protected:
  90. template <class TOtherAllocator>
  91. static void AssertBV(const BVSparse<TOtherAllocator> * bv);
  92. SparseBVUnit * BitsFromIndex(BVIndex i, bool create = true);
  93. const SparseBVUnit * BitsFromIndex(BVIndex i) const;
  94. BVSparseNode* NodeFromIndex(BVIndex i, Field(BVSparseNode*, TAllocator)** prevNextFieldOut,
  95. bool create = true);
  96. const BVSparseNode* NodeFromIndex(BVIndex i, Field(BVSparseNode*, TAllocator) const** prevNextFieldOut) const;
  97. BVSparseNode * DeleteNode(BVSparseNode *node, bool bResetLastUsed = true);
  98. void QueueInFreeList(BVSparseNode* node);
  99. BVSparseNode * Allocate(const BVIndex searchIndex, BVSparseNode *prevNode);
  100. template<void (SparseBVUnit::*callback)(SparseBVUnit)>
  101. void for_each(const BVSparse<TAllocator> *bv2);
  102. template<void (SparseBVUnit::*callback)(SparseBVUnit)>
  103. void for_each(const BVSparse<TAllocator> *bv1, const BVSparse<TAllocator> *bv2);
  104. // Methods
  105. public:
  106. BOOLEAN operator[](BVIndex i) const;
  107. BOOLEAN Test(BVIndex i) const;
  108. BVIndex GetNextBit(BVIndex i) const;
  109. BVIndex GetNextBit(BVSparseNode * node) const;
  110. BOOLEAN TestEmpty() const;
  111. BOOLEAN TestAndSet(BVIndex i);
  112. BOOLEAN TestAndClear(BVIndex i);
  113. void Set(BVIndex i);
  114. void Clear(BVIndex i);
  115. void Compliment(BVIndex i);
  116. // this |= bv;
  117. void Or(const BVSparse<TAllocator> *bv);
  118. // this = bv1 | bv2;
  119. void Or(const BVSparse<TAllocator> *bv1, const BVSparse<TAllocator> *bv2);
  120. // newBv = this | bv;
  121. BVSparse<TAllocator> * OrNew(const BVSparse<TAllocator> *bv, TAllocator* allocator) const;
  122. BVSparse<TAllocator> * OrNew(const BVSparse<TAllocator> *bv) const { return this->OrNew(bv, this->alloc); }
  123. // this &= bv;
  124. void And(const BVSparse<TAllocator> *bv);
  125. // this = bv1 & bv2;
  126. void And(const BVSparse<TAllocator> *bv1, const BVSparse<TAllocator> *bv2);
  127. // newBv = this & bv;
  128. BVSparse<TAllocator> * AndNew(const BVSparse<TAllocator> *bv, TAllocator* allocator) const;
  129. BVSparse<TAllocator> * AndNew(const BVSparse<TAllocator> *bv) const { return this->AndNew(bv, this->alloc); }
  130. // this ^= bv;
  131. void Xor(const BVSparse<TAllocator> *bv);
  132. // this = bv1 ^ bv2;
  133. void Xor(const BVSparse<TAllocator> *bv1, const BVSparse<TAllocator> *bv2);
  134. // newBv = this ^ bv;
  135. BVSparse<TAllocator> * XorNew(const BVSparse<TAllocator> *bv, TAllocator* allocator) const;
  136. BVSparse<TAllocator> * XorNew(const BVSparse<TAllocator> *bv) const { return this->XorNew(bv, this->alloc); }
  137. // this -= bv;
  138. void Minus(const BVSparse<TAllocator> *bv);
  139. // this = bv1 - bv2;
  140. void Minus(const BVSparse<TAllocator> *bv1, const BVSparse<TAllocator> *bv2);
  141. // newBv = this - bv;
  142. BVSparse<TAllocator> * MinusNew(const BVSparse<TAllocator> *bv, TAllocator* allocator) const;
  143. BVSparse<TAllocator> * MinusNew(const BVSparse<TAllocator> *bv) const { return this->MinusNew(bv, this->alloc); }
  144. template <class TSrcAllocator>
  145. void Copy(const BVSparse<TSrcAllocator> *bv);
  146. template <class TSrcAllocator>
  147. void CopyFromNode(const ::BVSparseNode<TSrcAllocator> * node2);
  148. BVSparse<TAllocator> * CopyNew(TAllocator* allocator) const;
  149. BVSparse<TAllocator> * CopyNew() const;
  150. void ComplimentAll();
  151. void ClearAll();
  152. BVIndex Count() const;
  153. bool IsEmpty() const;
  154. bool Equal(BVSparse<TAllocator> const * bv) const;
  155. // this & bv != empty
  156. bool Test(BVSparse const * bv) const;
  157. // Needed for the VS NatVis Extension
  158. #ifdef _WIN32
  159. void ToString(__out_ecount(strSize) char *const str, const size_t strSize) const;
  160. template<class F> void ToString(__out_ecount(strSize) char *const str, const size_t strSize, const F ReadNode) const;
  161. #endif
  162. TAllocator * GetAllocator() const { return alloc; }
  163. #if DBG_DUMP
  164. void Dump() const;
  165. #endif
  166. };
  167. template <class TAllocator>
  168. BVSparseNode<TAllocator>::BVSparseNode(BVIndex beginIndex, BVSparseNode<TAllocator> * nextNode) :
  169. startIndex(beginIndex),
  170. data(0),
  171. next(nextNode)
  172. {
  173. // Performance assert, BVSparseNode is heavily used in the backend, do perf
  174. // measurement before changing this.
  175. #if defined(TARGET_64)
  176. CompileAssert(sizeof(BVSparseNode) == 24);
  177. #else
  178. CompileAssert(sizeof(BVSparseNode) == 16);
  179. #endif
  180. }
  181. template <class TAllocator>
  182. void BVSparseNode<TAllocator>::init(BVIndex beginIndex, BVSparseNode<TAllocator> * nextNode)
  183. {
  184. this->startIndex = beginIndex;
  185. this->data = 0;
  186. this->next = nextNode;
  187. }
  188. #ifdef _WIN32
  189. template <class TAllocator>
  190. bool BVSparseNode<TAllocator>::ToString(
  191. __out_ecount(strSize) char *const str,
  192. const size_t strSize,
  193. size_t *const writtenLengthRef,
  194. const bool isInSequence,
  195. const bool isFirstInSequence,
  196. const bool isLastInSequence) const
  197. {
  198. Assert(str);
  199. Assert(!isFirstInSequence || isInSequence);
  200. Assert(!isLastInSequence || isInSequence);
  201. if (strSize == 0)
  202. {
  203. if (writtenLengthRef)
  204. {
  205. *writtenLengthRef = 0;
  206. }
  207. return false;
  208. }
  209. str[0] = '\0';
  210. const size_t reservedLength = _countof(", ...}");
  211. if (strSize <= reservedLength)
  212. {
  213. if (writtenLengthRef)
  214. {
  215. *writtenLengthRef = 0;
  216. }
  217. return false;
  218. }
  219. size_t length = 0;
  220. if (!isInSequence || isFirstInSequence)
  221. {
  222. str[length++] = '{';
  223. }
  224. bool insertComma = isInSequence && !isFirstInSequence;
  225. char tempStr[13];
  226. for (BVIndex i = data.GetNextBit(); i != BVInvalidIndex; i = data.GetNextBit(i + 1))
  227. {
  228. const size_t copyLength = sprintf_s(tempStr, insertComma ? ", %u" : "%u", startIndex + i);
  229. Assert(static_cast<int>(copyLength) > 0);
  230. Assert(strSize > length);
  231. Assert(strSize - length > reservedLength);
  232. if (strSize - length - reservedLength <= copyLength)
  233. {
  234. strcpy_s(&str[length], strSize - length, insertComma ? ", ...}" : "...}");
  235. if (writtenLengthRef)
  236. {
  237. *writtenLengthRef = length + (insertComma ? _countof(", ...}") : _countof("...}"));
  238. }
  239. return false;
  240. }
  241. strcpy_s(&str[length], strSize - length - reservedLength, tempStr);
  242. length += copyLength;
  243. insertComma = true;
  244. }
  245. if (!isInSequence || isLastInSequence)
  246. {
  247. Assert(_countof("}") < strSize - length);
  248. strcpy_s(&str[length], strSize - length, "}");
  249. length += _countof("}");
  250. }
  251. if (writtenLengthRef)
  252. {
  253. *writtenLengthRef = length;
  254. }
  255. return true;
  256. }
  257. #endif
  258. #if DBG_DUMP
  259. template <typename T> void Dump(T const& t);
  260. namespace Memory{ class JitArenaAllocator; }
  261. template<>
  262. inline void Dump(BVSparse<JitArenaAllocator> * const& bv)
  263. {
  264. bv->Dump();
  265. }
  266. namespace Memory { class Recycler; }
  267. template<>
  268. inline void Dump(BVSparse<Recycler> * const& bv)
  269. {
  270. bv->Dump();
  271. }
  272. #endif
  273. template <class TAllocator>
  274. const SparseBVUnit BVSparse<TAllocator>::s_EmptyUnit(0);
  275. template <class TAllocator>
  276. BVSparse<TAllocator>::BVSparse(TAllocator* allocator) :
  277. alloc(allocator),
  278. head(nullptr),
  279. lastFoundIndex(nullptr)
  280. {
  281. this->lastUsedNodePrevNextField = &this->head;
  282. }
  283. template <class TAllocator>
  284. void
  285. BVSparse<TAllocator>::QueueInFreeList(BVSparseNode *curNode)
  286. {
  287. AllocatorDelete(TAllocator, this->alloc, curNode);
  288. }
  289. template <class TAllocator>
  290. BVSparseNode<TAllocator> *
  291. BVSparse<TAllocator>::Allocate(const BVIndex searchIndex, BVSparseNode *nextNode)
  292. {
  293. return AllocatorNew(TAllocator, this->alloc, BVSparseNode, searchIndex, nextNode);
  294. }
  295. template <class TAllocator>
  296. BVSparse<TAllocator>::~BVSparse()
  297. {
  298. BVSparseNode * curNode = this->head;
  299. while (curNode != nullptr)
  300. {
  301. curNode = this->DeleteNode(curNode);
  302. }
  303. }
  304. // Searches for a node which would contain the required bit. If not found, then it inserts
  305. // a new node in the appropriate position.
  306. //
  307. template <class TAllocator>
  308. BVSparseNode<TAllocator> *
  309. BVSparse<TAllocator>::NodeFromIndex(BVIndex i, Field(BVSparseNode*, TAllocator)** prevNextFieldOut, bool create)
  310. {
  311. const BVIndex searchIndex = SparseBVUnit::Floor(i);
  312. Field(BVSparseNode*, TAllocator)* prevNextField = this->lastUsedNodePrevNextField;
  313. BVSparseNode* curNode = *prevNextField;
  314. if (curNode != nullptr)
  315. {
  316. if (curNode->startIndex == searchIndex)
  317. {
  318. *prevNextFieldOut = prevNextField;
  319. return curNode;
  320. }
  321. if (curNode->startIndex > searchIndex)
  322. {
  323. prevNextField = &this->head;
  324. curNode = this->head;
  325. }
  326. }
  327. else
  328. {
  329. prevNextField = &this->head;
  330. curNode = this->head;
  331. }
  332. for (; curNode && searchIndex > curNode->startIndex; curNode = curNode->next)
  333. {
  334. prevNextField = &curNode->next;
  335. }
  336. if(curNode && searchIndex == curNode->startIndex)
  337. {
  338. *prevNextFieldOut = prevNextField;
  339. this->lastUsedNodePrevNextField = prevNextField;
  340. return curNode;
  341. }
  342. if(!create)
  343. {
  344. return nullptr;
  345. }
  346. BVSparseNode * newNode = Allocate(searchIndex, *prevNextField);
  347. *prevNextField = newNode;
  348. *prevNextFieldOut = prevNextField;
  349. this->lastUsedNodePrevNextField = prevNextField;
  350. return newNode;
  351. }
  352. template <class TAllocator>
  353. const BVSparseNode<TAllocator> *
  354. BVSparse<TAllocator>::NodeFromIndex(BVIndex i, Field(BVSparseNode*, TAllocator) const** prevNextFieldOut) const
  355. {
  356. const BVIndex searchIndex = SparseBVUnit::Floor(i);
  357. Field(BVSparseNode*, TAllocator) const* prevNextField = &this->head;
  358. Field(BVSparseNode*, TAllocator) const* prevLastField = &this->lastFoundIndex;
  359. const BVSparseNode * curNode = *prevNextField,
  360. * lastNode = *prevLastField;
  361. if (curNode != nullptr)
  362. {
  363. if (curNode->startIndex == searchIndex)
  364. {
  365. *prevNextFieldOut = prevNextField;
  366. return curNode;
  367. }
  368. if (lastNode && lastNode->startIndex != curNode->startIndex)
  369. {
  370. if (lastNode->startIndex == searchIndex)
  371. {
  372. *prevNextFieldOut = prevLastField;
  373. return lastNode;
  374. }
  375. if (lastNode->startIndex < searchIndex)
  376. {
  377. prevNextField = &this->lastFoundIndex;
  378. curNode = this->lastFoundIndex;
  379. }
  380. }
  381. if (curNode->startIndex > searchIndex)
  382. {
  383. prevNextField = &this->head;
  384. curNode = this->head;
  385. }
  386. }
  387. else
  388. {
  389. prevNextField = &this->head;
  390. curNode = this->head;
  391. }
  392. for (; curNode && searchIndex > curNode->startIndex; curNode = curNode->next)
  393. {
  394. prevNextField = &curNode->next;
  395. }
  396. const_cast<BVSparse<TAllocator>*>(this)->lastFoundIndex = *prevNextField;
  397. if (curNode && searchIndex == curNode->startIndex)
  398. {
  399. *prevNextFieldOut = prevNextField;
  400. return curNode;
  401. }
  402. return nullptr;
  403. }
  404. template <class TAllocator>
  405. SparseBVUnit *
  406. BVSparse<TAllocator>::BitsFromIndex(BVIndex i, bool create)
  407. {
  408. Field(BVSparseNode*, TAllocator)* prevNextField = nullptr;
  409. BVSparseNode * node = NodeFromIndex(i, &prevNextField, create);
  410. if (node)
  411. {
  412. return &node->data;
  413. }
  414. else
  415. {
  416. return (SparseBVUnit *)&BVSparse::s_EmptyUnit;
  417. }
  418. }
  419. template <class TAllocator>
  420. const SparseBVUnit *
  421. BVSparse<TAllocator>::BitsFromIndex(BVIndex i) const
  422. {
  423. Field(BVSparseNode*, TAllocator) const* prevNextField = nullptr;
  424. const BVSparseNode * node = NodeFromIndex(i, &prevNextField);
  425. if (node)
  426. {
  427. return &node->data;
  428. }
  429. else
  430. {
  431. return (SparseBVUnit *)&BVSparse::s_EmptyUnit;
  432. }
  433. }
  434. template <class TAllocator>
  435. BVSparseNode<TAllocator> *
  436. BVSparse<TAllocator>::DeleteNode(BVSparseNode *node, bool bResetLastUsed)
  437. {
  438. this->lastFoundIndex = nullptr;
  439. BVSparseNode *next = node->next;
  440. QueueInFreeList(node);
  441. if (bResetLastUsed)
  442. {
  443. this->lastUsedNodePrevNextField = &this->head;
  444. }
  445. else
  446. {
  447. Assert(this->lastUsedNodePrevNextField != &node->next);
  448. }
  449. return next;
  450. }
  451. template <class TAllocator>
  452. BVIndex
  453. BVSparse<TAllocator>::GetNextBit(BVSparseNode *node) const
  454. {
  455. while(0 != node)
  456. {
  457. BVIndex ret = node->data.GetNextBit();
  458. if(BVInvalidIndex != ret)
  459. {
  460. return ret + node->startIndex;
  461. }
  462. }
  463. return BVInvalidIndex;
  464. }
  465. template <class TAllocator>
  466. BVIndex
  467. BVSparse<TAllocator>::GetNextBit(BVIndex i) const
  468. {
  469. const BVIndex startIndex = SparseBVUnit::Floor(i);
  470. for(BVSparseNode * node = this->head; node != 0 ; node = node->next)
  471. {
  472. if(startIndex == node->startIndex)
  473. {
  474. BVIndex ret = node->data.GetNextBit(SparseBVUnit::Offset(i));
  475. if(BVInvalidIndex != ret)
  476. {
  477. return ret + node->startIndex;
  478. }
  479. else
  480. {
  481. return GetNextBit(node->next);
  482. }
  483. }
  484. else if(startIndex < node->startIndex)
  485. {
  486. return GetNextBit(node->next);
  487. }
  488. }
  489. return BVInvalidIndex;
  490. }
  491. template <class TAllocator>
  492. template <class TOtherAllocator>
  493. void
  494. BVSparse<TAllocator>::AssertBV(const BVSparse<TOtherAllocator> *bv)
  495. {
  496. AssertMsg(nullptr != bv, "Cannot operate on NULL bitvector");
  497. }
  498. template <class TAllocator>
  499. void
  500. BVSparse<TAllocator>::ClearAll()
  501. {
  502. BVSparseNode* nextNode;
  503. for(BVSparseNode * node = this->head; node != 0 ; node = nextNode)
  504. {
  505. nextNode = node->next;
  506. QueueInFreeList(node);
  507. }
  508. this->head = nullptr;
  509. this->lastFoundIndex = nullptr;
  510. this->lastUsedNodePrevNextField = &this->head;
  511. }
  512. template <class TAllocator>
  513. void
  514. BVSparse<TAllocator>::Set(BVIndex i)
  515. {
  516. this->BitsFromIndex(i)->Set(SparseBVUnit::Offset(i));
  517. }
  518. template <class TAllocator>
  519. void
  520. BVSparse<TAllocator>::Clear(BVIndex i)
  521. {
  522. Field(BVSparseNode*, TAllocator)* prevNextField = nullptr;
  523. BVSparseNode * current = this->NodeFromIndex(i, &prevNextField, false /* create */);
  524. if(current)
  525. {
  526. current->data.Clear(SparseBVUnit::Offset(i));
  527. if (current->data.IsEmpty())
  528. {
  529. *prevNextField = this->DeleteNode(current, false);
  530. }
  531. }
  532. }
  533. template <class TAllocator>
  534. void
  535. BVSparse<TAllocator>::Compliment(BVIndex i)
  536. {
  537. this->BitsFromIndex(i)->Complement(SparseBVUnit::Offset(i));
  538. }
  539. template <class TAllocator>
  540. BOOLEAN
  541. BVSparse<TAllocator>::TestEmpty() const
  542. {
  543. return this->head != nullptr;
  544. }
  545. template <class TAllocator>
  546. BOOLEAN
  547. BVSparse<TAllocator>::Test(BVIndex i) const
  548. {
  549. return this->BitsFromIndex(i)->Test(SparseBVUnit::Offset(i));
  550. }
  551. template <class TAllocator>
  552. BOOLEAN
  553. BVSparse<TAllocator>::TestAndSet(BVIndex i)
  554. {
  555. SparseBVUnit * bvUnit = this->BitsFromIndex(i);
  556. BVIndex bvIndex = SparseBVUnit::Offset(i);
  557. BOOLEAN bit = bvUnit->Test(bvIndex);
  558. bvUnit->Set(bvIndex);
  559. return bit;
  560. }
  561. template <class TAllocator>
  562. BOOLEAN
  563. BVSparse<TAllocator>::TestAndClear(BVIndex i)
  564. {
  565. Field(BVSparseNode*, TAllocator)* prevNextField = nullptr;
  566. BVSparseNode * current = this->NodeFromIndex(i, &prevNextField, false /* create */);
  567. if (current == nullptr)
  568. {
  569. return false;
  570. }
  571. BVIndex bvIndex = SparseBVUnit::Offset(i);
  572. BOOLEAN bit = current->data.Test(bvIndex);
  573. current->data.Clear(bvIndex);
  574. if (current->data.IsEmpty())
  575. {
  576. *prevNextField = this->DeleteNode(current, false);
  577. }
  578. return bit;
  579. }
  580. template <class TAllocator>
  581. BOOLEAN
  582. BVSparse<TAllocator>::operator[](BVIndex i) const
  583. {
  584. return this->Test(i);
  585. }
  586. template<class TAllocator>
  587. template<void (SparseBVUnit::*callback)(SparseBVUnit)>
  588. void BVSparse<TAllocator>::for_each(const BVSparse *bv2)
  589. {
  590. Assert(callback == &SparseBVUnit::And || callback == &SparseBVUnit::Or || callback == &SparseBVUnit::Xor || callback == &SparseBVUnit::Minus);
  591. AssertBV(bv2);
  592. BVSparseNode * node1 = this->head;
  593. const BVSparseNode * node2 = bv2->head;
  594. Field(BVSparseNode*, TAllocator)* prevNodeNextField = &this->head;
  595. while(node1 != nullptr && node2 != nullptr)
  596. {
  597. if(node2->startIndex == node1->startIndex)
  598. {
  599. (node1->data.*callback)(node2->data);
  600. prevNodeNextField = &node1->next;
  601. node1 = node1->next;
  602. node2 = node2->next;
  603. }
  604. else if(node2->startIndex > node1->startIndex)
  605. {
  606. if (callback == &SparseBVUnit::And)
  607. {
  608. node1 = this->DeleteNode(node1);
  609. *prevNodeNextField = node1;
  610. }
  611. else
  612. {
  613. prevNodeNextField = &node1->next;
  614. node1 = node1->next;
  615. }
  616. }
  617. else
  618. {
  619. if (callback == &SparseBVUnit::Or || callback == &SparseBVUnit::Xor)
  620. {
  621. BVSparseNode * newNode = Allocate(node2->startIndex, node1);
  622. (newNode->data.*callback)(node2->data);
  623. *prevNodeNextField = newNode;
  624. prevNodeNextField = &newNode->next;
  625. }
  626. node2 = node2->next;
  627. }
  628. }
  629. if (callback == &SparseBVUnit::And)
  630. {
  631. while (node1 != nullptr)
  632. {
  633. node1 = this->DeleteNode(node1);
  634. }
  635. *prevNodeNextField = nullptr;
  636. }
  637. else if (callback == &SparseBVUnit::Or || callback == &SparseBVUnit::Xor)
  638. {
  639. while(node2 != 0)
  640. {
  641. Assert(*prevNodeNextField == nullptr);
  642. BVSparseNode * newNode = Allocate(node2->startIndex, nullptr);
  643. *prevNodeNextField = newNode;
  644. (newNode->data.*callback)(node2->data);
  645. node2 = node2->next;
  646. prevNodeNextField = &newNode->next;
  647. }
  648. }
  649. }
  650. template<class TAllocator>
  651. template<void (SparseBVUnit::*callback)(SparseBVUnit)>
  652. void BVSparse<TAllocator>::for_each(const BVSparse *bv1, const BVSparse *bv2)
  653. {
  654. Assert(callback == &SparseBVUnit::And || callback == &SparseBVUnit::Or || callback == &SparseBVUnit::Xor || callback == &SparseBVUnit::Minus);
  655. Assert(this->IsEmpty());
  656. AssertBV(bv1);
  657. AssertBV(bv2);
  658. BVSparseNode * node1 = bv1->head;
  659. const BVSparseNode * node2 = bv2->head;
  660. BVSparseNode * lastNode = nullptr;
  661. Field(BVSparseNode*, TAllocator)* prevNextField = &this->head;
  662. while(node1 != nullptr && node2 != nullptr)
  663. {
  664. lastNode = node1;
  665. BVIndex startIndex;
  666. SparseBVUnit bvUnit1;
  667. SparseBVUnit bvUnit2;
  668. if (node2->startIndex == node1->startIndex)
  669. {
  670. startIndex = node1->startIndex;
  671. bvUnit1 = node1->data;
  672. bvUnit2 = node2->data;
  673. node1 = node1->next;
  674. node2 = node2->next;
  675. }
  676. else if (node2->startIndex > node1->startIndex)
  677. {
  678. startIndex = node1->startIndex;
  679. bvUnit1 = node1->data;
  680. node1 = node1->next;
  681. }
  682. else
  683. {
  684. startIndex = node2->startIndex;
  685. bvUnit2 = node2->data;
  686. node2 = node2->next;
  687. }
  688. (bvUnit1.*callback)(bvUnit2);
  689. if (!bvUnit1.IsEmpty())
  690. {
  691. BVSparseNode * newNode = Allocate(startIndex, nullptr);
  692. newNode->data = bvUnit1;
  693. *prevNextField = newNode;
  694. prevNextField = &newNode->next;
  695. }
  696. }
  697. if (callback == &SparseBVUnit::Minus || callback == &SparseBVUnit::Or || callback == &SparseBVUnit::Xor)
  698. {
  699. BVSparseNode const * copyNode = (callback == &SparseBVUnit::Minus || node1 != nullptr)? node1 : node2;
  700. while (copyNode != nullptr)
  701. {
  702. if (!copyNode->data.IsEmpty())
  703. {
  704. BVSparseNode * newNode = Allocate(copyNode->startIndex, nullptr);
  705. newNode->data = copyNode->data;
  706. *prevNextField = newNode;
  707. prevNextField = &newNode->next;
  708. }
  709. copyNode = copyNode->next;
  710. }
  711. }
  712. }
  713. template <class TAllocator>
  714. void
  715. BVSparse<TAllocator>::Or(const BVSparse*bv)
  716. {
  717. this->for_each<&SparseBVUnit::Or>(bv);
  718. }
  719. template <class TAllocator>
  720. void
  721. BVSparse<TAllocator>::Or(const BVSparse * bv1, const BVSparse * bv2)
  722. {
  723. this->ClearAll();
  724. this->for_each<&SparseBVUnit::Or>(bv1, bv2);
  725. }
  726. template <class TAllocator>
  727. BVSparse<TAllocator> *
  728. BVSparse<TAllocator>::OrNew(const BVSparse* bv, TAllocator* allocator) const
  729. {
  730. BVSparse * newBv = AllocatorNew(TAllocator, allocator, BVSparse, allocator);
  731. newBv->for_each<&SparseBVUnit::Or>(this, bv);
  732. return newBv;
  733. }
  734. template <class TAllocator>
  735. void
  736. BVSparse<TAllocator>::And(const BVSparse*bv)
  737. {
  738. this->for_each<&SparseBVUnit::And>(bv);
  739. }
  740. template <class TAllocator>
  741. void
  742. BVSparse<TAllocator>::And(const BVSparse * bv1, const BVSparse * bv2)
  743. {
  744. this->ClearAll();
  745. this->for_each<&SparseBVUnit::And>(bv1, bv2);
  746. }
  747. template <class TAllocator>
  748. BVSparse<TAllocator> *
  749. BVSparse<TAllocator>::AndNew(const BVSparse* bv, TAllocator* allocator) const
  750. {
  751. BVSparse * newBv = AllocatorNew(TAllocator, allocator, BVSparse, allocator);
  752. newBv->for_each<&SparseBVUnit::And>(this, bv);
  753. return newBv;
  754. }
  755. template <class TAllocator>
  756. void
  757. BVSparse<TAllocator>::Xor(const BVSparse*bv)
  758. {
  759. this->for_each<&SparseBVUnit::Xor>(bv);
  760. }
  761. template <class TAllocator>
  762. void
  763. BVSparse<TAllocator>::Xor(const BVSparse * bv1, const BVSparse * bv2)
  764. {
  765. this->ClearAll();
  766. this->for_each<&SparseBVUnit::Xor>(bv1, bv2);
  767. }
  768. template <class TAllocator>
  769. BVSparse<TAllocator> *
  770. BVSparse<TAllocator>::XorNew(const BVSparse* bv, TAllocator* allocator) const
  771. {
  772. BVSparse * newBv = AllocatorNew(TAllocator, allocator, BVSparse, allocator);
  773. newBv->for_each<&SparseBVUnit::Xor>(this, bv);
  774. return newBv;
  775. }
  776. template <class TAllocator>
  777. void
  778. BVSparse<TAllocator>::Minus(const BVSparse*bv)
  779. {
  780. this->for_each<&SparseBVUnit::Minus>(bv);
  781. }
  782. template <class TAllocator>
  783. void
  784. BVSparse<TAllocator>::Minus(const BVSparse * bv1, const BVSparse * bv2)
  785. {
  786. this->ClearAll();
  787. this->for_each<&SparseBVUnit::Minus>(bv1, bv2);
  788. }
  789. template <class TAllocator>
  790. BVSparse<TAllocator> *
  791. BVSparse<TAllocator>::MinusNew(const BVSparse* bv, TAllocator* allocator) const
  792. {
  793. BVSparse * newBv = AllocatorNew(TAllocator, allocator, BVSparse, allocator);
  794. newBv->for_each<&SparseBVUnit::Minus>(this, bv);
  795. return newBv;
  796. }
  797. template <class TAllocator>
  798. template <class TSrcAllocator>
  799. void
  800. BVSparse<TAllocator>::Copy(const BVSparse<TSrcAllocator> * bv2)
  801. {
  802. AssertBV(bv2);
  803. CopyFromNode(bv2->head);
  804. }
  805. template <class TAllocator>
  806. template <class TSrcAllocator>
  807. void
  808. BVSparse<TAllocator>::CopyFromNode(const ::BVSparseNode<TSrcAllocator> * node2)
  809. {
  810. BVSparseNode * node1 = this->head;
  811. Field(BVSparseNode*, TAllocator)* prevNextField = &this->head;
  812. this->lastFoundIndex = nullptr;
  813. while (node1 != nullptr && node2 != nullptr)
  814. {
  815. if (!node2->data.IsEmpty())
  816. {
  817. node1->startIndex = node2->startIndex;
  818. node1->data.Copy(node2->data);
  819. prevNextField = &node1->next;
  820. node1 = node1->next;
  821. }
  822. node2 = node2->next;
  823. }
  824. if (node1 != nullptr)
  825. {
  826. while (node1 != nullptr)
  827. {
  828. node1 = this->DeleteNode(node1);
  829. }
  830. *prevNextField = nullptr;
  831. }
  832. else
  833. {
  834. while (node2 != nullptr)
  835. {
  836. if (!node2->data.IsEmpty())
  837. {
  838. BVSparseNode * newNode = Allocate(node2->startIndex, nullptr);
  839. newNode->data.Copy(node2->data);
  840. *prevNextField = newNode;
  841. prevNextField = &newNode->next;
  842. }
  843. node2 = node2->next;
  844. }
  845. }
  846. }
  847. template <class TAllocator>
  848. BVSparse<TAllocator> *
  849. BVSparse<TAllocator>::CopyNew(TAllocator* allocator) const
  850. {
  851. BVSparse * bv = AllocatorNew(TAllocator, allocator, BVSparse<TAllocator>, allocator);
  852. bv->Copy(this);
  853. return bv;
  854. }
  855. template <class TAllocator>
  856. BVSparse<TAllocator> *
  857. BVSparse<TAllocator>::CopyNew() const
  858. {
  859. return this->CopyNew(this->alloc);
  860. }
  861. template <class TAllocator>
  862. void
  863. BVSparse<TAllocator>::ComplimentAll()
  864. {
  865. for(BVSparseNode * node = this->head; node != 0 ; node = node->next)
  866. {
  867. node->data.ComplimentAll();
  868. }
  869. }
  870. template <class TAllocator>
  871. BVIndex
  872. BVSparse<TAllocator>::Count() const
  873. {
  874. BVIndex sum = 0;
  875. for(BVSparseNode * node = this->head; node != 0 ; node = node->next)
  876. {
  877. sum += node->data.Count();
  878. }
  879. return sum;
  880. }
  881. template <class TAllocator>
  882. bool
  883. BVSparse<TAllocator>::IsEmpty() const
  884. {
  885. for(BVSparseNode * node = this->head; node != 0 ; node = node->next)
  886. {
  887. if (!node->data.IsEmpty())
  888. {
  889. return false;
  890. }
  891. }
  892. return true;
  893. }
  894. template <class TAllocator>
  895. bool
  896. BVSparse<TAllocator>::Equal(BVSparse const * bv) const
  897. {
  898. BVSparseNode const * bvNode1 = this->head;
  899. BVSparseNode const * bvNode2 = bv->head;
  900. while (true)
  901. {
  902. while (bvNode1 != nullptr && bvNode1->data.IsEmpty())
  903. {
  904. bvNode1 = bvNode1->next;
  905. }
  906. while (bvNode2 != nullptr && bvNode2->data.IsEmpty())
  907. {
  908. bvNode2 = bvNode2->next;
  909. }
  910. if (bvNode1 == nullptr)
  911. {
  912. return (bvNode2 == nullptr);
  913. }
  914. if (bvNode2 == nullptr)
  915. {
  916. return false;
  917. }
  918. if (bvNode1->startIndex != bvNode2->startIndex)
  919. {
  920. return false;
  921. }
  922. if (!bvNode1->data.Equal(bvNode2->data))
  923. {
  924. return false;
  925. }
  926. bvNode1 = bvNode1->next;
  927. bvNode2 = bvNode2->next;
  928. }
  929. }
  930. template <class TAllocator>
  931. bool
  932. BVSparse<TAllocator>::Test(BVSparse const * bv) const
  933. {
  934. BVSparseNode const * bvNode1 = this->head;
  935. BVSparseNode const * bvNode2 = bv->head;
  936. while (bvNode1 != nullptr && bvNode2 != nullptr)
  937. {
  938. if (bvNode1->data.IsEmpty() || bvNode1->startIndex < bvNode2->startIndex)
  939. {
  940. bvNode1 = bvNode1->next;
  941. continue;
  942. }
  943. if (bvNode2->data.IsEmpty() || bvNode1->startIndex > bvNode2->startIndex)
  944. {
  945. bvNode2 = bvNode2->next;
  946. continue;
  947. }
  948. Assert(bvNode1->startIndex == bvNode2->startIndex);
  949. if (bvNode1->data.Test(bvNode2->data))
  950. {
  951. return true;
  952. }
  953. bvNode1 = bvNode1->next;
  954. bvNode2 = bvNode2->next;
  955. }
  956. return false;
  957. }
  958. #ifdef _WIN32
  959. template<class TAllocator>
  960. template<class F>
  961. void BVSparse<TAllocator>::ToString(__out_ecount(strSize) char *const str, const size_t strSize, const F ReadNode) const
  962. {
  963. Assert(str);
  964. if (strSize == 0)
  965. {
  966. return;
  967. }
  968. str[0] = '\0';
  969. bool empty = true;
  970. bool isFirstInSequence = true;
  971. size_t length = 0;
  972. BVSparseNode *nodePtr = head;
  973. while (nodePtr)
  974. {
  975. bool readSuccess;
  976. const BVSparseNode node(ReadNode(nodePtr, &readSuccess));
  977. if (!readSuccess)
  978. {
  979. str[0] = '\0';
  980. return;
  981. }
  982. if (node.data.IsEmpty())
  983. {
  984. nodePtr = node.next;
  985. continue;
  986. }
  987. empty = false;
  988. size_t writtenLength;
  989. if (!node.ToString(&str[length], strSize - length, &writtenLength, true, isFirstInSequence, !node.next))
  990. {
  991. return;
  992. }
  993. length += writtenLength;
  994. isFirstInSequence = false;
  995. nodePtr = node.next;
  996. }
  997. if (empty && _countof("{}") < strSize)
  998. {
  999. strcpy_s(str, strSize, "{}");
  1000. }
  1001. }
  1002. template<class TAllocator>
  1003. void BVSparse<TAllocator>::ToString(__out_ecount(strSize) char *const str, const size_t strSize) const
  1004. {
  1005. ToString(
  1006. str,
  1007. strSize,
  1008. [](BVSparseNode *const nodePtr, bool *const successRef) -> BVSparseNode
  1009. {
  1010. Assert(nodePtr);
  1011. Assert(successRef);
  1012. *successRef = true;
  1013. return *nodePtr;
  1014. });
  1015. }
  1016. #endif
  1017. #if DBG_DUMP
  1018. template <class TAllocator>
  1019. void
  1020. BVSparse<TAllocator>::Dump() const
  1021. {
  1022. bool hasBits = false;
  1023. Output::Print(_u("[ "));
  1024. for(BVSparseNode * node = this->head; node != 0 ; node = node->next)
  1025. {
  1026. hasBits = node->data.Dump(node->startIndex, hasBits);
  1027. }
  1028. Output::Print(_u("]\n"));
  1029. }
  1030. #endif