BitfieldManTest.cc 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643
  1. #include "BitfieldMan.h"
  2. #include <cstring>
  3. #include <vector>
  4. #include <cppunit/extensions/HelperMacros.h>
  5. #include "bitfield.h"
  6. #include "array_fun.h"
  7. namespace aria2 {
  8. class BitfieldManTest:public CppUnit::TestFixture {
  9. CPPUNIT_TEST_SUITE(BitfieldManTest);
  10. CPPUNIT_TEST(testGetBlockSize);
  11. CPPUNIT_TEST(testGetFirstMissingUnusedIndex);
  12. CPPUNIT_TEST(testGetFirstMissingIndex);
  13. CPPUNIT_TEST(testIsAllBitSet);
  14. CPPUNIT_TEST(testFilter);
  15. CPPUNIT_TEST(testAddFilter_zeroLength);
  16. CPPUNIT_TEST(testAddNotFilter);
  17. CPPUNIT_TEST(testAddNotFilter_zeroLength);
  18. CPPUNIT_TEST(testAddNotFilter_overflow);
  19. CPPUNIT_TEST(testGetSparseMissingUnusedIndex);
  20. CPPUNIT_TEST(testGetSparseMissingUnusedIndex_setBit);
  21. CPPUNIT_TEST(testGetSparseMissingUnusedIndex_withMinSplitSize);
  22. CPPUNIT_TEST(testIsBitSetOffsetRange);
  23. CPPUNIT_TEST(testGetMissingUnusedLength);
  24. CPPUNIT_TEST(testSetBitRange);
  25. CPPUNIT_TEST(testGetAllMissingIndexes);
  26. CPPUNIT_TEST(testGetAllMissingIndexes_noarg);
  27. CPPUNIT_TEST(testGetAllMissingIndexes_checkLastByte);
  28. CPPUNIT_TEST(testGetAllMissingUnusedIndexes);
  29. CPPUNIT_TEST(testCountFilteredBlock);
  30. CPPUNIT_TEST(testCountMissingBlock);
  31. CPPUNIT_TEST(testZeroLengthFilter);
  32. CPPUNIT_TEST(testGetFirstNMissingUnusedIndex);
  33. CPPUNIT_TEST_SUITE_END();
  34. public:
  35. void testGetBlockSize();
  36. void testGetFirstMissingUnusedIndex();
  37. void testGetFirstMissingIndex();
  38. void testGetAllMissingIndexes();
  39. void testGetAllMissingIndexes_noarg();
  40. void testGetAllMissingIndexes_checkLastByte();
  41. void testGetAllMissingUnusedIndexes();
  42. void testIsAllBitSet();
  43. void testFilter();
  44. void testAddFilter_zeroLength();
  45. void testAddNotFilter();
  46. void testAddNotFilter_zeroLength();
  47. void testAddNotFilter_overflow();
  48. void testGetSparseMissingUnusedIndex();
  49. void testGetSparseMissingUnusedIndex_setBit();
  50. void testGetSparseMissingUnusedIndex_withMinSplitSize();
  51. void testIsBitSetOffsetRange();
  52. void testGetMissingUnusedLength();
  53. void testSetBitRange();
  54. void testCountFilteredBlock();
  55. void testCountMissingBlock();
  56. void testZeroLengthFilter();
  57. void testGetFirstNMissingUnusedIndex();
  58. };
  59. CPPUNIT_TEST_SUITE_REGISTRATION( BitfieldManTest );
  60. void BitfieldManTest::testGetBlockSize() {
  61. BitfieldMan bt1(1024, 1024*10);
  62. CPPUNIT_ASSERT_EQUAL((size_t)1024, bt1.getBlockLength(9));
  63. BitfieldMan bt2(1024, 1024*10+1);
  64. CPPUNIT_ASSERT_EQUAL((size_t)1024, bt2.getBlockLength(9));
  65. CPPUNIT_ASSERT_EQUAL((size_t)1, bt2.getBlockLength(10));
  66. CPPUNIT_ASSERT_EQUAL((size_t)0, bt2.getBlockLength(11));
  67. }
  68. void BitfieldManTest::testGetFirstMissingUnusedIndex()
  69. {
  70. {
  71. BitfieldMan bt1(1024, 1024*10);
  72. {
  73. size_t index;
  74. CPPUNIT_ASSERT(bt1.getFirstMissingUnusedIndex(index));
  75. CPPUNIT_ASSERT_EQUAL((size_t)0, index);
  76. }
  77. bt1.setUseBit(0);
  78. {
  79. size_t index;
  80. CPPUNIT_ASSERT(bt1.getFirstMissingUnusedIndex(index));
  81. CPPUNIT_ASSERT_EQUAL((size_t)1, index);
  82. }
  83. bt1.unsetUseBit(0);
  84. bt1.setBit(0);
  85. {
  86. size_t index;
  87. CPPUNIT_ASSERT(bt1.getFirstMissingUnusedIndex(index));
  88. CPPUNIT_ASSERT_EQUAL((size_t)1, index);
  89. }
  90. bt1.setAllBit();
  91. {
  92. size_t index;
  93. CPPUNIT_ASSERT(!bt1.getFirstMissingUnusedIndex(index));
  94. }
  95. }
  96. {
  97. BitfieldMan bt1(1024, 1024*10);
  98. bt1.addFilter(1024, 1024*10);
  99. bt1.enableFilter();
  100. {
  101. size_t index;
  102. CPPUNIT_ASSERT(bt1.getFirstMissingUnusedIndex(index));
  103. CPPUNIT_ASSERT_EQUAL((size_t)1, index);
  104. }
  105. bt1.setUseBit(1);
  106. {
  107. size_t index;
  108. CPPUNIT_ASSERT(bt1.getFirstMissingUnusedIndex(index));
  109. CPPUNIT_ASSERT_EQUAL((size_t)2, index);
  110. }
  111. bt1.setBit(2);
  112. {
  113. size_t index;
  114. CPPUNIT_ASSERT(bt1.getFirstMissingUnusedIndex(index));
  115. CPPUNIT_ASSERT_EQUAL((size_t)3, index);
  116. }
  117. }
  118. }
  119. void BitfieldManTest::testGetFirstMissingIndex()
  120. {
  121. {
  122. BitfieldMan bt1(1024, 1024*10);
  123. {
  124. size_t index;
  125. CPPUNIT_ASSERT(bt1.getFirstMissingIndex(index));
  126. CPPUNIT_ASSERT_EQUAL((size_t)0, index);
  127. }
  128. bt1.setUseBit(0);
  129. {
  130. size_t index;
  131. CPPUNIT_ASSERT(bt1.getFirstMissingIndex(index));
  132. CPPUNIT_ASSERT_EQUAL((size_t)0, index);
  133. }
  134. bt1.unsetUseBit(0);
  135. bt1.setBit(0);
  136. {
  137. size_t index;
  138. CPPUNIT_ASSERT(bt1.getFirstMissingIndex(index));
  139. CPPUNIT_ASSERT_EQUAL((size_t)1, index);
  140. }
  141. bt1.setAllBit();
  142. {
  143. size_t index;
  144. CPPUNIT_ASSERT(!bt1.getFirstMissingIndex(index));
  145. }
  146. }
  147. {
  148. BitfieldMan bt1(1024, 1024*10);
  149. bt1.addFilter(1024, 1024*10);
  150. bt1.enableFilter();
  151. {
  152. size_t index;
  153. CPPUNIT_ASSERT(bt1.getFirstMissingIndex(index));
  154. CPPUNIT_ASSERT_EQUAL((size_t)1, index);
  155. }
  156. bt1.setUseBit(1);
  157. {
  158. size_t index;
  159. CPPUNIT_ASSERT(bt1.getFirstMissingIndex(index));
  160. CPPUNIT_ASSERT_EQUAL((size_t)1, index);
  161. }
  162. bt1.setBit(1);
  163. {
  164. size_t index;
  165. CPPUNIT_ASSERT(bt1.getFirstMissingIndex(index));
  166. CPPUNIT_ASSERT_EQUAL((size_t)2, index);
  167. }
  168. }
  169. }
  170. void BitfieldManTest::testIsAllBitSet() {
  171. BitfieldMan bt1(1024, 1024*10);
  172. CPPUNIT_ASSERT(!bt1.isAllBitSet());
  173. bt1.setBit(1);
  174. CPPUNIT_ASSERT(!bt1.isAllBitSet());
  175. for(size_t i = 0; i < 8; i++) {
  176. CPPUNIT_ASSERT(bt1.setBit(i));
  177. }
  178. CPPUNIT_ASSERT(!bt1.isAllBitSet());
  179. for(size_t i = 0; i < bt1.countBlock(); i++) {
  180. CPPUNIT_ASSERT(bt1.setBit(i));
  181. }
  182. CPPUNIT_ASSERT(bt1.isAllBitSet());
  183. BitfieldMan btzero(1024, 0);
  184. CPPUNIT_ASSERT(btzero.isAllBitSet());
  185. }
  186. void BitfieldManTest::testFilter()
  187. {
  188. BitfieldMan btman(2, 32);
  189. // test offset=4, length=12
  190. btman.addFilter(4, 12);
  191. btman.enableFilter();
  192. std::vector<size_t> out;
  193. CPPUNIT_ASSERT_EQUAL((size_t)6, btman.getFirstNMissingUnusedIndex(out, 32));
  194. const size_t ans[] = { 2, 3, 4, 5, 6, 7 };
  195. for(size_t i = 0; i < A2_ARRAY_LEN(ans); ++i) {
  196. CPPUNIT_ASSERT_EQUAL(ans[i], out[i]);
  197. }
  198. CPPUNIT_ASSERT_EQUAL((uint64_t)12ULL, btman.getFilteredTotalLength());
  199. // test offset=5, length=2
  200. out.clear();
  201. btman.clearAllBit();
  202. btman.clearAllUseBit();
  203. btman.clearFilter();
  204. btman.addFilter(5, 2);
  205. btman.enableFilter();
  206. CPPUNIT_ASSERT_EQUAL((size_t)2, btman.getFirstNMissingUnusedIndex(out, 32));
  207. CPPUNIT_ASSERT_EQUAL((size_t)2, out[0]);
  208. CPPUNIT_ASSERT_EQUAL((size_t)3, out[1]);
  209. btman.setBit(2);
  210. btman.setBit(3);
  211. CPPUNIT_ASSERT_EQUAL((uint64_t)4ULL, btman.getFilteredTotalLength());
  212. CPPUNIT_ASSERT(btman.isFilteredAllBitSet());
  213. BitfieldMan btman2(2, 31);
  214. btman2.addFilter(0, 31);
  215. btman2.enableFilter();
  216. CPPUNIT_ASSERT_EQUAL((uint64_t)31ULL, btman2.getFilteredTotalLength());
  217. }
  218. void BitfieldManTest::testAddFilter_zeroLength()
  219. {
  220. BitfieldMan bits(1024, 1024*1024);
  221. bits.addFilter(2048, 0);
  222. bits.enableFilter();
  223. CPPUNIT_ASSERT_EQUAL((size_t)0, bits.countMissingBlock());
  224. CPPUNIT_ASSERT(bits.isFilteredAllBitSet());
  225. }
  226. void BitfieldManTest::testAddNotFilter() {
  227. BitfieldMan btman(2, 32);
  228. btman.addNotFilter(3, 6);
  229. CPPUNIT_ASSERT(bitfield::test(btman.getFilterBitfield(), 16, 0));
  230. for(size_t i = 1; i < 5; ++i) {
  231. CPPUNIT_ASSERT(!bitfield::test(btman.getFilterBitfield(), 16, i));
  232. }
  233. for(size_t i = 5; i < 16; ++i) {
  234. CPPUNIT_ASSERT(bitfield::test(btman.getFilterBitfield(), 16, i));
  235. }
  236. }
  237. void BitfieldManTest::testAddNotFilter_zeroLength() {
  238. BitfieldMan btman(2, 6);
  239. btman.addNotFilter(2, 0);
  240. CPPUNIT_ASSERT(!bitfield::test(btman.getFilterBitfield(), 3, 0));
  241. CPPUNIT_ASSERT(!bitfield::test(btman.getFilterBitfield(), 3, 1));
  242. CPPUNIT_ASSERT(!bitfield::test(btman.getFilterBitfield(), 3, 2));
  243. }
  244. void BitfieldManTest::testAddNotFilter_overflow() {
  245. BitfieldMan btman(2, 6);
  246. btman.addNotFilter(6, 100);
  247. CPPUNIT_ASSERT(bitfield::test(btman.getFilterBitfield(), 3, 0));
  248. CPPUNIT_ASSERT(bitfield::test(btman.getFilterBitfield(), 3, 1));
  249. CPPUNIT_ASSERT(bitfield::test(btman.getFilterBitfield(), 3, 2));
  250. }
  251. // TODO1.5 add test using ignoreBitfield
  252. void BitfieldManTest::testGetSparseMissingUnusedIndex() {
  253. BitfieldMan bitfield(1024*1024, 10*1024*1024);
  254. const size_t length = 2;
  255. unsigned char ignoreBitfield[length];
  256. memset(ignoreBitfield, 0, sizeof(ignoreBitfield));
  257. size_t minSplitSize = 1024*1024;
  258. size_t index;
  259. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index, minSplitSize,
  260. ignoreBitfield, length));
  261. CPPUNIT_ASSERT_EQUAL((size_t)0, index);
  262. bitfield.setUseBit(0);
  263. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index, minSplitSize,
  264. ignoreBitfield, length));
  265. CPPUNIT_ASSERT_EQUAL((size_t)5, index);
  266. bitfield.setUseBit(5);
  267. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index, minSplitSize,
  268. ignoreBitfield, length));
  269. CPPUNIT_ASSERT_EQUAL((size_t)3, index);
  270. bitfield.setUseBit(3);
  271. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index, minSplitSize,
  272. ignoreBitfield, length));
  273. CPPUNIT_ASSERT_EQUAL((size_t)8, index);
  274. bitfield.setUseBit(8);
  275. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index, minSplitSize,
  276. ignoreBitfield, length));
  277. CPPUNIT_ASSERT_EQUAL((size_t)2, index);
  278. bitfield.setUseBit(2);
  279. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index, minSplitSize,
  280. ignoreBitfield, length));
  281. CPPUNIT_ASSERT_EQUAL((size_t)1, index);
  282. bitfield.setUseBit(1);
  283. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index, minSplitSize,
  284. ignoreBitfield, length));
  285. CPPUNIT_ASSERT_EQUAL((size_t)4, index);
  286. bitfield.setUseBit(4);
  287. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index, minSplitSize,
  288. ignoreBitfield, length));
  289. CPPUNIT_ASSERT_EQUAL((size_t)7, index);
  290. bitfield.setUseBit(7);
  291. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index, minSplitSize,
  292. ignoreBitfield, length));
  293. CPPUNIT_ASSERT_EQUAL((size_t)6, index);
  294. bitfield.setUseBit(6);
  295. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index, minSplitSize,
  296. ignoreBitfield, length));
  297. CPPUNIT_ASSERT_EQUAL((size_t)9, index);
  298. bitfield.setUseBit(9);
  299. CPPUNIT_ASSERT(!bitfield.getSparseMissingUnusedIndex(index, minSplitSize,
  300. ignoreBitfield, length));
  301. }
  302. void BitfieldManTest::testGetSparseMissingUnusedIndex_setBit() {
  303. BitfieldMan bitfield(1024*1024, 10*1024*1024);
  304. const size_t length = 2;
  305. unsigned char ignoreBitfield[length];
  306. memset(ignoreBitfield, 0, sizeof(ignoreBitfield));
  307. size_t minSplitSize = 1024*1024;
  308. size_t index;
  309. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index, minSplitSize,
  310. ignoreBitfield, length));
  311. CPPUNIT_ASSERT_EQUAL((size_t)0, index);
  312. bitfield.setBit(0);
  313. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index, minSplitSize,
  314. ignoreBitfield, length));
  315. CPPUNIT_ASSERT_EQUAL((size_t)1, index);
  316. bitfield.setBit(1);
  317. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index, minSplitSize,
  318. ignoreBitfield, length));
  319. CPPUNIT_ASSERT_EQUAL((size_t)2, index);
  320. bitfield.setBit(2);
  321. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index, minSplitSize,
  322. ignoreBitfield, length));
  323. CPPUNIT_ASSERT_EQUAL((size_t)3, index);
  324. bitfield.setBit(3);
  325. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index, minSplitSize,
  326. ignoreBitfield, length));
  327. CPPUNIT_ASSERT_EQUAL((size_t)4, index);
  328. bitfield.setBit(4);
  329. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index, minSplitSize,
  330. ignoreBitfield, length));
  331. CPPUNIT_ASSERT_EQUAL((size_t)5, index);
  332. bitfield.setBit(5);
  333. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index, minSplitSize,
  334. ignoreBitfield, length));
  335. CPPUNIT_ASSERT_EQUAL((size_t)6, index);
  336. bitfield.setBit(6);
  337. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index, minSplitSize,
  338. ignoreBitfield, length));
  339. CPPUNIT_ASSERT_EQUAL((size_t)7, index);
  340. bitfield.setBit(7);
  341. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index, minSplitSize,
  342. ignoreBitfield, length));
  343. CPPUNIT_ASSERT_EQUAL((size_t)8, index);
  344. bitfield.setBit(8);
  345. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index, minSplitSize,
  346. ignoreBitfield, length));
  347. CPPUNIT_ASSERT_EQUAL((size_t)9, index);
  348. bitfield.setBit(9);
  349. CPPUNIT_ASSERT(!bitfield.getSparseMissingUnusedIndex(index, minSplitSize,
  350. ignoreBitfield, length));
  351. }
  352. void BitfieldManTest::testGetSparseMissingUnusedIndex_withMinSplitSize()
  353. {
  354. BitfieldMan bitfield(1024*1024, 10*1024*1024);
  355. const size_t length = 2;
  356. unsigned char ignoreBitfield[length];
  357. memset(ignoreBitfield, 0, sizeof(ignoreBitfield));
  358. size_t minSplitSize = 2*1024*1024;
  359. size_t index;
  360. bitfield.setUseBit(1);
  361. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index, minSplitSize,
  362. ignoreBitfield, length));
  363. CPPUNIT_ASSERT_EQUAL((size_t)6, index);
  364. bitfield.setBit(6);
  365. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index, minSplitSize,
  366. ignoreBitfield, length));
  367. CPPUNIT_ASSERT_EQUAL((size_t)7, index);
  368. bitfield.setUseBit(7);
  369. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index, minSplitSize,
  370. ignoreBitfield, length));
  371. CPPUNIT_ASSERT_EQUAL((size_t)4, index);
  372. bitfield.setBit(4);
  373. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index, minSplitSize,
  374. ignoreBitfield, length));
  375. CPPUNIT_ASSERT_EQUAL((size_t)0, index);
  376. bitfield.setBit(0);
  377. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index, minSplitSize,
  378. ignoreBitfield, length));
  379. CPPUNIT_ASSERT_EQUAL((size_t)5, index);
  380. bitfield.setBit(5);
  381. CPPUNIT_ASSERT(!bitfield.getSparseMissingUnusedIndex(index, minSplitSize,
  382. ignoreBitfield, length));
  383. }
  384. void BitfieldManTest::testIsBitSetOffsetRange()
  385. {
  386. int64_t totalLength = 4ULL*1024*1024*1024;
  387. int32_t pieceLength = 4*1024*1024;
  388. BitfieldMan bitfield(pieceLength, totalLength);
  389. bitfield.setAllBit();
  390. CPPUNIT_ASSERT(!bitfield.isBitSetOffsetRange(0, 0));
  391. CPPUNIT_ASSERT(!bitfield.isBitSetOffsetRange(totalLength, 100));
  392. CPPUNIT_ASSERT(!bitfield.isBitSetOffsetRange(totalLength+1, 100));
  393. CPPUNIT_ASSERT(bitfield.isBitSetOffsetRange(0, totalLength));
  394. CPPUNIT_ASSERT(bitfield.isBitSetOffsetRange(0, totalLength+1));
  395. bitfield.clearAllBit();
  396. bitfield.setBit(100);
  397. bitfield.setBit(101);
  398. CPPUNIT_ASSERT(bitfield.isBitSetOffsetRange(pieceLength*100, pieceLength*2));
  399. CPPUNIT_ASSERT(!bitfield.isBitSetOffsetRange(pieceLength*100-10, pieceLength*2));
  400. CPPUNIT_ASSERT(!bitfield.isBitSetOffsetRange(pieceLength*100, pieceLength*2+1));
  401. bitfield.clearAllBit();
  402. bitfield.setBit(100);
  403. bitfield.setBit(102);
  404. CPPUNIT_ASSERT(!bitfield.isBitSetOffsetRange(pieceLength*100, pieceLength*3));
  405. }
  406. void BitfieldManTest::testGetMissingUnusedLength()
  407. {
  408. uint64_t totalLength = 1024*10+10;
  409. size_t blockLength = 1024;
  410. BitfieldMan bf(blockLength, totalLength);
  411. // from index 0 and all blocks are unused and not acquired.
  412. CPPUNIT_ASSERT_EQUAL(totalLength, bf.getMissingUnusedLength(0));
  413. // from index 10 and all blocks are unused and not acquired.
  414. CPPUNIT_ASSERT_EQUAL((uint64_t)10ULL, bf.getMissingUnusedLength(10));
  415. // from index 11
  416. CPPUNIT_ASSERT_EQUAL((uint64_t)0ULL, bf.getMissingUnusedLength(11));
  417. // from index 12
  418. CPPUNIT_ASSERT_EQUAL((uint64_t)0ULL, bf.getMissingUnusedLength(12));
  419. // from index 0 and 5th block is used.
  420. bf.setUseBit(5);
  421. CPPUNIT_ASSERT_EQUAL((uint64_t)5ULL*blockLength, bf.getMissingUnusedLength(0));
  422. // from index 0 and 4th block is acquired.
  423. bf.setBit(4);
  424. CPPUNIT_ASSERT_EQUAL((uint64_t)4ULL*blockLength, bf.getMissingUnusedLength(0));
  425. // from index 1
  426. CPPUNIT_ASSERT_EQUAL((uint64_t)3ULL*blockLength, bf.getMissingUnusedLength(1));
  427. }
  428. void BitfieldManTest::testSetBitRange()
  429. {
  430. size_t blockLength = 1024*1024;
  431. uint64_t totalLength = 10*blockLength;
  432. BitfieldMan bf(blockLength, totalLength);
  433. bf.setBitRange(0, 4);
  434. for(size_t i = 0; i < 5; ++i) {
  435. CPPUNIT_ASSERT(bf.isBitSet(i));
  436. }
  437. for(size_t i = 5; i < 10; ++i) {
  438. CPPUNIT_ASSERT(!bf.isBitSet(i));
  439. }
  440. CPPUNIT_ASSERT_EQUAL((uint64_t)5ULL*blockLength, bf.getCompletedLength());
  441. }
  442. void BitfieldManTest::testGetAllMissingIndexes_noarg()
  443. {
  444. size_t blockLength = 16*1024;
  445. uint64_t totalLength = 1024*1024;
  446. size_t nbits = (totalLength+blockLength-1)/blockLength;
  447. BitfieldMan bf(blockLength, totalLength);
  448. unsigned char misbitfield[8];
  449. CPPUNIT_ASSERT(bf.getAllMissingIndexes(misbitfield, sizeof(misbitfield)));
  450. CPPUNIT_ASSERT_EQUAL((size_t)64, bitfield::countSetBit(misbitfield, nbits));
  451. for(size_t i = 0; i < 63; ++i) {
  452. bf.setBit(i);
  453. }
  454. CPPUNIT_ASSERT(bf.getAllMissingIndexes(misbitfield, sizeof(misbitfield)));
  455. CPPUNIT_ASSERT_EQUAL((size_t)1, bitfield::countSetBit(misbitfield, nbits));
  456. CPPUNIT_ASSERT(bitfield::test(misbitfield, nbits, 63));
  457. }
  458. // See garbage bits of last byte are 0
  459. void BitfieldManTest::testGetAllMissingIndexes_checkLastByte()
  460. {
  461. size_t blockLength = 16*1024;
  462. uint64_t totalLength = blockLength*2;
  463. size_t nbits = (totalLength+blockLength-1)/blockLength;
  464. BitfieldMan bf(blockLength, totalLength);
  465. unsigned char misbitfield[1];
  466. CPPUNIT_ASSERT(bf.getAllMissingIndexes(misbitfield, sizeof(misbitfield)));
  467. CPPUNIT_ASSERT_EQUAL((size_t)2, bitfield::countSetBit(misbitfield, nbits));
  468. CPPUNIT_ASSERT(bitfield::test(misbitfield, nbits, 0));
  469. CPPUNIT_ASSERT(bitfield::test(misbitfield, nbits, 1));
  470. }
  471. void BitfieldManTest::testGetAllMissingIndexes()
  472. {
  473. size_t blockLength = 16*1024;
  474. uint64_t totalLength = 1024*1024;
  475. size_t nbits = (totalLength+blockLength-1)/blockLength;
  476. BitfieldMan bf(blockLength, totalLength);
  477. BitfieldMan peerBf(blockLength, totalLength);
  478. peerBf.setAllBit();
  479. unsigned char misbitfield[8];
  480. CPPUNIT_ASSERT(bf.getAllMissingIndexes(misbitfield, sizeof(misbitfield),
  481. peerBf.getBitfield(),
  482. peerBf.getBitfieldLength()));
  483. CPPUNIT_ASSERT_EQUAL((size_t)64, bitfield::countSetBit(misbitfield, nbits));
  484. for(size_t i = 0; i < 62; ++i) {
  485. bf.setBit(i);
  486. }
  487. peerBf.unsetBit(62);
  488. CPPUNIT_ASSERT(bf.getAllMissingIndexes(misbitfield, sizeof(misbitfield),
  489. peerBf.getBitfield(),
  490. peerBf.getBitfieldLength()));
  491. CPPUNIT_ASSERT_EQUAL((size_t)1, bitfield::countSetBit(misbitfield, nbits));
  492. CPPUNIT_ASSERT(bitfield::test(misbitfield, nbits, 63));
  493. }
  494. void BitfieldManTest::testGetAllMissingUnusedIndexes()
  495. {
  496. size_t blockLength = 16*1024;
  497. uint64_t totalLength = 1024*1024;
  498. size_t nbits = (totalLength+blockLength-1)/blockLength;
  499. BitfieldMan bf(blockLength, totalLength);
  500. BitfieldMan peerBf(blockLength, totalLength);
  501. peerBf.setAllBit();
  502. unsigned char misbitfield[8];
  503. CPPUNIT_ASSERT(bf.getAllMissingUnusedIndexes(misbitfield,
  504. sizeof(misbitfield),
  505. peerBf.getBitfield(),
  506. peerBf.getBitfieldLength()));
  507. CPPUNIT_ASSERT_EQUAL((size_t)64, bitfield::countSetBit(misbitfield, nbits));
  508. for(size_t i = 0; i < 61; ++i) {
  509. bf.setBit(i);
  510. }
  511. bf.setUseBit(61);
  512. peerBf.unsetBit(62);
  513. CPPUNIT_ASSERT(bf.getAllMissingUnusedIndexes(misbitfield,
  514. sizeof(misbitfield),
  515. peerBf.getBitfield(),
  516. peerBf.getBitfieldLength()));
  517. CPPUNIT_ASSERT_EQUAL((size_t)1, bitfield::countSetBit(misbitfield, nbits));
  518. CPPUNIT_ASSERT(bitfield::test(misbitfield, nbits, 63));
  519. }
  520. void BitfieldManTest::testCountFilteredBlock()
  521. {
  522. BitfieldMan bt(1024, 1024*256);
  523. CPPUNIT_ASSERT_EQUAL((size_t)256, bt.countBlock());
  524. CPPUNIT_ASSERT_EQUAL((size_t)0, bt.countFilteredBlock());
  525. bt.addFilter(1024, 1024*256);
  526. bt.enableFilter();
  527. CPPUNIT_ASSERT_EQUAL((size_t)256, bt.countBlock());
  528. CPPUNIT_ASSERT_EQUAL((size_t)255, bt.countFilteredBlock());
  529. bt.disableFilter();
  530. CPPUNIT_ASSERT_EQUAL((size_t)256, bt.countBlock());
  531. CPPUNIT_ASSERT_EQUAL((size_t)0, bt.countFilteredBlock());
  532. }
  533. void BitfieldManTest::testCountMissingBlock()
  534. {
  535. BitfieldMan bt(1024, 1024*10);
  536. CPPUNIT_ASSERT_EQUAL((size_t)10, bt.countMissingBlock());
  537. bt.setBit(1);
  538. CPPUNIT_ASSERT_EQUAL((size_t)9, bt.countMissingBlock());
  539. bt.setAllBit();
  540. CPPUNIT_ASSERT_EQUAL((size_t)0, bt.countMissingBlock());
  541. }
  542. void BitfieldManTest::testZeroLengthFilter()
  543. {
  544. BitfieldMan bt(1024, 1024*10);
  545. bt.enableFilter();
  546. CPPUNIT_ASSERT_EQUAL((size_t)0, bt.countMissingBlock());
  547. }
  548. void BitfieldManTest::testGetFirstNMissingUnusedIndex()
  549. {
  550. BitfieldMan bt(1024, 1024*10);
  551. bt.setUseBit(1);
  552. bt.setBit(5);
  553. std::vector<size_t> out;
  554. CPPUNIT_ASSERT_EQUAL((size_t)8, bt.getFirstNMissingUnusedIndex(out, 256));
  555. CPPUNIT_ASSERT_EQUAL((size_t)8, out.size());
  556. const size_t ans[] = {0, 2, 3, 4, 6, 7, 8, 9};
  557. for(size_t i = 0; i < out.size(); ++i) {
  558. CPPUNIT_ASSERT_EQUAL(ans[i], out[i]);
  559. }
  560. out.clear();
  561. CPPUNIT_ASSERT_EQUAL((size_t)3, bt.getFirstNMissingUnusedIndex(out, 3));
  562. CPPUNIT_ASSERT_EQUAL((size_t)3, out.size());
  563. for(size_t i = 0; i < out.size(); ++i) {
  564. CPPUNIT_ASSERT_EQUAL(ans[i], out[i]);
  565. }
  566. CPPUNIT_ASSERT_EQUAL((size_t)0, bt.getFirstNMissingUnusedIndex(out, 0));
  567. bt.setAllBit();
  568. CPPUNIT_ASSERT_EQUAL((size_t)0, bt.getFirstNMissingUnusedIndex(out, 10));
  569. bt.clearAllBit();
  570. out.clear();
  571. bt.addFilter(1024*9, 1024);
  572. bt.enableFilter();
  573. CPPUNIT_ASSERT_EQUAL((size_t)1, bt.getFirstNMissingUnusedIndex(out, 256));
  574. CPPUNIT_ASSERT_EQUAL((size_t)1, out.size());
  575. CPPUNIT_ASSERT_EQUAL((size_t)9, out[0]);
  576. }
  577. } // namespace aria2