BitfieldManTest.cc 21 KB

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