SparseBitVector.h 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901
  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. #if defined(_M_ARM64) || defined(_M_X64)
  7. typedef BVUnit32 SparseBVUnit;
  8. #else
  9. typedef BVUnit64 SparseBVUnit;
  10. #endif
  11. #define FOREACH_BITSET_IN_SPARSEBV(index, bv) \
  12. { \
  13. BVIndex index; \
  14. for(BVSparseNode * _curNode = (bv)->head; _curNode != 0 ; _curNode = _curNode->next) \
  15. { \
  16. BVIndex _offset; \
  17. BVIndex _startIndex = _curNode->startIndex; \
  18. SparseBVUnit _unit = _curNode->data; \
  19. for(_offset = _unit.GetNextBit(); _offset != -1; _offset = _unit.GetNextBit()) \
  20. { \
  21. index = _startIndex + _offset; \
  22. _unit.Clear(_offset); \
  23. \
  24. #define BREAK_BITSET_IN_SPARSEBV \
  25. _curNode = 0; \
  26. break;
  27. #define NEXT_BITSET_IN_SPARSEBV \
  28. } \
  29. if(_curNode == 0) \
  30. { \
  31. break; \
  32. } \
  33. } \
  34. }
  35. #define FOREACH_BITSET_IN_SPARSEBV_EDITING(index, bv) \
  36. { \
  37. BVIndex index; \
  38. BVSparseNode * _curNodeEdit = (bv)->head; \
  39. while (_curNodeEdit != nullptr) \
  40. { \
  41. BVSparseNode * _next = _curNodeEdit->next; \
  42. BVIndex _offset; \
  43. BVIndex _startIndex = _curNodeEdit->startIndex; \
  44. SparseBVUnit _unit = _curNodeEdit->data; \
  45. for(_offset = _unit.GetNextBit(); _offset != -1; _offset = _unit.GetNextBit()) \
  46. { \
  47. index = _startIndex + _offset; \
  48. _unit.Clear(_offset); \
  49. \
  50. #define NEXT_BITSET_IN_SPARSEBV_EDITING \
  51. } \
  52. _curNodeEdit = _next; \
  53. } \
  54. }
  55. #define SPARSEBV_CLEAR_CURRENT_BIT() _curNodeEdit->data.Clear(_offset)
  56. struct BVSparseNode
  57. {
  58. BVIndex startIndex;
  59. #if defined(_M_ARM64) || defined(_M_X64)
  60. //64-bit: the order is changed to make sure it fits in 16 bytes
  61. SparseBVUnit data;
  62. BVSparseNode * next;
  63. #else //_M_IX86 and _M_ARM32
  64. BVSparseNode * next;
  65. SparseBVUnit data;
  66. #endif
  67. BVSparseNode(BVIndex beginIndex, BVSparseNode * nextNode);
  68. void init(BVIndex beginIndex, BVSparseNode * nextNode);
  69. };
  70. // xplat-todo: revisit for unix
  71. #ifdef _WIN32
  72. CompileAssert(sizeof(BVSparseNode) == 16); // Performance assert, BVSparseNode is heavily used in the backend, do perf measurement before changing this.
  73. #endif
  74. template <class TAllocator>
  75. class BVSparse
  76. {
  77. // Data
  78. public:
  79. BVSparseNode * head;
  80. private:
  81. TAllocator * alloc;
  82. BVSparseNode ** 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. BVSparseNode* NodeFromIndex(BVIndex i, BVSparseNode *** prevNextFieldOut, bool create = true);
  94. BVSparseNode * DeleteNode(BVSparseNode *node, bool bResetLastUsed = true);
  95. void QueueInFreeList(BVSparseNode* node);
  96. BVSparseNode * Allocate(const BVIndex searchIndex, BVSparseNode *prevNode);
  97. template<void (SparseBVUnit::*callback)(SparseBVUnit)>
  98. void for_each(const BVSparse<TAllocator> *bv2);
  99. template<void (SparseBVUnit::*callback)(SparseBVUnit)>
  100. void for_each(const BVSparse<TAllocator> *bv1, const BVSparse<TAllocator> *bv2);
  101. // Methods
  102. public:
  103. BOOLEAN operator[](BVIndex i) const;
  104. BOOLEAN Test(BVIndex i);
  105. BVIndex GetNextBit(BVIndex i) const;
  106. BVIndex GetNextBit(BVSparseNode * node) const;
  107. BOOLEAN TestEmpty() const;
  108. BOOLEAN TestAndSet(BVIndex i);
  109. BOOLEAN TestAndClear(BVIndex i);
  110. void Set(BVIndex i);
  111. void Clear(BVIndex i);
  112. void Compliment(BVIndex i);
  113. // this |= bv;
  114. void Or(const BVSparse<TAllocator> *bv);
  115. // this = bv1 | bv2;
  116. void Or(const BVSparse<TAllocator> *bv1, const BVSparse<TAllocator> *bv2);
  117. // newBv = this | bv;
  118. BVSparse<TAllocator> * OrNew(const BVSparse<TAllocator> *bv, TAllocator* allocator) const;
  119. BVSparse<TAllocator> * OrNew(const BVSparse<TAllocator> *bv) const { return this->OrNew(bv, this->alloc); }
  120. // this &= bv;
  121. void And(const BVSparse<TAllocator> *bv);
  122. // this = bv1 & bv2;
  123. void And(const BVSparse<TAllocator> *bv1, const BVSparse<TAllocator> *bv2);
  124. // newBv = this & bv;
  125. BVSparse<TAllocator> * AndNew(const BVSparse<TAllocator> *bv, TAllocator* allocator) const;
  126. BVSparse<TAllocator> * AndNew(const BVSparse<TAllocator> *bv) const { return this->AndNew(bv, this->alloc); }
  127. // this ^= bv;
  128. void Xor(const BVSparse<TAllocator> *bv);
  129. // this = bv1 ^ bv2;
  130. void Xor(const BVSparse<TAllocator> *bv1, const BVSparse<TAllocator> *bv2);
  131. // newBv = this ^ bv;
  132. BVSparse<TAllocator> * XorNew(const BVSparse<TAllocator> *bv, TAllocator* allocator) const;
  133. BVSparse<TAllocator> * XorNew(const BVSparse<TAllocator> *bv) const { return this->XorNew(bv, this->alloc); }
  134. // this -= bv;
  135. void Minus(const BVSparse<TAllocator> *bv);
  136. // this = bv1 - bv2;
  137. void Minus(const BVSparse<TAllocator> *bv1, const BVSparse<TAllocator> *bv2);
  138. // newBv = this - bv;
  139. BVSparse<TAllocator> * MinusNew(const BVSparse<TAllocator> *bv, TAllocator* allocator) const;
  140. BVSparse<TAllocator> * MinusNew(const BVSparse<TAllocator> *bv) const { return this->MinusNew(bv, this->alloc); }
  141. template <class TSrcAllocator>
  142. void Copy(const BVSparse<TSrcAllocator> *bv);
  143. BVSparse<TAllocator> * CopyNew(TAllocator* allocator) const;
  144. BVSparse<TAllocator> * CopyNew() const;
  145. void ComplimentAll();
  146. void ClearAll();
  147. BVIndex Count() const;
  148. bool IsEmpty() const;
  149. bool Equal(BVSparse<TAllocator> const * bv) const;
  150. // this & bv != empty
  151. bool Test(BVSparse const * bv) const;
  152. TAllocator * GetAllocator() const { return alloc; }
  153. #if DBG_DUMP
  154. void Dump() const;
  155. #endif
  156. };
  157. #if DBG_DUMP
  158. template <typename T> void Dump(T const& t);
  159. namespace Memory{ class JitArenaAllocator; }
  160. template<>
  161. inline void Dump(BVSparse<JitArenaAllocator> * const& bv)
  162. {
  163. bv->Dump();
  164. }
  165. namespace Memory { class Recycler; }
  166. template<>
  167. inline void Dump(BVSparse<Recycler> * const& bv)
  168. {
  169. bv->Dump();
  170. }
  171. #endif
  172. template <class TAllocator>
  173. const SparseBVUnit BVSparse<TAllocator>::s_EmptyUnit(0);
  174. template <class TAllocator>
  175. BVSparse<TAllocator>::BVSparse(TAllocator* allocator) :
  176. alloc(allocator),
  177. head(nullptr)
  178. {
  179. this->lastUsedNodePrevNextField = &this->head;
  180. }
  181. template <class TAllocator>
  182. void
  183. BVSparse<TAllocator>::QueueInFreeList(BVSparseNode *curNode)
  184. {
  185. AllocatorDelete(TAllocator, this->alloc, curNode);
  186. }
  187. template <class TAllocator>
  188. BVSparseNode *
  189. BVSparse<TAllocator>::Allocate(const BVIndex searchIndex, BVSparseNode *nextNode)
  190. {
  191. return AllocatorNew(TAllocator, this->alloc, BVSparseNode, searchIndex, nextNode);
  192. }
  193. template <class TAllocator>
  194. BVSparse<TAllocator>::~BVSparse()
  195. {
  196. BVSparseNode * curNode = this->head;
  197. while (curNode != nullptr)
  198. {
  199. curNode = this->DeleteNode(curNode);
  200. }
  201. }
  202. // Searches for a node which would contain the required bit. If not found, then it inserts
  203. // a new node in the appropriate position.
  204. //
  205. template <class TAllocator>
  206. BVSparseNode *
  207. BVSparse<TAllocator>::NodeFromIndex(BVIndex i, BVSparseNode *** prevNextFieldOut, bool create)
  208. {
  209. const BVIndex searchIndex = SparseBVUnit::Floor(i);
  210. BVSparseNode ** prevNextField = this->lastUsedNodePrevNextField;
  211. BVSparseNode * curNode = (*prevNextField);
  212. if (curNode != nullptr)
  213. {
  214. if (curNode->startIndex == searchIndex)
  215. {
  216. *prevNextFieldOut = prevNextField;
  217. return curNode;
  218. }
  219. if (curNode->startIndex > searchIndex)
  220. {
  221. prevNextField = &this->head;
  222. curNode = this->head;
  223. }
  224. }
  225. else
  226. {
  227. prevNextField = &this->head;
  228. curNode = this->head;
  229. }
  230. for (; curNode && searchIndex > curNode->startIndex; curNode = curNode->next)
  231. {
  232. prevNextField = &curNode->next;
  233. }
  234. if(curNode && searchIndex == curNode->startIndex)
  235. {
  236. *prevNextFieldOut = prevNextField;
  237. this->lastUsedNodePrevNextField = prevNextField;
  238. return curNode;
  239. }
  240. if(!create)
  241. {
  242. return nullptr;
  243. }
  244. BVSparseNode * newNode = Allocate(searchIndex, *prevNextField);
  245. *prevNextField = newNode;
  246. *prevNextFieldOut = prevNextField;
  247. this->lastUsedNodePrevNextField = prevNextField;
  248. return newNode;
  249. }
  250. template <class TAllocator>
  251. SparseBVUnit *
  252. BVSparse<TAllocator>::BitsFromIndex(BVIndex i, bool create)
  253. {
  254. BVSparseNode ** prevNextField;
  255. BVSparseNode * node = NodeFromIndex(i, &prevNextField, create);
  256. if (node)
  257. {
  258. return &node->data;
  259. }
  260. else
  261. {
  262. return (SparseBVUnit *)&BVSparse::s_EmptyUnit;
  263. }
  264. }
  265. template <class TAllocator>
  266. BVSparseNode *
  267. BVSparse<TAllocator>::DeleteNode(BVSparseNode *node, bool bResetLastUsed)
  268. {
  269. BVSparseNode *next = node->next;
  270. QueueInFreeList(node);
  271. if (bResetLastUsed)
  272. {
  273. this->lastUsedNodePrevNextField = &this->head;
  274. }
  275. else
  276. {
  277. Assert(this->lastUsedNodePrevNextField != &node->next);
  278. }
  279. return next;
  280. }
  281. template <class TAllocator>
  282. BVIndex
  283. BVSparse<TAllocator>::GetNextBit(BVSparseNode *node) const
  284. {
  285. while(0 != node)
  286. {
  287. BVIndex ret = node->data.GetNextBit();
  288. if(-1 != ret)
  289. {
  290. return ret + node->startIndex;
  291. }
  292. }
  293. return -1;
  294. }
  295. template <class TAllocator>
  296. BVIndex
  297. BVSparse<TAllocator>::GetNextBit(BVIndex i) const
  298. {
  299. const BVIndex startIndex = SparseBVUnit::Floor(i);
  300. for(BVSparseNode * node = this->head; node != 0 ; node = node->next)
  301. {
  302. if(startIndex == node->startIndex)
  303. {
  304. BVIndex ret = node->data.GetNextBit(SparseBVUnit::Offset(i));
  305. if(-1 != ret)
  306. {
  307. return ret + node->startIndex;
  308. }
  309. else
  310. {
  311. return GetNextBit(node->next);
  312. }
  313. }
  314. else if(startIndex < node->startIndex)
  315. {
  316. return GetNextBit(node->next);
  317. }
  318. }
  319. return -1;
  320. }
  321. template <class TAllocator>
  322. template <class TOtherAllocator>
  323. void
  324. BVSparse<TAllocator>::AssertBV(const BVSparse<TOtherAllocator> *bv)
  325. {
  326. AssertMsg(nullptr != bv, "Cannot operate on NULL bitvector");
  327. }
  328. template <class TAllocator>
  329. void
  330. BVSparse<TAllocator>::ClearAll()
  331. {
  332. BVSparseNode* nextNode;
  333. for(BVSparseNode * node = this->head; node != 0 ; node = nextNode)
  334. {
  335. nextNode = node->next;
  336. QueueInFreeList(node);
  337. }
  338. this->head = nullptr;
  339. this->lastUsedNodePrevNextField = &this->head;
  340. }
  341. template <class TAllocator>
  342. void
  343. BVSparse<TAllocator>::Set(BVIndex i)
  344. {
  345. this->BitsFromIndex(i)->Set(SparseBVUnit::Offset(i));
  346. }
  347. template <class TAllocator>
  348. void
  349. BVSparse<TAllocator>::Clear(BVIndex i)
  350. {
  351. BVSparseNode ** prevNextField;
  352. BVSparseNode * current = this->NodeFromIndex(i, &prevNextField, false /* create */);
  353. if(current)
  354. {
  355. current->data.Clear(SparseBVUnit::Offset(i));
  356. if (current->data.IsEmpty())
  357. {
  358. *prevNextField = this->DeleteNode(current, false);
  359. }
  360. }
  361. }
  362. template <class TAllocator>
  363. void
  364. BVSparse<TAllocator>::Compliment(BVIndex i)
  365. {
  366. this->BitsFromIndex(i)->Complement(SparseBVUnit::Offset(i));
  367. }
  368. template <class TAllocator>
  369. BOOLEAN
  370. BVSparse<TAllocator>::TestEmpty() const
  371. {
  372. return this->head != nullptr;
  373. }
  374. template <class TAllocator>
  375. BOOLEAN
  376. BVSparse<TAllocator>::Test(BVIndex i)
  377. {
  378. return this->BitsFromIndex(i, false)->Test(SparseBVUnit::Offset(i));
  379. }
  380. template <class TAllocator>
  381. BOOLEAN
  382. BVSparse<TAllocator>::TestAndSet(BVIndex i)
  383. {
  384. SparseBVUnit * bvUnit = this->BitsFromIndex(i);
  385. BVIndex bvIndex = SparseBVUnit::Offset(i);
  386. BOOLEAN bit = bvUnit->Test(bvIndex);
  387. bvUnit->Set(bvIndex);
  388. return bit;
  389. }
  390. template <class TAllocator>
  391. BOOLEAN
  392. BVSparse<TAllocator>::TestAndClear(BVIndex i)
  393. {
  394. BVSparseNode ** prevNextField;
  395. BVSparseNode * current = this->NodeFromIndex(i, &prevNextField);
  396. BVIndex bvIndex = SparseBVUnit::Offset(i);
  397. BOOLEAN bit = current->data.Test(bvIndex);
  398. current->data.Clear(bvIndex);
  399. if (current->data.IsEmpty())
  400. {
  401. *prevNextField = this->DeleteNode(current, false);
  402. }
  403. return bit;
  404. }
  405. template <class TAllocator>
  406. BOOLEAN
  407. BVSparse<TAllocator>::operator[](BVIndex i) const
  408. {
  409. return this->Test(i);
  410. }
  411. template<class TAllocator>
  412. template<void (SparseBVUnit::*callback)(SparseBVUnit)>
  413. void BVSparse<TAllocator>::for_each(const BVSparse *bv2)
  414. {
  415. Assert(callback == &SparseBVUnit::And || callback == &SparseBVUnit::Or || callback == &SparseBVUnit::Xor || callback == &SparseBVUnit::Minus);
  416. AssertBV(bv2);
  417. BVSparseNode * node1 = this->head;
  418. const BVSparseNode * node2 = bv2->head;
  419. BVSparseNode ** prevNodeNextField = &this->head;
  420. while(node1 != nullptr && node2 != nullptr)
  421. {
  422. if(node2->startIndex == node1->startIndex)
  423. {
  424. (node1->data.*callback)(node2->data);
  425. prevNodeNextField = &node1->next;
  426. node1 = node1->next;
  427. node2 = node2->next;
  428. }
  429. else if(node2->startIndex > node1->startIndex)
  430. {
  431. if (callback == &SparseBVUnit::And)
  432. {
  433. node1 = this->DeleteNode(node1);
  434. *prevNodeNextField = node1;
  435. }
  436. else
  437. {
  438. prevNodeNextField = &node1->next;
  439. node1 = node1->next;
  440. }
  441. }
  442. else
  443. {
  444. if (callback == &SparseBVUnit::Or || callback == &SparseBVUnit::Xor)
  445. {
  446. BVSparseNode * newNode = Allocate(node2->startIndex, node1);
  447. (newNode->data.*callback)(node2->data);
  448. *prevNodeNextField = newNode;
  449. prevNodeNextField = &newNode->next;
  450. }
  451. node2 = node2->next;
  452. }
  453. }
  454. if (callback == &SparseBVUnit::And)
  455. {
  456. while (node1 != nullptr)
  457. {
  458. node1 = this->DeleteNode(node1);
  459. }
  460. *prevNodeNextField = nullptr;
  461. }
  462. else if (callback == &SparseBVUnit::Or || callback == &SparseBVUnit::Xor)
  463. {
  464. while(node2 != 0)
  465. {
  466. Assert(*prevNodeNextField == nullptr);
  467. BVSparseNode * newNode = Allocate(node2->startIndex, nullptr);
  468. *prevNodeNextField = newNode;
  469. (newNode->data.*callback)(node2->data);
  470. node2 = node2->next;
  471. prevNodeNextField = &newNode->next;
  472. }
  473. }
  474. }
  475. template<class TAllocator>
  476. template<void (SparseBVUnit::*callback)(SparseBVUnit)>
  477. void BVSparse<TAllocator>::for_each(const BVSparse *bv1, const BVSparse *bv2)
  478. {
  479. Assert(callback == &SparseBVUnit::And || callback == &SparseBVUnit::Or || callback == &SparseBVUnit::Xor || callback == &SparseBVUnit::Minus);
  480. Assert(this->IsEmpty());
  481. AssertBV(bv1);
  482. AssertBV(bv2);
  483. BVSparseNode * node1 = bv1->head;
  484. const BVSparseNode * node2 = bv2->head;
  485. BVSparseNode * lastNode = nullptr;
  486. BVSparseNode ** prevNextField = &this->head;
  487. while(node1 != nullptr && node2 != nullptr)
  488. {
  489. lastNode = node1;
  490. BVIndex startIndex;
  491. SparseBVUnit bvUnit1;
  492. SparseBVUnit bvUnit2;
  493. if (node2->startIndex == node1->startIndex)
  494. {
  495. startIndex = node1->startIndex;
  496. bvUnit1 = node1->data;
  497. bvUnit2 = node2->data;
  498. node1 = node1->next;
  499. node2 = node2->next;
  500. }
  501. else if (node2->startIndex > node1->startIndex)
  502. {
  503. startIndex = node1->startIndex;
  504. bvUnit1 = node1->data;
  505. node1 = node1->next;
  506. }
  507. else
  508. {
  509. startIndex = node2->startIndex;
  510. bvUnit2 = node2->data;
  511. node2 = node2->next;
  512. }
  513. (bvUnit1.*callback)(bvUnit2);
  514. if (!bvUnit1.IsEmpty())
  515. {
  516. BVSparseNode * newNode = Allocate(startIndex, nullptr);
  517. newNode->data = bvUnit1;
  518. *prevNextField = newNode;
  519. prevNextField = &newNode->next;
  520. }
  521. }
  522. if (callback == &SparseBVUnit::Minus || callback == &SparseBVUnit::Or || callback == &SparseBVUnit::Xor)
  523. {
  524. BVSparseNode const * copyNode = (callback == &SparseBVUnit::Minus || node1 != nullptr)? node1 : node2;
  525. while (copyNode != nullptr)
  526. {
  527. if (!copyNode->data.IsEmpty())
  528. {
  529. BVSparseNode * newNode = Allocate(copyNode->startIndex, nullptr);
  530. newNode->data = copyNode->data;
  531. *prevNextField = newNode;
  532. prevNextField = &newNode->next;
  533. }
  534. copyNode = copyNode->next;
  535. }
  536. }
  537. }
  538. template <class TAllocator>
  539. void
  540. BVSparse<TAllocator>::Or(const BVSparse*bv)
  541. {
  542. this->for_each<&SparseBVUnit::Or>(bv);
  543. }
  544. template <class TAllocator>
  545. void
  546. BVSparse<TAllocator>::Or(const BVSparse * bv1, const BVSparse * bv2)
  547. {
  548. this->ClearAll();
  549. this->for_each<&SparseBVUnit::Or>(bv1, bv2);
  550. }
  551. template <class TAllocator>
  552. BVSparse<TAllocator> *
  553. BVSparse<TAllocator>::OrNew(const BVSparse* bv, TAllocator* allocator) const
  554. {
  555. BVSparse * newBv = AllocatorNew(TAllocator, allocator, BVSparse, allocator);
  556. newBv->for_each<&SparseBVUnit::Or>(this, bv);
  557. return newBv;
  558. }
  559. template <class TAllocator>
  560. void
  561. BVSparse<TAllocator>::And(const BVSparse*bv)
  562. {
  563. this->for_each<&SparseBVUnit::And>(bv);
  564. }
  565. template <class TAllocator>
  566. void
  567. BVSparse<TAllocator>::And(const BVSparse * bv1, const BVSparse * bv2)
  568. {
  569. this->ClearAll();
  570. this->for_each<&SparseBVUnit::And>(bv1, bv2);
  571. }
  572. template <class TAllocator>
  573. BVSparse<TAllocator> *
  574. BVSparse<TAllocator>::AndNew(const BVSparse* bv, TAllocator* allocator) const
  575. {
  576. BVSparse * newBv = AllocatorNew(TAllocator, allocator, BVSparse, allocator);
  577. newBv->for_each<&SparseBVUnit::And>(this, bv);
  578. return newBv;
  579. }
  580. template <class TAllocator>
  581. void
  582. BVSparse<TAllocator>::Xor(const BVSparse*bv)
  583. {
  584. this->for_each<&SparseBVUnit::Xor>(bv);
  585. }
  586. template <class TAllocator>
  587. void
  588. BVSparse<TAllocator>::Xor(const BVSparse * bv1, const BVSparse * bv2)
  589. {
  590. this->ClearAll();
  591. this->for_each<&SparseBVUnit::Xor>(bv1, bv2);
  592. }
  593. template <class TAllocator>
  594. BVSparse<TAllocator> *
  595. BVSparse<TAllocator>::XorNew(const BVSparse* bv, TAllocator* allocator) const
  596. {
  597. BVSparse * newBv = AllocatorNew(TAllocator, allocator, BVSparse, allocator);
  598. newBv->for_each<&SparseBVUnit::Xor>(this, bv);
  599. return newBv;
  600. }
  601. template <class TAllocator>
  602. void
  603. BVSparse<TAllocator>::Minus(const BVSparse*bv)
  604. {
  605. this->for_each<&SparseBVUnit::Minus>(bv);
  606. }
  607. template <class TAllocator>
  608. void
  609. BVSparse<TAllocator>::Minus(const BVSparse * bv1, const BVSparse * bv2)
  610. {
  611. this->ClearAll();
  612. this->for_each<&SparseBVUnit::Minus>(bv1, bv2);
  613. }
  614. template <class TAllocator>
  615. BVSparse<TAllocator> *
  616. BVSparse<TAllocator>::MinusNew(const BVSparse* bv, TAllocator* allocator) const
  617. {
  618. BVSparse * newBv = AllocatorNew(TAllocator, allocator, BVSparse, allocator);
  619. newBv->for_each<&SparseBVUnit::Minus>(this, bv);
  620. return newBv;
  621. }
  622. template <class TAllocator>
  623. template <class TSrcAllocator>
  624. void
  625. BVSparse<TAllocator>::Copy(const BVSparse<TSrcAllocator> * bv2)
  626. {
  627. AssertBV(bv2);
  628. BVSparseNode * node1 = this->head;
  629. const BVSparseNode * node2 = bv2->head;
  630. BVSparseNode ** prevNextField = &this->head;
  631. while (node1 != nullptr && node2 != nullptr)
  632. {
  633. if (!node2->data.IsEmpty())
  634. {
  635. node1->startIndex = node2->startIndex;
  636. node1->data.Copy(node2->data);
  637. prevNextField = &node1->next;
  638. node1 = node1->next;
  639. }
  640. node2 = node2->next;
  641. }
  642. if (node1 != nullptr)
  643. {
  644. while (node1 != nullptr)
  645. {
  646. node1 = this->DeleteNode(node1);
  647. }
  648. *prevNextField = nullptr;
  649. }
  650. else
  651. {
  652. while (node2 != nullptr)
  653. {
  654. if (!node2->data.IsEmpty())
  655. {
  656. BVSparseNode * newNode = Allocate(node2->startIndex, nullptr);
  657. newNode->data.Copy(node2->data);
  658. *prevNextField = newNode;
  659. prevNextField = &newNode->next;
  660. }
  661. node2 = node2->next;
  662. }
  663. }
  664. }
  665. template <class TAllocator>
  666. BVSparse<TAllocator> *
  667. BVSparse<TAllocator>::CopyNew(TAllocator* allocator) const
  668. {
  669. BVSparse * bv = AllocatorNew(TAllocator, allocator, BVSparse, allocator);
  670. bv->Copy(this);
  671. return bv;
  672. }
  673. template <class TAllocator>
  674. BVSparse<TAllocator> *
  675. BVSparse<TAllocator>::CopyNew() const
  676. {
  677. return this->CopyNew(this->alloc);
  678. }
  679. template <class TAllocator>
  680. void
  681. BVSparse<TAllocator>::ComplimentAll()
  682. {
  683. for(BVSparseNode * node = this->head; node != 0 ; node = node->next)
  684. {
  685. node->data.ComplimentAll();
  686. }
  687. }
  688. template <class TAllocator>
  689. BVIndex
  690. BVSparse<TAllocator>::Count() const
  691. {
  692. BVIndex sum = 0;
  693. for(BVSparseNode * node = this->head; node != 0 ; node = node->next)
  694. {
  695. sum += node->data.Count();
  696. }
  697. return sum;
  698. }
  699. template <class TAllocator>
  700. bool
  701. BVSparse<TAllocator>::IsEmpty() const
  702. {
  703. for(BVSparseNode * node = this->head; node != 0 ; node = node->next)
  704. {
  705. if (!node->data.IsEmpty())
  706. {
  707. return false;
  708. }
  709. }
  710. return true;
  711. }
  712. template <class TAllocator>
  713. bool
  714. BVSparse<TAllocator>::Equal(BVSparse const * bv) const
  715. {
  716. BVSparseNode const * bvNode1 = this->head;
  717. BVSparseNode const * bvNode2 = bv->head;
  718. while (true)
  719. {
  720. while (bvNode1 != nullptr && bvNode1->data.IsEmpty())
  721. {
  722. bvNode1 = bvNode1->next;
  723. }
  724. while (bvNode2 != nullptr && bvNode2->data.IsEmpty())
  725. {
  726. bvNode2 = bvNode2->next;
  727. }
  728. if (bvNode1 == nullptr)
  729. {
  730. return (bvNode2 == nullptr);
  731. }
  732. if (bvNode2 == nullptr)
  733. {
  734. return false;
  735. }
  736. if (bvNode1->startIndex != bvNode2->startIndex)
  737. {
  738. return false;
  739. }
  740. if (!bvNode1->data.Equal(bvNode2->data))
  741. {
  742. return false;
  743. }
  744. bvNode1 = bvNode1->next;
  745. bvNode2 = bvNode2->next;
  746. }
  747. }
  748. template <class TAllocator>
  749. bool
  750. BVSparse<TAllocator>::Test(BVSparse const * bv) const
  751. {
  752. BVSparseNode const * bvNode1 = this->head;
  753. BVSparseNode const * bvNode2 = bv->head;
  754. while (bvNode1 != nullptr && bvNode2 != nullptr)
  755. {
  756. if (bvNode1->data.IsEmpty() || bvNode1->startIndex < bvNode2->startIndex)
  757. {
  758. bvNode1 = bvNode1->next;
  759. continue;
  760. }
  761. if (bvNode2->data.IsEmpty() || bvNode1->startIndex > bvNode2->startIndex)
  762. {
  763. bvNode2 = bvNode2->next;
  764. continue;
  765. }
  766. Assert(bvNode1->startIndex == bvNode2->startIndex);
  767. if (bvNode1->data.Test(bvNode2->data))
  768. {
  769. return true;
  770. }
  771. bvNode1 = bvNode1->next;
  772. bvNode2 = bvNode2->next;
  773. }
  774. return false;
  775. }
  776. #if DBG_DUMP
  777. template <class TAllocator>
  778. void
  779. BVSparse<TAllocator>::Dump() const
  780. {
  781. bool hasBits = false;
  782. Output::Print(CH_WSTR("[ "));
  783. for(BVSparseNode * node = this->head; node != 0 ; node = node->next)
  784. {
  785. hasBits = node->data.Dump(node->startIndex, hasBits);
  786. }
  787. Output::Print(CH_WSTR("]\n"));
  788. }
  789. #endif