BitfieldManTest.cc 27 KB

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