BitfieldManTest.cc 23 KB

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