BitfieldManTest.cc 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846
  1. #include "BitfieldMan.h"
  2. #include <cstring>
  3. #include <cppunit/extensions/HelperMacros.h>
  4. #include "FixedNumberRandomizer.h"
  5. #include "bitfield.h"
  6. namespace aria2 {
  7. class BitfieldManTest:public CppUnit::TestFixture {
  8. CPPUNIT_TEST_SUITE(BitfieldManTest);
  9. CPPUNIT_TEST(testGetBlockSize);
  10. CPPUNIT_TEST(testGetFirstMissingUnusedIndex);
  11. CPPUNIT_TEST(testGetFirstMissingIndex);
  12. CPPUNIT_TEST(testIsAllBitSet);
  13. CPPUNIT_TEST(testFilter);
  14. CPPUNIT_TEST(testAddFilter_zeroLength);
  15. CPPUNIT_TEST(testAddNotFilter);
  16. CPPUNIT_TEST(testAddNotFilter_zeroLength);
  17. CPPUNIT_TEST(testAddNotFilter_overflow);
  18. CPPUNIT_TEST(testGetMissingIndex);
  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(testGetMissingUnusedIndex);
  29. CPPUNIT_TEST(testGetMissingIndex_noarg);
  30. CPPUNIT_TEST(testGetMissingUnusedIndex_noarg);
  31. CPPUNIT_TEST(testCountFilteredBlock);
  32. CPPUNIT_TEST(testCountMissingBlock);
  33. CPPUNIT_TEST(testZeroLengthFilter);
  34. CPPUNIT_TEST_SUITE_END();
  35. private:
  36. SharedHandle<Randomizer> fixedNumberRandomizer;
  37. public:
  38. BitfieldManTest() {
  39. FixedNumberRandomizer* randomizer = new FixedNumberRandomizer();
  40. randomizer->setFixedNumber(0);
  41. this->fixedNumberRandomizer.reset(randomizer);
  42. }
  43. void setUp() {
  44. }
  45. void testGetBlockSize();
  46. void testGetFirstMissingUnusedIndex();
  47. void testGetFirstMissingIndex();
  48. void testGetMissingIndex();
  49. void testGetMissingIndex_noarg();
  50. void testGetMissingUnusedIndex();
  51. void testGetMissingUnusedIndex_noarg();
  52. void testGetAllMissingIndexes();
  53. void testGetAllMissingIndexes_noarg();
  54. void testGetAllMissingIndexes_checkLastByte();
  55. void testGetAllMissingUnusedIndexes();
  56. void testIsAllBitSet();
  57. void testFilter();
  58. void testAddFilter_zeroLength();
  59. void testAddNotFilter();
  60. void testAddNotFilter_zeroLength();
  61. void testAddNotFilter_overflow();
  62. void testGetSparceMissingUnusedIndex();
  63. void testGetSparceMissingUnusedIndex_setBit();
  64. void testIsBitSetOffsetRange();
  65. void testGetMissingUnusedLength();
  66. void testSetBitRange();
  67. void testCountFilteredBlock();
  68. void testCountMissingBlock();
  69. void testZeroLengthFilter();
  70. };
  71. CPPUNIT_TEST_SUITE_REGISTRATION( BitfieldManTest );
  72. void BitfieldManTest::testGetBlockSize() {
  73. BitfieldMan bt1(1024, 1024*10);
  74. CPPUNIT_ASSERT_EQUAL((size_t)1024, bt1.getBlockLength(9));
  75. BitfieldMan bt2(1024, 1024*10+1);
  76. CPPUNIT_ASSERT_EQUAL((size_t)1024, bt2.getBlockLength(9));
  77. CPPUNIT_ASSERT_EQUAL((size_t)1, bt2.getBlockLength(10));
  78. CPPUNIT_ASSERT_EQUAL((size_t)0, bt2.getBlockLength(11));
  79. }
  80. void BitfieldManTest::testGetFirstMissingUnusedIndex()
  81. {
  82. {
  83. BitfieldMan bt1(1024, 1024*10);
  84. {
  85. size_t index;
  86. CPPUNIT_ASSERT(bt1.getFirstMissingUnusedIndex(index));
  87. CPPUNIT_ASSERT_EQUAL((size_t)0, index);
  88. }
  89. bt1.setUseBit(0);
  90. {
  91. size_t index;
  92. CPPUNIT_ASSERT(bt1.getFirstMissingUnusedIndex(index));
  93. CPPUNIT_ASSERT_EQUAL((size_t)1, index);
  94. }
  95. bt1.unsetUseBit(0);
  96. bt1.setBit(0);
  97. {
  98. size_t index;
  99. CPPUNIT_ASSERT(bt1.getFirstMissingUnusedIndex(index));
  100. CPPUNIT_ASSERT_EQUAL((size_t)1, index);
  101. }
  102. bt1.setAllBit();
  103. {
  104. size_t index;
  105. CPPUNIT_ASSERT(!bt1.getFirstMissingUnusedIndex(index));
  106. }
  107. }
  108. {
  109. BitfieldMan bt1(1024, 1024*10);
  110. bt1.addFilter(1024, 1024*10);
  111. bt1.enableFilter();
  112. {
  113. size_t index;
  114. CPPUNIT_ASSERT(bt1.getFirstMissingUnusedIndex(index));
  115. CPPUNIT_ASSERT_EQUAL((size_t)1, index);
  116. }
  117. bt1.setUseBit(1);
  118. {
  119. size_t index;
  120. CPPUNIT_ASSERT(bt1.getFirstMissingUnusedIndex(index));
  121. CPPUNIT_ASSERT_EQUAL((size_t)2, index);
  122. }
  123. bt1.setBit(2);
  124. {
  125. size_t index;
  126. CPPUNIT_ASSERT(bt1.getFirstMissingUnusedIndex(index));
  127. CPPUNIT_ASSERT_EQUAL((size_t)3, index);
  128. }
  129. }
  130. }
  131. void BitfieldManTest::testGetFirstMissingIndex()
  132. {
  133. {
  134. BitfieldMan bt1(1024, 1024*10);
  135. {
  136. size_t index;
  137. CPPUNIT_ASSERT(bt1.getFirstMissingIndex(index));
  138. CPPUNIT_ASSERT_EQUAL((size_t)0, index);
  139. }
  140. bt1.setUseBit(0);
  141. {
  142. size_t index;
  143. CPPUNIT_ASSERT(bt1.getFirstMissingIndex(index));
  144. CPPUNIT_ASSERT_EQUAL((size_t)0, index);
  145. }
  146. bt1.unsetUseBit(0);
  147. bt1.setBit(0);
  148. {
  149. size_t index;
  150. CPPUNIT_ASSERT(bt1.getFirstMissingIndex(index));
  151. CPPUNIT_ASSERT_EQUAL((size_t)1, index);
  152. }
  153. bt1.setAllBit();
  154. {
  155. size_t index;
  156. CPPUNIT_ASSERT(!bt1.getFirstMissingIndex(index));
  157. }
  158. }
  159. {
  160. BitfieldMan bt1(1024, 1024*10);
  161. bt1.addFilter(1024, 1024*10);
  162. bt1.enableFilter();
  163. {
  164. size_t index;
  165. CPPUNIT_ASSERT(bt1.getFirstMissingIndex(index));
  166. CPPUNIT_ASSERT_EQUAL((size_t)1, index);
  167. }
  168. bt1.setUseBit(1);
  169. {
  170. size_t index;
  171. CPPUNIT_ASSERT(bt1.getFirstMissingIndex(index));
  172. CPPUNIT_ASSERT_EQUAL((size_t)1, index);
  173. }
  174. bt1.setBit(1);
  175. {
  176. size_t index;
  177. CPPUNIT_ASSERT(bt1.getFirstMissingIndex(index));
  178. CPPUNIT_ASSERT_EQUAL((size_t)2, index);
  179. }
  180. }
  181. }
  182. void BitfieldManTest::testGetMissingUnusedIndex_noarg()
  183. {
  184. {
  185. BitfieldMan bt1(1024, 1024*10);
  186. bt1.setRandomizer(fixedNumberRandomizer);
  187. {
  188. size_t index;
  189. CPPUNIT_ASSERT(bt1.getMissingUnusedIndex(index));
  190. CPPUNIT_ASSERT_EQUAL((size_t)0, index);
  191. }
  192. bt1.setUseBit(0);
  193. {
  194. size_t index;
  195. CPPUNIT_ASSERT(bt1.getMissingUnusedIndex(index));
  196. CPPUNIT_ASSERT_EQUAL((size_t)1, index);
  197. }
  198. bt1.unsetUseBit(0);
  199. bt1.setBit(0);
  200. {
  201. size_t index;
  202. CPPUNIT_ASSERT(bt1.getMissingUnusedIndex(index));
  203. CPPUNIT_ASSERT_EQUAL((size_t)1, index);
  204. }
  205. bt1.setAllBit();
  206. {
  207. size_t index;
  208. CPPUNIT_ASSERT(!bt1.getMissingUnusedIndex(index));
  209. }
  210. }
  211. {
  212. BitfieldMan bt1(1024, 1024*10);
  213. bt1.setRandomizer(fixedNumberRandomizer);
  214. bt1.addFilter(1024, 1024*10);
  215. bt1.enableFilter();
  216. {
  217. size_t index;
  218. CPPUNIT_ASSERT(bt1.getMissingUnusedIndex(index));
  219. CPPUNIT_ASSERT_EQUAL((size_t)1, index);
  220. }
  221. bt1.setUseBit(1);
  222. {
  223. size_t index;
  224. CPPUNIT_ASSERT(bt1.getMissingUnusedIndex(index));
  225. CPPUNIT_ASSERT_EQUAL((size_t)2, index);
  226. }
  227. bt1.setBit(2);
  228. {
  229. size_t index;
  230. CPPUNIT_ASSERT(bt1.getMissingUnusedIndex(index));
  231. CPPUNIT_ASSERT_EQUAL((size_t)3, index);
  232. }
  233. }
  234. }
  235. void BitfieldManTest::testGetMissingIndex_noarg()
  236. {
  237. {
  238. BitfieldMan bt1(1024, 1024*10);
  239. bt1.setRandomizer(fixedNumberRandomizer);
  240. {
  241. size_t index;
  242. CPPUNIT_ASSERT(bt1.getMissingIndex(index));
  243. CPPUNIT_ASSERT_EQUAL((size_t)0, index);
  244. }
  245. bt1.setUseBit(0);
  246. {
  247. size_t index;
  248. CPPUNIT_ASSERT(bt1.getMissingIndex(index));
  249. CPPUNIT_ASSERT_EQUAL((size_t)0, index);
  250. }
  251. bt1.unsetUseBit(0);
  252. bt1.setBit(0);
  253. {
  254. size_t index;
  255. CPPUNIT_ASSERT(bt1.getMissingIndex(index));
  256. CPPUNIT_ASSERT_EQUAL((size_t)1, index);
  257. }
  258. bt1.setAllBit();
  259. {
  260. size_t index;
  261. CPPUNIT_ASSERT(!bt1.getMissingIndex(index));
  262. }
  263. }
  264. {
  265. BitfieldMan bt1(1024, 1024*10);
  266. bt1.setRandomizer(fixedNumberRandomizer);
  267. bt1.addFilter(1024, 1024*10);
  268. bt1.enableFilter();
  269. {
  270. size_t index;
  271. CPPUNIT_ASSERT(bt1.getMissingIndex(index));
  272. CPPUNIT_ASSERT_EQUAL((size_t)1, index);
  273. }
  274. bt1.setUseBit(1);
  275. {
  276. size_t index;
  277. CPPUNIT_ASSERT(bt1.getMissingIndex(index));
  278. CPPUNIT_ASSERT_EQUAL((size_t)1, index);
  279. }
  280. bt1.setBit(1);
  281. {
  282. size_t index;
  283. CPPUNIT_ASSERT(bt1.getMissingIndex(index));
  284. CPPUNIT_ASSERT_EQUAL((size_t)2, index);
  285. }
  286. }
  287. }
  288. void BitfieldManTest::testIsAllBitSet() {
  289. BitfieldMan bt1(1024, 1024*10);
  290. CPPUNIT_ASSERT(!bt1.isAllBitSet());
  291. bt1.setBit(1);
  292. CPPUNIT_ASSERT(!bt1.isAllBitSet());
  293. for(size_t i = 0; i < 8; i++) {
  294. CPPUNIT_ASSERT(bt1.setBit(i));
  295. }
  296. CPPUNIT_ASSERT(!bt1.isAllBitSet());
  297. for(size_t i = 0; i < bt1.countBlock(); i++) {
  298. CPPUNIT_ASSERT(bt1.setBit(i));
  299. }
  300. CPPUNIT_ASSERT(bt1.isAllBitSet());
  301. BitfieldMan btzero(1024, 0);
  302. CPPUNIT_ASSERT(btzero.isAllBitSet());
  303. }
  304. void BitfieldManTest::testFilter() {
  305. BitfieldMan btman(2, 32);
  306. btman.setRandomizer(fixedNumberRandomizer);
  307. // test offset=4, length=12
  308. btman.addFilter(4, 12);
  309. btman.enableFilter();
  310. unsigned char peerBt[2];
  311. memset(peerBt, 0xff, sizeof(peerBt));
  312. size_t index;
  313. CPPUNIT_ASSERT(btman.getMissingUnusedIndex(index, peerBt, sizeof(peerBt)));
  314. btman.setUseBit(index);
  315. CPPUNIT_ASSERT_EQUAL((size_t)2, index);
  316. CPPUNIT_ASSERT(btman.getMissingUnusedIndex(index, peerBt, sizeof(peerBt)));
  317. btman.setUseBit(index);
  318. CPPUNIT_ASSERT_EQUAL((size_t)3, index);
  319. CPPUNIT_ASSERT(btman.getMissingUnusedIndex(index, peerBt, sizeof(peerBt)));
  320. btman.setUseBit(index);
  321. CPPUNIT_ASSERT_EQUAL((size_t)4, index);
  322. CPPUNIT_ASSERT(btman.getMissingUnusedIndex(index, peerBt, sizeof(peerBt)));
  323. btman.setUseBit(index);
  324. CPPUNIT_ASSERT_EQUAL((size_t)5, index);
  325. CPPUNIT_ASSERT(btman.getMissingUnusedIndex(index, peerBt, sizeof(peerBt)));
  326. btman.setUseBit(index);
  327. CPPUNIT_ASSERT_EQUAL((size_t)6, index);
  328. CPPUNIT_ASSERT(btman.getMissingUnusedIndex(index, peerBt, sizeof(peerBt)));
  329. btman.setUseBit(index);
  330. CPPUNIT_ASSERT_EQUAL((size_t)7, index);
  331. CPPUNIT_ASSERT(!btman.getMissingUnusedIndex(index, peerBt, sizeof(peerBt)));
  332. CPPUNIT_ASSERT_EQUAL((uint64_t)12ULL, btman.getFilteredTotalLength());
  333. // test offset=5, length=2
  334. btman.clearAllBit();
  335. btman.clearAllUseBit();
  336. btman.clearFilter();
  337. btman.addFilter(5, 2);
  338. btman.enableFilter();
  339. CPPUNIT_ASSERT(btman.getMissingUnusedIndex(index, peerBt, sizeof(peerBt)));
  340. btman.setUseBit(index);
  341. btman.setBit(index);
  342. CPPUNIT_ASSERT_EQUAL((size_t)2, index);
  343. CPPUNIT_ASSERT(btman.getMissingUnusedIndex(index, peerBt, sizeof(peerBt)));
  344. btman.setUseBit(index);
  345. btman.setBit(index);
  346. CPPUNIT_ASSERT_EQUAL((size_t)3, index);
  347. CPPUNIT_ASSERT(!btman.getMissingUnusedIndex(index, peerBt, sizeof(peerBt)));
  348. CPPUNIT_ASSERT_EQUAL((uint64_t)4ULL, btman.getFilteredTotalLength());
  349. CPPUNIT_ASSERT(btman.isFilteredAllBitSet());
  350. BitfieldMan btman2(2, 31);
  351. btman2.addFilter(0, 31);
  352. btman2.enableFilter();
  353. CPPUNIT_ASSERT_EQUAL((uint64_t)31ULL, btman2.getFilteredTotalLength());
  354. }
  355. void BitfieldManTest::testAddFilter_zeroLength()
  356. {
  357. BitfieldMan bits(1024, 1024*1024);
  358. bits.addFilter(2048, 0);
  359. bits.enableFilter();
  360. CPPUNIT_ASSERT_EQUAL((size_t)0, bits.countMissingBlock());
  361. CPPUNIT_ASSERT(bits.isFilteredAllBitSet());
  362. }
  363. void BitfieldManTest::testAddNotFilter() {
  364. BitfieldMan btman(2, 32);
  365. btman.addNotFilter(3, 6);
  366. CPPUNIT_ASSERT(bitfield::test(btman.getFilterBitfield(), 16, 0));
  367. for(size_t i = 1; i < 5; ++i) {
  368. CPPUNIT_ASSERT(!bitfield::test(btman.getFilterBitfield(), 16, i));
  369. }
  370. for(size_t i = 5; i < 16; ++i) {
  371. CPPUNIT_ASSERT(bitfield::test(btman.getFilterBitfield(), 16, i));
  372. }
  373. }
  374. void BitfieldManTest::testAddNotFilter_zeroLength() {
  375. BitfieldMan btman(2, 6);
  376. btman.addNotFilter(2, 0);
  377. CPPUNIT_ASSERT(!bitfield::test(btman.getFilterBitfield(), 3, 0));
  378. CPPUNIT_ASSERT(!bitfield::test(btman.getFilterBitfield(), 3, 1));
  379. CPPUNIT_ASSERT(!bitfield::test(btman.getFilterBitfield(), 3, 2));
  380. }
  381. void BitfieldManTest::testAddNotFilter_overflow() {
  382. BitfieldMan btman(2, 6);
  383. btman.addNotFilter(6, 100);
  384. CPPUNIT_ASSERT(bitfield::test(btman.getFilterBitfield(), 3, 0));
  385. CPPUNIT_ASSERT(bitfield::test(btman.getFilterBitfield(), 3, 1));
  386. CPPUNIT_ASSERT(bitfield::test(btman.getFilterBitfield(), 3, 2));
  387. }
  388. void BitfieldManTest::testGetMissingIndex() {
  389. BitfieldMan bt1(1024, 1024*256);
  390. bt1.setRandomizer(fixedNumberRandomizer);
  391. unsigned char bitArray[] = {
  392. 0xff, 0xff, 0xff, 0xff,
  393. 0xff, 0xff, 0xff, 0xff,
  394. 0xff, 0xff, 0xff, 0xff,
  395. 0xff, 0xff, 0xff, 0xff,
  396. 0xff, 0xff, 0xff, 0xff,
  397. 0xff, 0xff, 0xff, 0xff,
  398. 0xff, 0xff, 0xff, 0xff,
  399. 0xff, 0xff, 0xff, 0xff,
  400. };
  401. size_t index;
  402. CPPUNIT_ASSERT(bt1.getMissingIndex(index, bitArray, 32));
  403. CPPUNIT_ASSERT_EQUAL((size_t)0, index);
  404. bt1.addFilter(1024, 1024*256);
  405. bt1.enableFilter();
  406. CPPUNIT_ASSERT(bt1.getMissingIndex(index, bitArray, 32));
  407. CPPUNIT_ASSERT_EQUAL((size_t)1, index);
  408. bt1.disableFilter();
  409. unsigned char bitArray2[] = {
  410. 0x0f, 0xff, 0xff, 0xff,
  411. 0xff, 0xff, 0xff, 0xff,
  412. 0xff, 0xff, 0xff, 0xff,
  413. 0xff, 0xff, 0xff, 0xff,
  414. 0xff, 0xff, 0xff, 0xff,
  415. 0xff, 0xff, 0xff, 0xff,
  416. 0xff, 0xff, 0xff, 0xff,
  417. 0xff, 0xff, 0xff, 0xff,
  418. };
  419. CPPUNIT_ASSERT(bt1.getMissingIndex(index, bitArray2, 32));
  420. CPPUNIT_ASSERT_EQUAL((size_t)4, index);
  421. unsigned char bitArray3[] = {
  422. 0x00, 0xff, 0xff, 0xff,
  423. 0xff, 0xff, 0xff, 0xff,
  424. 0xff, 0xff, 0xff, 0xff,
  425. 0xff, 0xff, 0xff, 0xff,
  426. 0xff, 0xff, 0xff, 0xff,
  427. 0xff, 0xff, 0xff, 0xff,
  428. 0xff, 0xff, 0xff, 0xff,
  429. 0xff, 0xff, 0xff, 0xff,
  430. };
  431. CPPUNIT_ASSERT(bt1.getMissingIndex(index, bitArray3, 32));
  432. CPPUNIT_ASSERT_EQUAL((size_t)8, index);
  433. unsigned char bitArray4[] = {
  434. 0x00, 0x00, 0x00, 0x00,
  435. 0x00, 0x00, 0x00, 0x00,
  436. 0x00, 0x00, 0x00, 0x00,
  437. 0x00, 0x00, 0x00, 0x00,
  438. 0x00, 0x00, 0x00, 0x00,
  439. 0x00, 0x00, 0x00, 0x00,
  440. 0x00, 0x00, 0x00, 0x00,
  441. 0x00, 0x00, 0x00, 0x00,
  442. };
  443. CPPUNIT_ASSERT(!bt1.getMissingIndex(index, bitArray4, 32));
  444. }
  445. // TODO1.5 add test using ignoreBitfield
  446. void BitfieldManTest::testGetSparceMissingUnusedIndex() {
  447. BitfieldMan bitfield(1024*1024, 10*1024*1024);
  448. const size_t length = 2;
  449. unsigned char ignoreBitfield[length];
  450. memset(ignoreBitfield, 0, sizeof(ignoreBitfield));
  451. size_t index;
  452. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index,
  453. ignoreBitfield, length));
  454. CPPUNIT_ASSERT_EQUAL((size_t)0, index);
  455. bitfield.setUseBit(0);
  456. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index,
  457. ignoreBitfield, length));
  458. CPPUNIT_ASSERT_EQUAL((size_t)5, index);
  459. bitfield.setUseBit(5);
  460. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index,
  461. ignoreBitfield, length));
  462. CPPUNIT_ASSERT_EQUAL((size_t)3, index);
  463. bitfield.setUseBit(3);
  464. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index,
  465. ignoreBitfield, length));
  466. CPPUNIT_ASSERT_EQUAL((size_t)8, index);
  467. bitfield.setUseBit(8);
  468. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index,
  469. ignoreBitfield, length));
  470. CPPUNIT_ASSERT_EQUAL((size_t)2, index);
  471. bitfield.setUseBit(2);
  472. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index,
  473. ignoreBitfield, length));
  474. CPPUNIT_ASSERT_EQUAL((size_t)7, index);
  475. bitfield.setUseBit(7);
  476. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index,
  477. ignoreBitfield, length));
  478. CPPUNIT_ASSERT_EQUAL((size_t)1, index);
  479. bitfield.setUseBit(1);
  480. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index,
  481. ignoreBitfield, length));
  482. CPPUNIT_ASSERT_EQUAL((size_t)4, index);
  483. bitfield.setUseBit(4);
  484. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index,
  485. ignoreBitfield, length));
  486. CPPUNIT_ASSERT_EQUAL((size_t)6, index);
  487. bitfield.setUseBit(6);
  488. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index,
  489. ignoreBitfield, length));
  490. CPPUNIT_ASSERT_EQUAL((size_t)9, index);
  491. bitfield.setUseBit(9);
  492. CPPUNIT_ASSERT(!bitfield.getSparseMissingUnusedIndex(index,
  493. ignoreBitfield, length));
  494. }
  495. void BitfieldManTest::testGetSparceMissingUnusedIndex_setBit() {
  496. BitfieldMan bitfield(1024*1024, 10*1024*1024);
  497. const size_t length = 2;
  498. unsigned char ignoreBitfield[length];
  499. memset(ignoreBitfield, 0, sizeof(ignoreBitfield));
  500. size_t index;
  501. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index,
  502. ignoreBitfield, length));
  503. CPPUNIT_ASSERT_EQUAL((size_t)0, index);
  504. bitfield.setBit(0);
  505. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index,
  506. ignoreBitfield, length));
  507. CPPUNIT_ASSERT_EQUAL((size_t)1, index);
  508. bitfield.setBit(1);
  509. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index,
  510. ignoreBitfield, length));
  511. CPPUNIT_ASSERT_EQUAL((size_t)2, index);
  512. bitfield.setBit(2);
  513. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index,
  514. ignoreBitfield, length));
  515. CPPUNIT_ASSERT_EQUAL((size_t)3, index);
  516. bitfield.setBit(3);
  517. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index,
  518. ignoreBitfield, length));
  519. CPPUNIT_ASSERT_EQUAL((size_t)4, index);
  520. bitfield.setBit(4);
  521. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index,
  522. ignoreBitfield, length));
  523. CPPUNIT_ASSERT_EQUAL((size_t)5, index);
  524. bitfield.setBit(5);
  525. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index,
  526. ignoreBitfield, length));
  527. CPPUNIT_ASSERT_EQUAL((size_t)6, index);
  528. bitfield.setBit(6);
  529. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index,
  530. ignoreBitfield, length));
  531. CPPUNIT_ASSERT_EQUAL((size_t)7, index);
  532. bitfield.setBit(7);
  533. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index,
  534. ignoreBitfield, length));
  535. CPPUNIT_ASSERT_EQUAL((size_t)8, index);
  536. bitfield.setBit(8);
  537. CPPUNIT_ASSERT(bitfield.getSparseMissingUnusedIndex(index,
  538. ignoreBitfield, length));
  539. CPPUNIT_ASSERT_EQUAL((size_t)9, index);
  540. bitfield.setBit(9);
  541. CPPUNIT_ASSERT(!bitfield.getSparseMissingUnusedIndex(index,
  542. ignoreBitfield, length));
  543. }
  544. void BitfieldManTest::testIsBitSetOffsetRange()
  545. {
  546. int64_t totalLength = 4ULL*1024*1024*1024;
  547. int32_t pieceLength = 4*1024*1024;
  548. BitfieldMan bitfield(pieceLength, totalLength);
  549. bitfield.setAllBit();
  550. CPPUNIT_ASSERT(!bitfield.isBitSetOffsetRange(0, 0));
  551. CPPUNIT_ASSERT(!bitfield.isBitSetOffsetRange(totalLength, 100));
  552. CPPUNIT_ASSERT(!bitfield.isBitSetOffsetRange(totalLength+1, 100));
  553. CPPUNIT_ASSERT(bitfield.isBitSetOffsetRange(0, totalLength));
  554. CPPUNIT_ASSERT(bitfield.isBitSetOffsetRange(0, totalLength+1));
  555. bitfield.clearAllBit();
  556. bitfield.setBit(100);
  557. bitfield.setBit(101);
  558. CPPUNIT_ASSERT(bitfield.isBitSetOffsetRange(pieceLength*100, pieceLength*2));
  559. CPPUNIT_ASSERT(!bitfield.isBitSetOffsetRange(pieceLength*100-10, pieceLength*2));
  560. CPPUNIT_ASSERT(!bitfield.isBitSetOffsetRange(pieceLength*100, pieceLength*2+1));
  561. bitfield.clearAllBit();
  562. bitfield.setBit(100);
  563. bitfield.setBit(102);
  564. CPPUNIT_ASSERT(!bitfield.isBitSetOffsetRange(pieceLength*100, pieceLength*3));
  565. }
  566. void BitfieldManTest::testGetMissingUnusedLength()
  567. {
  568. uint64_t totalLength = 1024*10+10;
  569. size_t blockLength = 1024;
  570. BitfieldMan bf(blockLength, totalLength);
  571. // from index 0 and all blocks are unused and not acquired.
  572. CPPUNIT_ASSERT_EQUAL(totalLength, bf.getMissingUnusedLength(0));
  573. // from index 10 and all blocks are unused and not acquired.
  574. CPPUNIT_ASSERT_EQUAL((uint64_t)10ULL, bf.getMissingUnusedLength(10));
  575. // from index 11
  576. CPPUNIT_ASSERT_EQUAL((uint64_t)0ULL, bf.getMissingUnusedLength(11));
  577. // from index 12
  578. CPPUNIT_ASSERT_EQUAL((uint64_t)0ULL, bf.getMissingUnusedLength(12));
  579. // from index 0 and 5th block is used.
  580. bf.setUseBit(5);
  581. CPPUNIT_ASSERT_EQUAL((uint64_t)5ULL*blockLength, bf.getMissingUnusedLength(0));
  582. // from index 0 and 4th block is acquired.
  583. bf.setBit(4);
  584. CPPUNIT_ASSERT_EQUAL((uint64_t)4ULL*blockLength, bf.getMissingUnusedLength(0));
  585. // from index 1
  586. CPPUNIT_ASSERT_EQUAL((uint64_t)3ULL*blockLength, bf.getMissingUnusedLength(1));
  587. }
  588. void BitfieldManTest::testSetBitRange()
  589. {
  590. size_t blockLength = 1024*1024;
  591. uint64_t totalLength = 10*blockLength;
  592. BitfieldMan bf(blockLength, totalLength);
  593. bf.setBitRange(0, 4);
  594. for(size_t i = 0; i < 5; ++i) {
  595. CPPUNIT_ASSERT(bf.isBitSet(i));
  596. }
  597. for(size_t i = 5; i < 10; ++i) {
  598. CPPUNIT_ASSERT(!bf.isBitSet(i));
  599. }
  600. CPPUNIT_ASSERT_EQUAL((uint64_t)5ULL*blockLength, bf.getCompletedLength());
  601. }
  602. void BitfieldManTest::testGetAllMissingIndexes_noarg()
  603. {
  604. size_t blockLength = 16*1024;
  605. uint64_t totalLength = 1024*1024;
  606. size_t nbits = (totalLength+blockLength-1)/blockLength;
  607. BitfieldMan bf(blockLength, totalLength);
  608. unsigned char misbitfield[8];
  609. CPPUNIT_ASSERT(bf.getAllMissingIndexes(misbitfield, sizeof(misbitfield)));
  610. CPPUNIT_ASSERT_EQUAL((size_t)64, bitfield::countSetBit(misbitfield, nbits));
  611. for(size_t i = 0; i < 63; ++i) {
  612. bf.setBit(i);
  613. }
  614. CPPUNIT_ASSERT(bf.getAllMissingIndexes(misbitfield, sizeof(misbitfield)));
  615. CPPUNIT_ASSERT_EQUAL((size_t)1, bitfield::countSetBit(misbitfield, nbits));
  616. CPPUNIT_ASSERT(bitfield::test(misbitfield, nbits, 63));
  617. }
  618. // See garbage bits of last byte are 0
  619. void BitfieldManTest::testGetAllMissingIndexes_checkLastByte()
  620. {
  621. size_t blockLength = 16*1024;
  622. uint64_t totalLength = blockLength*2;
  623. size_t nbits = (totalLength+blockLength-1)/blockLength;
  624. BitfieldMan bf(blockLength, totalLength);
  625. unsigned char misbitfield[1];
  626. CPPUNIT_ASSERT(bf.getAllMissingIndexes(misbitfield, sizeof(misbitfield)));
  627. CPPUNIT_ASSERT_EQUAL((size_t)2, bitfield::countSetBit(misbitfield, nbits));
  628. CPPUNIT_ASSERT(bitfield::test(misbitfield, nbits, 0));
  629. CPPUNIT_ASSERT(bitfield::test(misbitfield, nbits, 1));
  630. }
  631. void BitfieldManTest::testGetAllMissingIndexes()
  632. {
  633. size_t blockLength = 16*1024;
  634. uint64_t totalLength = 1024*1024;
  635. size_t nbits = (totalLength+blockLength-1)/blockLength;
  636. BitfieldMan bf(blockLength, totalLength);
  637. BitfieldMan peerBf(blockLength, totalLength);
  638. peerBf.setAllBit();
  639. unsigned char misbitfield[8];
  640. CPPUNIT_ASSERT(bf.getAllMissingIndexes(misbitfield, sizeof(misbitfield),
  641. peerBf.getBitfield(),
  642. peerBf.getBitfieldLength()));
  643. CPPUNIT_ASSERT_EQUAL((size_t)64, bitfield::countSetBit(misbitfield, nbits));
  644. for(size_t i = 0; i < 62; ++i) {
  645. bf.setBit(i);
  646. }
  647. peerBf.unsetBit(62);
  648. CPPUNIT_ASSERT(bf.getAllMissingIndexes(misbitfield, sizeof(misbitfield),
  649. peerBf.getBitfield(),
  650. peerBf.getBitfieldLength()));
  651. CPPUNIT_ASSERT_EQUAL((size_t)1, bitfield::countSetBit(misbitfield, nbits));
  652. CPPUNIT_ASSERT(bitfield::test(misbitfield, nbits, 63));
  653. }
  654. void BitfieldManTest::testGetAllMissingUnusedIndexes()
  655. {
  656. size_t blockLength = 16*1024;
  657. uint64_t totalLength = 1024*1024;
  658. size_t nbits = (totalLength+blockLength-1)/blockLength;
  659. BitfieldMan bf(blockLength, totalLength);
  660. BitfieldMan peerBf(blockLength, totalLength);
  661. peerBf.setAllBit();
  662. unsigned char misbitfield[8];
  663. CPPUNIT_ASSERT(bf.getAllMissingUnusedIndexes(misbitfield,
  664. sizeof(misbitfield),
  665. peerBf.getBitfield(),
  666. peerBf.getBitfieldLength()));
  667. CPPUNIT_ASSERT_EQUAL((size_t)64, bitfield::countSetBit(misbitfield, nbits));
  668. for(size_t i = 0; i < 61; ++i) {
  669. bf.setBit(i);
  670. }
  671. bf.setUseBit(61);
  672. peerBf.unsetBit(62);
  673. CPPUNIT_ASSERT(bf.getAllMissingUnusedIndexes(misbitfield,
  674. sizeof(misbitfield),
  675. peerBf.getBitfield(),
  676. peerBf.getBitfieldLength()));
  677. CPPUNIT_ASSERT_EQUAL((size_t)1, bitfield::countSetBit(misbitfield, nbits));
  678. CPPUNIT_ASSERT(bitfield::test(misbitfield, nbits, 63));
  679. }
  680. void BitfieldManTest::testGetMissingUnusedIndex()
  681. {
  682. BitfieldMan bt1(1024, 1024*256);
  683. bt1.setRandomizer(fixedNumberRandomizer);
  684. size_t index;
  685. {
  686. unsigned char bitArray[] = {
  687. 0xff, 0xff, 0xff, 0xff,
  688. 0xff, 0xff, 0xff, 0xff,
  689. 0xff, 0xff, 0xff, 0xff,
  690. 0xff, 0xff, 0xff, 0xff,
  691. 0xff, 0xff, 0xff, 0xff,
  692. 0xff, 0xff, 0xff, 0xff,
  693. 0xff, 0xff, 0xff, 0xff,
  694. 0xff, 0xff, 0xff, 0xff,
  695. };
  696. CPPUNIT_ASSERT(bt1.getMissingUnusedIndex(index, bitArray, 32));
  697. CPPUNIT_ASSERT_EQUAL((size_t)0, index);
  698. bt1.addFilter(1024, 1024*256);
  699. bt1.enableFilter();
  700. CPPUNIT_ASSERT(bt1.getMissingUnusedIndex(index, bitArray, 32));
  701. CPPUNIT_ASSERT_EQUAL((size_t)1, index);
  702. bt1.setUseBit(1);
  703. CPPUNIT_ASSERT(bt1.getMissingUnusedIndex(index, bitArray, 32));
  704. CPPUNIT_ASSERT_EQUAL((size_t)2, index);
  705. bt1.disableFilter();
  706. bt1.setBit(0);
  707. CPPUNIT_ASSERT(bt1.getMissingUnusedIndex(index, bitArray, 32));
  708. CPPUNIT_ASSERT_EQUAL((size_t)2, index);
  709. bt1.setAllBit();
  710. CPPUNIT_ASSERT(!bt1.getMissingUnusedIndex(index, bitArray, 32));
  711. bt1.clearAllBit();
  712. bt1.setAllUseBit();
  713. CPPUNIT_ASSERT(!bt1.getMissingUnusedIndex(index, bitArray, 32));
  714. }
  715. {
  716. unsigned char bitArray4[] = {
  717. 0x00, 0x00, 0x00, 0x00,
  718. 0x00, 0x00, 0x00, 0x00,
  719. 0x00, 0x00, 0x00, 0x00,
  720. 0x00, 0x00, 0x00, 0x00,
  721. 0x00, 0x00, 0x00, 0x00,
  722. 0x00, 0x00, 0x00, 0x00,
  723. 0x00, 0x00, 0x00, 0x00,
  724. 0x00, 0x00, 0x00, 0x00,
  725. };
  726. CPPUNIT_ASSERT(!bt1.getMissingUnusedIndex(index, bitArray4, 32));
  727. }
  728. }
  729. void BitfieldManTest::testCountFilteredBlock()
  730. {
  731. BitfieldMan bt(1024, 1024*256);
  732. CPPUNIT_ASSERT_EQUAL((size_t)256, bt.countBlock());
  733. CPPUNIT_ASSERT_EQUAL((size_t)0, bt.countFilteredBlock());
  734. bt.addFilter(1024, 1024*256);
  735. bt.enableFilter();
  736. CPPUNIT_ASSERT_EQUAL((size_t)256, bt.countBlock());
  737. CPPUNIT_ASSERT_EQUAL((size_t)255, bt.countFilteredBlock());
  738. bt.disableFilter();
  739. CPPUNIT_ASSERT_EQUAL((size_t)256, bt.countBlock());
  740. CPPUNIT_ASSERT_EQUAL((size_t)0, bt.countFilteredBlock());
  741. }
  742. void BitfieldManTest::testCountMissingBlock()
  743. {
  744. BitfieldMan bt(1024, 1024*10);
  745. CPPUNIT_ASSERT_EQUAL((size_t)10, bt.countMissingBlock());
  746. bt.setBit(1);
  747. CPPUNIT_ASSERT_EQUAL((size_t)9, bt.countMissingBlock());
  748. bt.setAllBit();
  749. CPPUNIT_ASSERT_EQUAL((size_t)0, bt.countMissingBlock());
  750. }
  751. void BitfieldManTest::testZeroLengthFilter()
  752. {
  753. BitfieldMan bt(1024, 1024*10);
  754. bt.enableFilter();
  755. CPPUNIT_ASSERT_EQUAL((size_t)0, bt.countMissingBlock());
  756. }
  757. } // namespace aria2