BitfieldMan.cc 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791
  1. /* <!-- copyright */
  2. /*
  3. * aria2 - The high speed download utility
  4. *
  5. * Copyright (C) 2006 Tatsuhiro Tsujikawa
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. *
  21. * In addition, as a special exception, the copyright holders give
  22. * permission to link the code of portions of this program with the
  23. * OpenSSL library under certain conditions as described in each
  24. * individual source file, and distribute linked combinations
  25. * including the two.
  26. * You must obey the GNU General Public License in all respects
  27. * for all of the code used other than OpenSSL. If you modify
  28. * file(s) with this exception, you may extend this exception to your
  29. * version of the file(s), but you are not obligated to do so. If you
  30. * do not wish to do so, delete this exception statement from your
  31. * version. If you delete this exception statement from all source
  32. * files in the program, then also delete it here.
  33. */
  34. /* copyright --> */
  35. #include "BitfieldMan.h"
  36. #include <cassert>
  37. #include <cstring>
  38. #include "Randomizer.h"
  39. #include "util.h"
  40. #include "array_fun.h"
  41. #include "bitfield.h"
  42. using namespace aria2::expr;
  43. namespace aria2 {
  44. BitfieldMan::BitfieldMan(size_t blockLength, uint64_t totalLength)
  45. :blockLength(blockLength),
  46. totalLength(totalLength),
  47. bitfieldLength(0),
  48. blocks(0),
  49. filterEnabled(false),
  50. bitfield(0),
  51. useBitfield(0),
  52. filterBitfield(0),
  53. cachedNumMissingBlock(0),
  54. cachedNumFilteredBlock(0),
  55. cachedCompletedLength(0),
  56. cachedFilteredComletedLength(0),
  57. cachedFilteredTotalLength(0)
  58. {
  59. if(blockLength > 0 && totalLength > 0) {
  60. blocks = totalLength/blockLength+(totalLength%blockLength ? 1 : 0);
  61. bitfieldLength = blocks/8+(blocks%8 ? 1 : 0);
  62. bitfield = new unsigned char[bitfieldLength];
  63. useBitfield = new unsigned char[bitfieldLength];
  64. memset(bitfield, 0, bitfieldLength);
  65. memset(useBitfield, 0, bitfieldLength);
  66. updateCache();
  67. }
  68. }
  69. BitfieldMan::BitfieldMan(const BitfieldMan& bitfieldMan)
  70. :blockLength(bitfieldMan.blockLength),
  71. totalLength(bitfieldMan.totalLength),
  72. bitfieldLength(bitfieldMan.bitfieldLength),
  73. blocks(bitfieldMan.blocks),
  74. filterEnabled(bitfieldMan.filterEnabled),
  75. bitfield(new unsigned char[bitfieldLength]),
  76. useBitfield(new unsigned char[bitfieldLength]),
  77. filterBitfield(0),
  78. randomizer(bitfieldMan.randomizer),
  79. cachedNumMissingBlock(0),
  80. cachedNumFilteredBlock(0),
  81. cachedCompletedLength(0),
  82. cachedFilteredComletedLength(0),
  83. cachedFilteredTotalLength(0)
  84. {
  85. memcpy(bitfield, bitfieldMan.bitfield, bitfieldLength);
  86. memcpy(useBitfield, bitfieldMan.useBitfield, bitfieldLength);
  87. if(filterEnabled) {
  88. filterBitfield = new unsigned char[bitfieldLength];
  89. memcpy(filterBitfield, bitfieldMan.filterBitfield, bitfieldLength);
  90. }
  91. updateCache();
  92. }
  93. BitfieldMan& BitfieldMan::operator=(const BitfieldMan& bitfieldMan)
  94. {
  95. if(this != &bitfieldMan) {
  96. blockLength = bitfieldMan.blockLength;
  97. totalLength = bitfieldMan.totalLength;
  98. blocks = bitfieldMan.blocks;
  99. bitfieldLength = bitfieldMan.bitfieldLength;
  100. filterEnabled = bitfieldMan.filterEnabled;
  101. delete [] bitfield;
  102. bitfield = new unsigned char[bitfieldLength];
  103. memcpy(bitfield, bitfieldMan.bitfield, bitfieldLength);
  104. delete [] useBitfield;
  105. useBitfield = new unsigned char[bitfieldLength];
  106. memcpy(useBitfield, bitfieldMan.useBitfield, bitfieldLength);
  107. delete [] filterBitfield;
  108. if(filterEnabled) {
  109. filterBitfield = new unsigned char[bitfieldLength];
  110. memcpy(filterBitfield, bitfieldMan.filterBitfield, bitfieldLength);
  111. } else {
  112. filterBitfield = 0;
  113. }
  114. updateCache();
  115. }
  116. return *this;
  117. }
  118. BitfieldMan::~BitfieldMan() {
  119. delete [] bitfield;
  120. delete [] useBitfield;
  121. delete [] filterBitfield;
  122. }
  123. size_t BitfieldMan::getBlockLength(size_t index) const
  124. {
  125. if(index == blocks-1) {
  126. return getLastBlockLength();
  127. } else if(index < blocks-1) {
  128. return getBlockLength();
  129. } else {
  130. return 0;
  131. }
  132. }
  133. size_t
  134. BitfieldMan::getNthBitIndex(const unsigned char bitfield, size_t nth) const
  135. {
  136. size_t index = 0;
  137. for(int bs = 7; bs >= 0; --bs) {
  138. unsigned char mask = 1 << bs;
  139. if(bitfield & mask) {
  140. nth--;
  141. if(nth == 0) {
  142. index = 7-bs;
  143. break;
  144. }
  145. }
  146. }
  147. return index;
  148. }
  149. template<typename Array>
  150. bool BitfieldMan::getMissingIndexRandomly(size_t& index,
  151. const Array& bitfield,
  152. size_t bitfieldLength) const
  153. {
  154. size_t byte = randomizer->getRandomNumber(bitfieldLength);
  155. for(size_t i = 0; i < bitfieldLength; ++i) {
  156. unsigned char mask;
  157. if(byte == bitfieldLength-1) {
  158. mask = bitfield::lastByteMask(blocks);
  159. } else {
  160. mask = 0xff;
  161. }
  162. unsigned char bits = bitfield[byte];
  163. if(bits&mask) {
  164. index = byte*8+getNthBitIndex(bits, 1);
  165. return true;
  166. }
  167. ++byte;
  168. if(byte == bitfieldLength) {
  169. byte = 0;
  170. }
  171. }
  172. return false;
  173. }
  174. bool BitfieldMan::hasMissingPiece(const unsigned char* peerBitfield, size_t length) const {
  175. if(bitfieldLength != length) {
  176. return false;
  177. }
  178. bool retval = false;
  179. for(size_t i = 0; i < bitfieldLength; ++i) {
  180. unsigned char temp = peerBitfield[i] & ~bitfield[i];
  181. if(filterEnabled) {
  182. temp &= filterBitfield[i];
  183. }
  184. if(temp&0xff) {
  185. retval = true;
  186. break;
  187. }
  188. }
  189. return retval;
  190. }
  191. bool BitfieldMan::getMissingIndex(size_t& index, const unsigned char* peerBitfield, size_t length) const {
  192. if(bitfieldLength != length) {
  193. return false;
  194. }
  195. if(filterEnabled) {
  196. return getMissingIndexRandomly
  197. (index,
  198. ~array(bitfield)&array(peerBitfield)&array(filterBitfield),
  199. bitfieldLength);
  200. } else {
  201. return getMissingIndexRandomly
  202. (index, ~array(bitfield)&array(peerBitfield), bitfieldLength);
  203. }
  204. }
  205. bool BitfieldMan::getMissingUnusedIndex(size_t& index, const unsigned char* peerBitfield, size_t length) const {
  206. if(bitfieldLength != length) {
  207. return false;
  208. }
  209. if(filterEnabled) {
  210. return getMissingIndexRandomly
  211. (index,
  212. ~array(bitfield)&~array(useBitfield)&array(peerBitfield)&array(filterBitfield),
  213. bitfieldLength);
  214. } else {
  215. return getMissingIndexRandomly
  216. (index,
  217. ~array(bitfield)&~array(useBitfield)&array(peerBitfield),
  218. bitfieldLength);
  219. }
  220. }
  221. template<typename Array>
  222. bool BitfieldMan::getFirstMissingIndex(size_t& index, const Array& bitfield, size_t bitfieldLength) const
  223. {
  224. for(size_t i = 0; i < bitfieldLength; ++i) {
  225. unsigned char bits = bitfield[i];
  226. unsigned char mask = 128;
  227. size_t tindex = i*8;
  228. for(size_t bi = 0; bi < 8 && tindex < blocks; ++bi, mask >>= 1, ++tindex) {
  229. if(bits & mask) {
  230. index = tindex;
  231. return true;
  232. }
  233. }
  234. }
  235. return false;
  236. }
  237. bool BitfieldMan::getFirstMissingUnusedIndex(size_t& index) const
  238. {
  239. if(filterEnabled) {
  240. return getFirstMissingIndex
  241. (index, ~array(bitfield)&~array(useBitfield)&array(filterBitfield),
  242. bitfieldLength);
  243. } else {
  244. return getFirstMissingIndex
  245. (index, ~array(bitfield)&~array(useBitfield),
  246. bitfieldLength);
  247. }
  248. }
  249. bool BitfieldMan::getFirstMissingIndex(size_t& index) const
  250. {
  251. if(filterEnabled) {
  252. return getFirstMissingIndex(index, ~array(bitfield)&array(filterBitfield),
  253. bitfieldLength);
  254. } else {
  255. return getFirstMissingIndex(index, ~array(bitfield), bitfieldLength);
  256. }
  257. }
  258. bool BitfieldMan::getMissingIndex(size_t& index) const {
  259. if(filterEnabled) {
  260. return getMissingIndexRandomly
  261. (index, ~array(bitfield)&array(filterBitfield), bitfieldLength);
  262. } else {
  263. return getMissingIndexRandomly(index, ~array(bitfield), bitfieldLength);
  264. }
  265. }
  266. bool BitfieldMan::getMissingUnusedIndex(size_t& index) const
  267. {
  268. if(filterEnabled) {
  269. return getMissingIndexRandomly
  270. (index, ~array(bitfield)&~array(useBitfield)&array(filterBitfield),
  271. bitfieldLength);
  272. } else {
  273. return getMissingIndexRandomly
  274. (index, ~array(bitfield)&~array(useBitfield), bitfieldLength);
  275. }
  276. }
  277. template<typename Array>
  278. static size_t getStartIndex(size_t index, const Array& bitfield, size_t blocks) {
  279. while(index < blocks && bitfield::test(bitfield, blocks, index)) {
  280. ++index;
  281. }
  282. if(blocks <= index) {
  283. return blocks;
  284. } else {
  285. return index;
  286. }
  287. }
  288. template<typename Array>
  289. static size_t getEndIndex(size_t index, const Array& bitfield, size_t blocks) {
  290. while(index < blocks && !bitfield::test(bitfield, blocks, index)) {
  291. ++index;
  292. }
  293. return index;
  294. }
  295. template<typename Array>
  296. static bool getSparseMissingUnusedIndex
  297. (size_t& index,
  298. const Array& bitfield,
  299. const unsigned char* useBitfield,
  300. size_t blocks)
  301. {
  302. BitfieldMan::Range maxRange;
  303. BitfieldMan::Range currentRange;
  304. {
  305. size_t nextIndex = 0;
  306. while(nextIndex < blocks) {
  307. currentRange.startIndex =
  308. getStartIndex(nextIndex, bitfield, blocks);
  309. if(currentRange.startIndex == blocks) {
  310. break;
  311. }
  312. currentRange.endIndex =
  313. getEndIndex(currentRange.startIndex, bitfield, blocks);
  314. if(maxRange < currentRange) {
  315. maxRange = currentRange;
  316. }
  317. nextIndex = currentRange.endIndex;
  318. }
  319. }
  320. if(maxRange.getSize()) {
  321. if(maxRange.startIndex == 0) {
  322. index = 0;
  323. } else if(bitfield::test(useBitfield, blocks, maxRange.startIndex-1)) {
  324. index = maxRange.getMidIndex();
  325. } else {
  326. index = maxRange.startIndex;
  327. }
  328. return true;
  329. } else {
  330. return false;
  331. }
  332. }
  333. bool BitfieldMan::getSparseMissingUnusedIndex
  334. (size_t& index,
  335. const unsigned char* ignoreBitfield,
  336. size_t ignoreBitfieldLength) const
  337. {
  338. if(filterEnabled) {
  339. return aria2::getSparseMissingUnusedIndex
  340. (index, array(ignoreBitfield)|~array(filterBitfield)|array(bitfield)|array(useBitfield),
  341. useBitfield, blocks);
  342. } else {
  343. return aria2::getSparseMissingUnusedIndex
  344. (index, array(ignoreBitfield)|array(bitfield)|array(useBitfield),
  345. useBitfield, blocks);
  346. }
  347. }
  348. template<typename Array>
  349. static bool copyBitfield(unsigned char* dst, const Array& src, size_t blocks)
  350. {
  351. unsigned char bits = 0;
  352. size_t len = (blocks+7)/8;
  353. for(size_t i = 0; i < len-1; ++i) {
  354. dst[i] = src[i];
  355. bits |= dst[i];
  356. }
  357. dst[len-1] = src[len-1]&bitfield::lastByteMask(blocks);
  358. bits |= dst[len-1];
  359. return bits != 0;
  360. }
  361. bool BitfieldMan::getAllMissingIndexes(unsigned char* misbitfield, size_t len)
  362. const
  363. {
  364. assert(len == bitfieldLength);
  365. if(filterEnabled) {
  366. return copyBitfield
  367. (misbitfield, ~array(bitfield)&array(filterBitfield), blocks);
  368. } else {
  369. return copyBitfield(misbitfield, ~array(bitfield), blocks);
  370. }
  371. }
  372. bool BitfieldMan::getAllMissingIndexes(unsigned char* misbitfield, size_t len,
  373. const unsigned char* peerBitfield,
  374. size_t peerBitfieldLength) const
  375. {
  376. assert(len == bitfieldLength);
  377. if(bitfieldLength != peerBitfieldLength) {
  378. return false;
  379. }
  380. if(filterEnabled) {
  381. return copyBitfield
  382. (misbitfield, ~array(bitfield)&array(peerBitfield)&array(filterBitfield),
  383. blocks);
  384. } else {
  385. return copyBitfield
  386. (misbitfield, ~array(bitfield)&array(peerBitfield),
  387. blocks);
  388. }
  389. }
  390. bool BitfieldMan::getAllMissingUnusedIndexes(unsigned char* misbitfield,
  391. size_t len,
  392. const unsigned char* peerBitfield,
  393. size_t peerBitfieldLength) const
  394. {
  395. assert(len == bitfieldLength);
  396. if(bitfieldLength != peerBitfieldLength) {
  397. return false;
  398. }
  399. if(filterEnabled) {
  400. return copyBitfield
  401. (misbitfield,
  402. ~array(bitfield)&~array(useBitfield)&array(peerBitfield)&array(filterBitfield),
  403. blocks);
  404. } else {
  405. return copyBitfield
  406. (misbitfield,
  407. ~array(bitfield)&~array(useBitfield)&array(peerBitfield),
  408. blocks);
  409. }
  410. }
  411. size_t BitfieldMan::countMissingBlock() const {
  412. return cachedNumMissingBlock;
  413. }
  414. size_t BitfieldMan::countMissingBlockNow() const {
  415. if(filterEnabled) {
  416. array_ptr<unsigned char> temp(new unsigned char[bitfieldLength]);
  417. for(size_t i = 0; i < bitfieldLength; ++i) {
  418. temp[i] = bitfield[i]&filterBitfield[i];
  419. }
  420. size_t count = bitfield::countSetBit(filterBitfield, blocks)-
  421. bitfield::countSetBit(temp, blocks);
  422. return count;
  423. } else {
  424. return blocks-bitfield::countSetBit(bitfield, blocks);
  425. }
  426. }
  427. size_t BitfieldMan::countFilteredBlockNow() const {
  428. if(filterEnabled) {
  429. return bitfield::countSetBit(filterBitfield, blocks);
  430. } else {
  431. return 0;
  432. }
  433. }
  434. bool BitfieldMan::setBitInternal(unsigned char* bitfield, size_t index, bool on) {
  435. if(blocks <= index) { return false; }
  436. unsigned char mask = 128 >> index%8;
  437. if(on) {
  438. bitfield[index/8] |= mask;
  439. } else {
  440. bitfield[index/8] &= ~mask;
  441. }
  442. return true;
  443. }
  444. bool BitfieldMan::setUseBit(size_t index) {
  445. return setBitInternal(useBitfield, index, true);
  446. }
  447. bool BitfieldMan::unsetUseBit(size_t index) {
  448. return setBitInternal(useBitfield, index, false);
  449. }
  450. bool BitfieldMan::setBit(size_t index) {
  451. bool b = setBitInternal(bitfield, index, true);
  452. updateCache();
  453. return b;
  454. }
  455. bool BitfieldMan::unsetBit(size_t index) {
  456. bool b = setBitInternal(bitfield, index, false);
  457. updateCache();
  458. return b;
  459. }
  460. bool BitfieldMan::isFilteredAllBitSet() const {
  461. if(filterEnabled) {
  462. for(size_t i = 0; i < bitfieldLength; ++i) {
  463. if((bitfield[i]&filterBitfield[i]) != filterBitfield[i]) {
  464. return false;
  465. }
  466. }
  467. return true;
  468. } else {
  469. return isAllBitSet();
  470. }
  471. }
  472. static bool testAllBitSet
  473. (const unsigned char* bitfield, size_t length, size_t blocks)
  474. {
  475. if(length == 0) {
  476. return true;
  477. }
  478. for(size_t i = 0; i < length-1; ++i) {
  479. if(bitfield[i] != 0xff) {
  480. return false;
  481. }
  482. }
  483. unsigned char b = ~((128 >> (blocks-1)%8)-1);
  484. if(bitfield[length-1] != b) {
  485. return false;
  486. }
  487. return true;
  488. }
  489. bool BitfieldMan::isAllBitSet() const
  490. {
  491. return testAllBitSet(bitfield, bitfieldLength, blocks);
  492. }
  493. bool BitfieldMan::isAllFilterBitSet() const
  494. {
  495. if(!filterBitfield) {
  496. return false;
  497. }
  498. return testAllBitSet(filterBitfield, bitfieldLength, blocks);
  499. }
  500. bool BitfieldMan::isBitSet(size_t index) const
  501. {
  502. return bitfield::test(bitfield, blocks, index);
  503. }
  504. bool BitfieldMan::isUseBitSet(size_t index) const
  505. {
  506. return bitfield::test(useBitfield, blocks, index);
  507. }
  508. void BitfieldMan::setBitfield(const unsigned char* bitfield, size_t bitfieldLength) {
  509. if(this->bitfieldLength != bitfieldLength) {
  510. return;
  511. }
  512. memcpy(this->bitfield, bitfield, this->bitfieldLength);
  513. memset(this->useBitfield, 0, this->bitfieldLength);
  514. updateCache();
  515. }
  516. void BitfieldMan::clearAllBit() {
  517. memset(this->bitfield, 0, this->bitfieldLength);
  518. updateCache();
  519. }
  520. void BitfieldMan::setAllBit() {
  521. for(size_t i = 0; i < blocks; ++i) {
  522. setBitInternal(bitfield, i, true);
  523. }
  524. updateCache();
  525. }
  526. void BitfieldMan::clearAllUseBit() {
  527. memset(this->useBitfield, 0, this->bitfieldLength);
  528. updateCache();
  529. }
  530. void BitfieldMan::setAllUseBit() {
  531. for(size_t i = 0; i < blocks; ++i) {
  532. setBitInternal(useBitfield, i, true);
  533. }
  534. }
  535. bool BitfieldMan::setFilterBit(size_t index) {
  536. return setBitInternal(filterBitfield, index, true);
  537. }
  538. void BitfieldMan::ensureFilterBitfield()
  539. {
  540. if(!filterBitfield) {
  541. filterBitfield = new unsigned char[bitfieldLength];
  542. memset(filterBitfield, 0, bitfieldLength);
  543. }
  544. }
  545. void BitfieldMan::addFilter(uint64_t offset, uint64_t length) {
  546. ensureFilterBitfield();
  547. if(length > 0) {
  548. size_t startBlock = offset/blockLength;
  549. size_t endBlock = (offset+length-1)/blockLength;
  550. for(size_t i = startBlock; i <= endBlock && i < blocks; i++) {
  551. setFilterBit(i);
  552. }
  553. }
  554. updateCache();
  555. }
  556. void BitfieldMan::removeFilter(uint64_t offset, uint64_t length) {
  557. ensureFilterBitfield();
  558. if(length > 0) {
  559. size_t startBlock = offset/blockLength;
  560. size_t endBlock = (offset+length-1)/blockLength;
  561. for(size_t i = startBlock; i <= endBlock && i < blocks; i++) {
  562. setBitInternal(filterBitfield, i, false);
  563. }
  564. }
  565. updateCache();
  566. }
  567. void BitfieldMan::addNotFilter(uint64_t offset, uint64_t length)
  568. {
  569. ensureFilterBitfield();
  570. if(length > 0 && blocks > 0) {
  571. size_t startBlock = offset/blockLength;
  572. if(blocks <= startBlock) {
  573. startBlock = blocks;
  574. }
  575. size_t endBlock = (offset+length-1)/blockLength;
  576. for(size_t i = 0; i < startBlock; ++i) {
  577. setFilterBit(i);
  578. }
  579. for(size_t i = endBlock+1; i < blocks; ++i) {
  580. setFilterBit(i);
  581. }
  582. }
  583. updateCache();
  584. }
  585. void BitfieldMan::enableFilter() {
  586. ensureFilterBitfield();
  587. filterEnabled = true;
  588. updateCache();
  589. }
  590. void BitfieldMan::disableFilter() {
  591. filterEnabled = false;
  592. updateCache();
  593. }
  594. void BitfieldMan::clearFilter() {
  595. if(filterBitfield) {
  596. delete [] filterBitfield;
  597. filterBitfield = 0;
  598. }
  599. filterEnabled = false;
  600. updateCache();
  601. }
  602. uint64_t BitfieldMan::getFilteredTotalLengthNow() const {
  603. if(!filterBitfield) {
  604. return 0;
  605. }
  606. size_t filteredBlocks = bitfield::countSetBit(filterBitfield, blocks);
  607. if(filteredBlocks == 0) {
  608. return 0;
  609. }
  610. if(bitfield::test(filterBitfield, blocks, blocks-1)) {
  611. return ((uint64_t)filteredBlocks-1)*blockLength+getLastBlockLength();
  612. } else {
  613. return ((uint64_t)filteredBlocks)*blockLength;
  614. }
  615. }
  616. uint64_t BitfieldMan::getCompletedLength(bool useFilter) const {
  617. unsigned char* temp;
  618. if(useFilter) {
  619. temp = new unsigned char[bitfieldLength];
  620. for(size_t i = 0; i < bitfieldLength; ++i) {
  621. temp[i] = bitfield[i];
  622. if(filterEnabled) {
  623. temp[i] &= filterBitfield[i];
  624. }
  625. }
  626. } else {
  627. temp = bitfield;
  628. }
  629. size_t completedBlocks = bitfield::countSetBit(temp, blocks);
  630. uint64_t completedLength = 0;
  631. if(completedBlocks == 0) {
  632. completedLength = 0;
  633. } else {
  634. if(bitfield::test(temp, blocks, blocks-1)) {
  635. completedLength = ((uint64_t)completedBlocks-1)*blockLength+getLastBlockLength();
  636. } else {
  637. completedLength = ((uint64_t)completedBlocks)*blockLength;
  638. }
  639. }
  640. if(useFilter) {
  641. delete [] temp;
  642. }
  643. return completedLength;
  644. }
  645. uint64_t BitfieldMan::getCompletedLengthNow() const {
  646. return getCompletedLength(false);
  647. }
  648. uint64_t BitfieldMan::getFilteredCompletedLengthNow() const {
  649. return getCompletedLength(true);
  650. }
  651. void BitfieldMan::updateCache()
  652. {
  653. cachedNumMissingBlock = countMissingBlockNow();
  654. cachedNumFilteredBlock = countFilteredBlockNow();
  655. cachedFilteredTotalLength = getFilteredTotalLengthNow();
  656. cachedCompletedLength = getCompletedLengthNow();
  657. cachedFilteredComletedLength = getFilteredCompletedLengthNow();
  658. }
  659. bool BitfieldMan::isBitRangeSet(size_t startIndex, size_t endIndex) const
  660. {
  661. for(size_t i = startIndex; i <= endIndex; ++i) {
  662. if(!isBitSet(i)) {
  663. return false;
  664. }
  665. }
  666. return true;
  667. }
  668. void BitfieldMan::unsetBitRange(size_t startIndex, size_t endIndex)
  669. {
  670. for(size_t i = startIndex; i <= endIndex; ++i) {
  671. unsetBit(i);
  672. }
  673. updateCache();
  674. }
  675. void BitfieldMan::setBitRange(size_t startIndex, size_t endIndex)
  676. {
  677. for(size_t i = startIndex; i <= endIndex; ++i) {
  678. setBit(i);
  679. }
  680. updateCache();
  681. }
  682. bool BitfieldMan::isBitSetOffsetRange(uint64_t offset, uint64_t length) const
  683. {
  684. if(length <= 0) {
  685. return false;
  686. }
  687. if(totalLength <= offset) {
  688. return false;
  689. }
  690. if(totalLength < offset+length) {
  691. length = totalLength-offset;
  692. }
  693. size_t startBlock = offset/blockLength;
  694. size_t endBlock = (offset+length-1)/blockLength;
  695. for(size_t i = startBlock; i <= endBlock; i++) {
  696. if(!isBitSet(i)) {
  697. return false;
  698. }
  699. }
  700. return true;
  701. }
  702. uint64_t BitfieldMan::getMissingUnusedLength(size_t startingIndex) const
  703. {
  704. if(startingIndex < 0 || blocks <= startingIndex) {
  705. return 0;
  706. }
  707. uint64_t length = 0;
  708. for(size_t i = startingIndex; i < blocks; ++i) {
  709. if(isBitSet(i) || isUseBitSet(i)) {
  710. break;
  711. }
  712. length += getBlockLength(i);
  713. }
  714. return length;
  715. }
  716. void BitfieldMan::setRandomizer(const SharedHandle<Randomizer>& randomizer)
  717. {
  718. this->randomizer = randomizer;
  719. }
  720. } // namespace aria2