BitfieldManTest.cc 20 KB

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