BitfieldManTest.cc 28 KB

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